Page MenuHomeIsabelle/Phabricator

No OneTemporary

This file is larger than 256 KB, so syntax highlighting was skipped.
This document is not UTF8. It was detected as ISO-8859-1 (Latin 1) and converted to UTF8 for display.
diff --git a/metadata/metadata b/metadata/metadata
--- a/metadata/metadata
+++ b/metadata/metadata
@@ -1,9814 +1,9939 @@
[Arith_Prog_Rel_Primes]
title = Arithmetic progressions and relative primes
author = José Manuel Rodríguez Caballero <https://josephcmac.github.io/>
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
<a href="https://www.ocf.berkeley.edu/~wwu/riddles/putnam.shtml">
Putnam exam problems of 2002</a>. The statement of the problem is
as follows: For which integers <em>n</em> > 1 does the set of positive
integers less than and relatively prime to <em>n</em> constitute an
arithmetic progression?
[Banach_Steinhaus]
title = Banach-Steinhaus Theorem
author = Dominique Unruh <http://kodu.ut.ee/~unruh/> <mailto:unruh@ut.ee>, Jose Manuel Rodriguez Caballero <https://josephcmac.github.io/> <mailto:jose.manuel.rodriguez.caballero@ut.ee>
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ć <http://www.matf.bg.ac.rs/~filip>, Danijela Simić <http://poincare.matf.bg.ac.rs/~danijela>
topic = Mathematics/Geometry
date = 2019-12-16
notify = danijela@matf.bg.ac.rs, filip@matf.bg.ac.rs, boutry@unistra.fr
abstract =
A formalization of geometry of complex numbers is presented.
Fundamental objects that are investigated are the complex plane
extended by a single infinite point, its objects (points, lines and
circles), and groups of transformations that act on them (e.g.,
inversions and Möbius transformations). Most objects are defined
algebraically, but correspondence with classical geometric definitions
is shown.
[Poincare_Disc]
title = Poincaré Disc Model
author = Danijela Simić <http://poincare.matf.bg.ac.rs/~danijela>, Filip Marić <http://www.matf.bg.ac.rs/~filip>, Pierre Boutry <mailto:boutry@unistra.fr>
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 &#8450;P1), formalized in the AFP entry “Complex Geometry”.
Points, lines, congruence of pairs of points, betweenness of triples
of points, circles, and isometries are defined within the model. It is
shown that the model satisfies all Tarski's axioms except the
Euclid's axiom. It is shown that it satisfies its negation and
the limiting parallels axiom (which proves it to be a model of
hyperbolic geometry).
[Fourier]
title = Fourier Series
author = Lawrence C Paulson <https://www.cl.cam.ac.uk/~lp15/>
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 <mailto:jonas.raedle@gmail.com>, Lars Hupel <https://www21.in.tum.de/~hupel/>
topic = Computer science/Data structures
date = 2018-11-06
notify = jonas.raedle@gmail.com
abstract =
<p>We provide a framework for automatically deriving instances for
generic type classes. Our approach is inspired by Haskell's
<i>generic-deriving</i> package and Scala's
<i>shapeless</i> 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.</p>
<p>Note: There are already articles in the AFP that provide
automatic instantiation for a number of classes. Concretely, <a href="https://www.isa-afp.org/entries/Deriving.html">Deriving</a> allows the automatic instantiation of comparators, linear orders, equality, and hashing. <a href="https://www.isa-afp.org/entries/Show.html">Show</a> instantiates a Haskell-style <i>show</i> class.</p><p>Our approach works for arbitrary classes (with some Isabelle/HOL overhead for each class), but a smaller set of datatypes.</p>
[Partial_Order_Reduction]
title = Partial Order Reduction
author = Julian Brunner <http://www21.in.tum.de/~brunnerj/>
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 <https://www21.in.tum.de/~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 <https://lars.hupel.info/>
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 <http://lig-membres.imag.fr/mechenim/>
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 <a
href="https://hal.archives-ouvertes.fr/hal-01562944">paper</a>.
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)<br>
[Pell]
title = Pell's Equation
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory
date = 2018-06-23
notify = eberlm@in.tum.de
abstract =
<p> This article gives the basic theory of Pell's equation
<em>x</em><sup>2</sup> = 1 +
<em>D</em>&thinsp;<em>y</em><sup>2</sup>,
where
<em>D</em>&thinsp;&isin;&thinsp;&#8469; is
a parameter and <em>x</em>, <em>y</em> are
integer variables. </p> <p> The main result that is proven
is the following: If <em>D</em> is not a perfect square,
then there exists a <em>fundamental solution</em>
(<em>x</em><sub>0</sub>,
<em>y</em><sub>0</sub>) that is not the
trivial solution (1, 0) and which generates all other solutions
(<em>x</em>, <em>y</em>) in the sense that
there exists some
<em>n</em>&thinsp;&isin;&thinsp;&#8469;
such that |<em>x</em>| +
|<em>y</em>|&thinsp;&radic;<span
style="text-decoration:
overline"><em>D</em></span> =
(<em>x</em><sub>0</sub> +
<em>y</em><sub>0</sub>&thinsp;&radic;<span
style="text-decoration:
overline"><em>D</em></span>)<sup><em>n</em></sup>.
This also implies that the set of solutions is infinite, and it gives
us an explicit and executable characterisation of all the solutions.
</p> <p> Based on this, simple executable algorithms for
computing the fundamental solution and the infinite sequence of all
non-negative solutions are also provided. </p>
[WebAssembly]
title = WebAssembly
author = Conrad Watt <http://www.cl.cam.ac.uk/~caw77/>
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 <mailto:hellauer@in.tum.de>, Peter Lammich <http://www21.in.tum.de/~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 <i>s</i> in a text
<i>t</i> can be solved deterministically in
<i>O(|s| + |t|)</i> time. We use the Isabelle
Refinement Framework to formulate and verify the algorithm. Via
refinement, we apply some optimisations and finally use the
<em>Sepref</em> tool to obtain executable code in
<em>Imperative/HOL</em>.
[Minkowskis_Theorem]
title = Minkowski's Theorem
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Geometry, Mathematics/Number theory
date = 2017-07-13
notify = eberlm@in.tum.de
abstract =
<p>Minkowski's theorem relates a subset of
&#8477;<sup>n</sup>, the Lebesgue measure, and the
integer lattice &#8484;<sup>n</sup>: It states that
any convex subset of &#8477;<sup>n</sup> with volume
greater than 2<sup>n</sup> contains at least one lattice
point from &#8484;<sup>n</sup>\{0}, i.&thinsp;e. a
non-zero point with integer coefficients.</p> <p>A
related theorem which directly implies this is Blichfeldt's
theorem, which states that any subset of
&#8477;<sup>n</sup> with a volume greater than 1
contains two different points whose difference vector has integer
components.</p> <p>The entry contains a proof of both
theorems.</p>
[Name_Carrying_Type_Inference]
title = Verified Metatheory and Type Inference for a Name-Carrying Simply-Typed Lambda Calculus
author = Michael Rawson <mailto:michaelrawson76@gmail.com>
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 <a
href="http://www.openthesis.org/documents/Verified-Metatheory-Type-Inference-Simply-603182.html">undergraduate
dissertation</a>.
[Propositional_Proof_Systems]
title = Propositional Proof Systems
author = Julius Michaelis <http://liftm.de>, Tobias Nipkow <http://www21.in.tum.de/~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 <mailto:simon.foster@york.ac.uk>, Frank Zeyda <mailto:frank.zeyda@york.ac.uk>
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, <em>get</em>, the return a value
from the source type, and <em>put</em> that updates the
value. We mechanise the underlying theory of lenses, in terms of an
algebraic hierarchy of lenses, including well-behaved and very
well-behaved lenses, each lens class being characterised by a set of
lens laws. We also mechanise a lens algebra in Isabelle that enables
their composition and comparison, so as to allow construction of
complex lenses. This is accompanied by a large library of algebraic
laws. Moreover we also show how the lens classes can be applied by
instantiating them with a number of Isabelle data types.
extra-history =
Change history:
[2020-03-02]:
Added partial bijective and symmetric lenses.
Improved alphabet command generating additional lenses and results.
Several additional lens relations, including observational equivalence.
Additional theorems throughout.
Adaptations for Isabelle 2020.
(revision 44e2e5c)
[Game_Based_Crypto]
title = Game-based cryptography in HOL
author = Andreas Lochbihler <http://www.andreas-lochbihler.de>, S. Reza Sefidgar <>, Bhargav Bhatt <mailto:bhargav.bhatt@inf.ethz.ch>
topic = Computer science/Security/Cryptography
date = 2017-05-05
notify = mail@andreas-lochbihler.de
abstract =
<p>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.
</p><p>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.</p>
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 <http://homepages.inf.ed.ac.uk/da/>, David Butler <mailto:dbutler@turing.ac.uk>
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 <https://www.turing.ac.uk/people/doctoral-students/david-butler>, Andreas Lochbihler <http://www.andreas-lochbihler.de>
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 <http://www.andreas-lochbihler.de>
topic = Computer science/Security/Cryptography, Computer science/Functional programming, Mathematics/Probability theory
date = 2017-05-05
notify = mail@andreas-lochbihler.de
abstract =
<p>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.
</p><p>
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.</p>
[Constructive_Cryptography]
title = Constructive Cryptography in HOL
author = Andreas Lochbihler <http://www.andreas-lochbihler.de/>, 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 <http://www.andreas-lochbihler.de>
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)<br>
[Monad_Normalisation]
title = Monad normalisation
author = Joshua Schneider <>, Manuel Eberl <https://www21.in.tum.de/~eberlm>, Andreas Lochbihler <http://www.andreas-lochbihler.de>
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 <http://www.andreas-lochbihler.de>
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)<br>
[Constructor_Funs]
title = Constructor Functions
author = Lars Hupel <https://www21.in.tum.de/~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 <https://www21.in.tum.de/~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, <tt>if-then-else</tt> 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 <tt>if-then-else</tt> as functions.
[Dict_Construction]
title = Dictionary Construction
author = Lars Hupel <https://www21.in.tum.de/~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 <https://lars.hupel.info/>
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 <a
href="http://dx.doi.org/10.1007/978-3-319-89884-1_35">verified
compiler from Isabelle to CakeML</a>. 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
<a
href="https://www.isa-afp.org/entries/Lambda_Free_RPOs.html">Blanchette’s
&lambda;-free higher-order terms</a>. Furthermore, I
implement translation functions between de-Bruijn terms and named
terms and prove their correctness.
[Subresultants]
title = Subresultants
author = Sebastiaan Joosten <mailto:sebastiaan.joosten@uibk.ac.at>, René Thiemann <mailto:rene.thiemann@uibk.ac.at>, Akihisa Yamada <mailto:akihisa.yamada@uibk.ac.at>
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 <https://www21.in.tum.de/~eberlm>
topic = Computer science/Algorithms
date = 2017-03-15
notify = eberlm@in.tum.de
abstract =
<p>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 <em>n</em> is at
least <em>log<sub>2</sub>&nbsp;(n!)</em>
in the worst case, i.&thinsp;e.&nbsp;<em>Ω(n log
n)</em>.</p> <p>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.</p>
[Quick_Sort_Cost]
title = The number of comparisons in QuickSort
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Computer science/Algorithms
date = 2017-03-15
notify = eberlm@in.tum.de
abstract =
<p>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.&thinsp;e.&nbsp;QuickSort with random pivot choice) is
<em>2&thinsp;(n+1)&thinsp;H<sub>n</sub> -
4&thinsp;n</em>, which is asymptotically equivalent to
<em>2&thinsp;n ln n</em>; second, the number of
comparisons performed by the classic non-randomised QuickSort has the
same distribution in the average case as the randomised one.</p>
[Random_BSTs]
title = Expected Shape of Random Binary Search Trees
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Computer science/Data structures
date = 2017-04-04
notify = eberlm@in.tum.de
abstract =
<p>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.&thinsp;e. BSTs that are formed by taking
an empty BST and inserting elements from a fixed set in random
order.</p> <p>In particular, we prove a logarithmic upper
bound on the expected height and the <em>Θ(n log n)</em>
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.</p>
[Randomised_BSTs]
title = Randomised Binary Search Trees
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Computer science/Data structures
date = 2018-10-19
notify = eberlm@in.tum.de
abstract =
<p>This work is a formalisation of the Randomised Binary Search
Trees introduced by Martínez and Roura, including definitions and
correctness proofs.</p> <p>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.</p>
[E_Transcendental]
title = The Transcendence of e
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Analysis, Mathematics/Number theory
date = 2017-01-12
notify = eberlm@in.tum.de
abstract =
<p>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.</p> <p>This kind of approach can be found in
many different sources; this formalisation mostly follows a <a href="http://planetmath.org/proofoflindemannweierstrasstheoremandthateandpiaretranscendental">PlanetMath article</a> by Roger Lipsett.</p>
[Pi_Transcendental]
title = The Transcendence of π
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory
date = 2018-09-28
notify = eberlm@in.tum.de
abstract =
<p>This entry shows the transcendence of &pi; 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
<em>e</em>.</p>
[DFS_Framework]
title = A Framework for Verifying Depth-First Search Algorithms
author = Peter Lammich <http://www21.in.tum.de/~lammich>, René Neumann <mailto:neumannr@in.tum.de>
notify = lammich@in.tum.de
date = 2016-07-05
topic = Computer science/Algorithms/Graph
abstract =
<p>
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.
</p><p>
[CPP-2015] Peter Lammich, René Neumann: A Framework for Verifying
Depth-First Search Algorithms. CPP 2015: 137-146</p>
[Flow_Networks]
title = Flow Networks and the Min-Cut-Max-Flow Theorem
author = Peter Lammich <http://www21.in.tum.de/~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 <http://www21.in.tum.de/~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 <http://ualberta.ca/~jsylvest/>
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 <i>group_add</i> 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 <mailto:victor.gomes@cl.cam.ac.uk>, Georg Struth <mailto:g.struth@sheffield.ac.uk>
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 <mailto:maxime.buyse@polytechnique.edu>, Jason Jaskolka <https://carleton.ca/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 <mailto:lukas.bulwahn@gmail.com>
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 <mailto:lukas.bulwahn@gmail.com>
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 <mailto:lukas.bulwahn@gmail.com>
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 <mailto:stark@cs.stonybrook.edu>
notify = stark@cs.stonybrook.edu
date = 2016-06-26
topic = Mathematics/Category theory
abstract =
This article attempts to develop a usable framework for doing category
theory in Isabelle/HOL. Our point of view, which to some extent
differs from that of the previous AFP articles on the subject, is to
try to explore how category theory can be done efficaciously within
HOL, rather than trying to match exactly the way things are done using
a traditional approach. To this end, we define the notion of category
in an "object-free" style, in which a category is represented by a
single partial composition operation on arrows. This way of defining
categories provides some advantages in the context of HOL, including
the ability to avoid the use of records and the possibility of
defining functors and natural transformations simply as certain
functions on arrows, rather than as composite objects. We define
various constructions associated with the basic notions, including:
dual category, product category, functor category, discrete category,
free category, functor composition, and horizontal and vertical
composite of natural transformations. A "set category" locale is
defined that axiomatizes the notion "category of all sets at a type
and all functions between them," and a fairly extensive set of
properties of set categories is derived from the locale assumptions.
The notion of a set category is used to prove the Yoneda Lemma in a
general setting of a category equipped with a "hom embedding," which
maps arrows of the category to the "universe" of the set category. We
also give a treatment of adjunctions, defining adjunctions via left
and right adjoint functors, natural bijections between hom-sets, and
unit and counit natural transformations, and showing the equivalence
of these definitions. We also develop the theory of limits, including
representations of functors, diagrams and cones, and diagonal
functors. We show that right adjoint functors preserve limits, and
that limits can be constructed via products and equalizers. We
characterize the conditions under which limits exist in a set
category. We also examine the case of limits in a functor category,
ultimately culminating in a proof that the Yoneda embedding preserves
limits.
extra-history =
Change history:
[2018-05-29]:
Revised axioms for the category locale. Introduced notation for composition and "in hom".
(revision 8318366d4575)<br>
[2020-02-15]:
Move ConcreteCategory.thy from Bicategory to Category3 and use it systematically.
Make other minor improvements throughout.
(revision a51840d36867)<br>
[MonoidalCategory]
title = Monoidal Categories
author = Eugene W. Stark <mailto:stark@cs.stonybrook.edu>
topic = Mathematics/Category theory
date = 2017-05-04
notify = stark@cs.stonybrook.edu
abstract =
Building on the formalization of basic category theory set out in the
author's previous AFP article, the present article formalizes
some basic aspects of the theory of monoidal categories. Among the
notions defined here are monoidal category, monoidal functor, and
equivalence of monoidal categories. The main theorems formalized are
MacLane's coherence theorem and the constructions of the free
monoidal category and free strict monoidal category generated by a
given category. The coherence theorem is proved syntactically, using
a structurally recursive approach to reduction of terms that might
have some novel aspects. We also give proofs of some results given by
Etingof et al, which may prove useful in a formal setting. In
particular, we show that the left and right unitors need not be taken
as given data in the definition of monoidal category, nor does the
definition of monoidal functor need to take as given a specific
isomorphism expressing the preservation of the unit object. Our
definitions of monoidal category and monoidal functor are stated so as
to take advantage of the economy afforded by these facts.
extra-history =
Change history:
[2017-05-18]:
Integrated material from MonoidalCategory/Category3Adapter into Category3/ and deleted adapter.
(revision 015543cdd069)<br>
[2018-05-29]:
Modifications required due to 'Category3' changes. Introduced notation for "in hom".
(revision 8318366d4575)<br>
[2020-02-15]:
Cosmetic improvements.
(revision a51840d36867)<br>
[Card_Multisets]
title = Cardinality of Multisets
author = Lukas Bulwahn <mailto:lukas.bulwahn@gmail.com>
notify = lukas.bulwahn@gmail.com
date = 2016-06-26
topic = Mathematics/Combinatorics
abstract =
<p>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.</p> <p>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.</p>
[Posix-Lexing]
title = POSIX Lexing with Derivatives of Regular Expressions
author = Fahad Ausaf <http://kcl.academia.edu/FahadAusaf>, Roy Dyckhoff <https://rd.host.cs.st-andrews.ac.uk>, Christian Urban <http://www.inf.kcl.ac.uk/staff/urbanc/>
notify = christian.urban@kcl.ac.uk
date = 2016-05-24
topic = Computer science/Automata and formal languages
abstract =
Brzozowski introduced the notion of derivatives for regular
expressions. They can be used for a very simple regular expression
matching algorithm. Sulzmann and Lu cleverly extended this algorithm
in order to deal with POSIX matching, which is the underlying
disambiguation strategy for regular expressions needed in lexers. In
this entry we give our inductive definition of what a POSIX value is
and show (i) that such a value is unique (for given regular expression
and string being matched) and (ii) that Sulzmann and Lu's algorithm
always generates such a value (provided that the regular expression
matches the string). We also prove the correctness of an optimised
version of the POSIX matching algorithm.
[LocalLexing]
title = Local Lexing
author = Steven Obua <mailto:steven@recursivemind.com>
topic = Computer science/Automata and formal languages
date = 2017-04-28
notify = steven@recursivemind.com
abstract =
This formalisation accompanies the paper <a
href="https://arxiv.org/abs/1702.03277">Local
Lexing</a> 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 <http://www.andreas-lochbihler.de>
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
<emph>The Max-Flow Min-Cut theorem for countable networks</emph> by
Aharoni et al. Additionally, we prove a characterisation of the
lifting operation for relations on discrete probability distributions,
which leads to a concise proof of its distributivity over relation
composition.
notify = mail@andreas-lochbihler.de
extra-history =
Change history:
[2017-09-06]:
derive characterisation for the lifting operations on discrete distributions from finite version of the max-flow min-cut theorem
(revision a7a198f5bab0)<br>
[Liouville_Numbers]
title = Liouville numbers
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
date = 2015-12-28
topic = Mathematics/Analysis, Mathematics/Number theory
abstract =
<p>
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.
</p><p>
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.
</p><p>
The proof is very elementary and requires only standard arithmetic, the Mean
Value Theorem for polynomials, and the boundedness of polynomials on compact
intervals.
</p>
notify = eberlm@in.tum.de
[Triangle]
title = Basic Geometric Properties of Triangles
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
date = 2015-12-28
topic = Mathematics/Geometry
abstract =
<p>
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.
</p><p>
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.
</p>
notify = eberlm@in.tum.de
[Prime_Harmonic_Series]
title = The Divergence of the Prime Harmonic Series
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
date = 2015-12-28
topic = Mathematics/Number theory
abstract =
<p>
In this work, we prove the lower bound <span class="nobr">ln(H_n) -
ln(5/3)</span> for the
partial sum of the Prime Harmonic series and, based on this, the divergence of
the Prime Harmonic Series
<span class="nobr">∑[p&thinsp;prime]&thinsp;·&thinsp;1/p.</span>
</p><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.
</p>
notify = eberlm@in.tum.de
[Descartes_Sign_Rule]
title = Descartes' Rule of Signs
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
date = 2015-12-28
topic = Mathematics/Analysis
abstract =
<p>
Descartes' Rule of Signs relates the number of positive real roots of a
polynomial with the number of sign changes in its coefficient sequence.
</p><p>
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.
</p>
notify = eberlm@in.tum.de
[Euler_MacLaurin]
title = The Euler–MacLaurin Formula
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Analysis
date = 2017-03-10
notify = eberlm@in.tum.de
abstract =
<p>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.</p> <p>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 <em>Concrete Mathematics</em> that is
more useful for deriving asymptotic estimates.</p> <p>As
example applications, we use that formula to derive the full
asymptotic expansion of the harmonic numbers and the sum of inverse
squares.</p>
[Card_Partitions]
title = Cardinality of Set Partitions
author = Lukas Bulwahn <mailto:lukas.bulwahn@gmail.com>
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 <mailto:lukas.bulwahn@gmail.com>
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 <http://www.sci.kagoshima-u.ac.jp/~furusawa/>, Georg Struth <http://www.dcs.shef.ac.uk/~georg>
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 <mailto:pasquale.noce.lavoro@gmail.com>
date = 2015-06-11
topic = Computer science/Security, Computer science/Concurrency/Process calculi
abstract =
<p>
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.
</p><p>
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.
</p><p>
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.
</p><p>
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.
</p>
notify =
[Noninterference_Ipurge_Unwinding]
title = The Ipurge Unwinding Theorem for CSP Noninterference Security
author = Pasquale Noce <mailto:pasquale.noce.lavoro@gmail.com>
date = 2015-06-11
topic = Computer science/Security
abstract =
<p>
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.
</p><p>
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.
</p><p>
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.
</p><p>
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.
</p>
notify =
[List_Interleaving]
title = Reasoning about Lists via List Interleaving
author = Pasquale Noce <mailto:pasquale.noce.lavoro@gmail.com>
date = 2015-06-11
topic = Computer science/Data structures
abstract =
<p>
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.
</p><p>
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.
</p>
notify =
[Residuated_Lattices]
title = Residuated Lattices
author = Victor B. F. Gomes <mailto:vborgesferreiragomes1@sheffield.ac.uk>, Georg Struth <mailto:g.struth@sheffield.ac.uk>
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 <http://peteg.org>, Tony Hosking <https://www.cs.purdue.edu/homes/hosking/>, Kai Engelhardt <>
date = 2015-04-13
topic = Computer science/Algorithms/Concurrent
abstract =
<p>
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.</p>
<p>
This development accompanies the PLDI 2015 paper of the same name.
</p>
notify = peteg42@gmail.com
[List_Update]
title = Analysis of List Update Algorithms
author = Maximilian P.L. Haslbeck <http://in.tum.de/~haslbema/>, Tobias Nipkow <http://www21.in.tum.de/~nipkow>
date = 2016-02-17
topic = Computer science/Algorithms/Online
abstract =
<p>
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 <i>Online Computation
and Competitive Analysis</i> by Borodin and El-Yaniv.
</p>
<p>
For an informal description see the FSTTCS 2016 publication
<a href="http://www21.in.tum.de/~nipkow/pubs/fsttcs16.html">Verified Analysis of List Update Algorithms</a>
by Haslbeck and Nipkow.
</p>
notify = nipkow@in.tum.de
[ConcurrentIMP]
title = Concurrent IMP
author = Peter Gammie <http://peteg.org>
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 <http://peteg.org>
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 <mailto:adbrucker@0x5f.org>, Lukas Brügger <mailto:lukas.a.bruegger@gmail.com>, Burkhart Wolff <mailto:wolff@lri.fr>
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 <https://www.brucker.ch>, Lukas Brügger<>, Burkhart Wolff <https://www.lri.fr/~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 <http://www.tbrk.org>, Peter Höfner <http://www.hoefner-online.de/>
date = 2014-10-23
topic = Computer science/Concurrency/Process calculi
abstract =
<p>
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.
<p>
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.
</p><p>
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.
</p>
notify = tim@tbrk.org
[Show]
title = Haskell's Show Class in Isabelle/HOL
author = Christian Sternagel <mailto:c.sternagel@gmail.com>, René Thiemann <mailto:rene.thiemann@uibk.ac.at>
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.<br>
[2015-04-10]: Moved development for old-style datatypes into subdirectory
"Old_Datatype".<br>
notify = christian.sternagel@uibk.ac.at, rene.thiemann@uibk.ac.at
[Certification_Monads]
title = Certification Monads
author = Christian Sternagel <mailto:c.sternagel@gmail.com>, René Thiemann <mailto:rene.thiemann@uibk.ac.at>
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 <mailto:Freek.Verbeek@ou.nl>, Sergey Tverdyshev <mailto:stv@sysgo.com>, Oto Havle <mailto:oha@sysgo.com>, Holger Blasum <mailto:holger.blasum@sysgo.com>, Bruno Langenstein <mailto:langenstein@dfki.de>, Werner Stephan <mailto:stephan@dfki.de>, Yakoub Nemouchi <mailto:nemouchi@lri.fr>, Abderrahmane Feliachi <mailto:abderrahmane.feliachi@lri.fr>, Burkhart Wolff <mailto:wolff@lri.fr>, Julien Schmaltz <mailto:Julien.Schmaltz@ou.nl>
date = 2014-07-18
topic = Computer science/Security
abstract =
<p>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.</p>
<p>
This document corresponds to the deliverable D31.1 of the EURO-MILS
Project <a href="http://www.euromils.eu">http://www.euromils.eu</a>.</p>
notify =
[pGCL]
title = pGCL for Isabelle
author = David Cock <mailto:david.cock@nicta.com.au>
date = 2014-07-13
topic = Computer science/Programming languages/Language definitions
abstract =
<p>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.</p>
<p> This package provides both a shallow embedding of the language
primitives, and an annotation and refinement framework. The generated
document includes a brief tutorial.</p>
notify =
[Noninterference_CSP]
title = Noninterference Security in Communicating Sequential Processes
author = Pasquale Noce <mailto:pasquale.noce.lavoro@gmail.com>
date = 2014-05-23
topic = Computer science/Security
abstract =
<p>
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.
</p>
<p>
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.
</p>
<p>
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.
</p>
notify = pasquale.noce.lavoro@gmail.com
[Floyd_Warshall]
title = The Floyd-Warshall Algorithm for Shortest Paths
author = Simon Wimmer <http://in.tum.de/~wimmers>, Peter Lammich <http://www21.in.tum.de/~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 <http://www.doc.ic.ac.uk/~jpw48>
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 <http://www.tbrk.org>
date = 2014-03-08
topic = Computer science/Concurrency/Process calculi
abstract =
<p>
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.</p>
<p>
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).</p>
notify = tim@tbrk.org
[Selection_Heap_Sort]
title = Verification of Selection and Heap Sort Using Locales
author = Danijela Petrovic <http://www.matf.bg.ac.rs/~danijela>
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 <mailto:rene.thiemann@uibk.ac.at>
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.
<p>
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 <https://www.mpi-inf.mpg.de/~crizkall/>
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 <http://pp.ipd.kit.edu/~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 <http://pp.ipd.kit.edu/~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).
<p>
We use syntax and the denotational semantics from the entry
"Launchbury", where we formalized Launchbury's natural semantics for
lazy evaluation.
<p>
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.
<p>
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 <http://www.itu.dk/people/jebe>
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.
<p>
This entry is described in detail in <a href="http://www.itu.dk/people/jebe/files/thesis.pdf">Bengtson's thesis</a>.
notify =
[Pi_Calculus]
title = The pi-calculus in nominal logic
author = Jesper Bengtson <http://www.itu.dk/people/jebe>
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.
<p>
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.
<p>
This entry is described in detail in <a href="http://www.itu.dk/people/jebe/files/thesis.pdf">Bengtson's thesis</a>.
notify =
[Psi_Calculi]
title = Psi-calculi in Isabelle
author = Jesper Bengtson <http://www.itu.dk/people/jebe>
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.
<p>
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.
<p>
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.
<p>
This entry is described in detail in <a href="http://www.itu.dk/people/jebe/files/thesis.pdf">Bengtson's thesis</a>.
notify =
[Encodability_Process_Calculi]
title = Analysing and Comparing Encodability Criteria for Process Calculi
author = Kirstin Peters <mailto:kirstin.peters@tu-berlin.de>, Rob van Glabbeek <http://theory.stanford.edu/~rvg/>
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 <mailto:abderrahmane.feliachi@lri.fr>, Burkhart Wolff <mailto:wolff@lri.fr>, Marie-Claude Gaudel <mailto:mcg@lri.fr>
contributors = Makarius Wenzel <mailto:Makarius.wenzel@lri.fr>
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).
<p>
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 <mailto:b.n@wwu.de>, Peter Lammich <http://www21.in.tum.de/~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 <http://www21.in.tum.de/~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.
<p>
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.
<p>
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<br>
[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.<br>
[2012-07] New example: Nested DFS for emptiness check of Buchi-automata with witness.<br>
New feature:
fo_rule method to apply resolution using first-order matching. Useful for arg_conf, fun_cong.<br>
[2012-08] Adaptation to ICF v2.<br>
[2012-10-05] Adaptations to include support for Automatic Refinement Framework.<br>
[2013-09] This entry now depends on Automatic Refinement<br>
[2014-06] New feature: vc_solve method to solve verification conditions.
Maintenace changes: VCG-rules for nfoldli, improved setup for FOREACH-loops.<br>
[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.<br>
[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 <http://www21.in.tum.de/~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 <mailto:lammich@in.tum.de>
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.
<p>
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 <mailto:lammich@in.tum.de>, 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 <http://www21.in.tum.de/~lammich>, Simon Wimmer <http://in.tum.de/~wimmers>
topic = Computer science/Algorithms
date = 2018-04-27
notify = lammich@in.tum.de
abstract =
<a
href="http://www.pm.inf.ethz.ch/research/verifythis.html">VerifyThis
2018</a> 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 <http://users.abo.fi/vpreotea/>
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 <http://users.abo.fi/vpreotea/>
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 <http://users.abo.fi/vpreotea/>
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 <mailto:ralph.romanos@student.ecp.fr>, Lawrence C. Paulson <http://www.cl.cam.ac.uk/~lp15/>
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 <http://net.in.tum.de/~diekmann>, Julius Michaelis <http://liftm.de>, Lars Hupel <https://www21.in.tum.de/~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 <http://net.in.tum.de/~diekmann>, Julius Michaelis <http://liftm.de>, Maximilian Haslbeck<http://cl-informatik.uibk.ac.at/users/mhaslbeck//>
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
<a href="http://dl.ifip.org/db/conf/networking/networking2016/1570232858.pdf">Verified iptables Firewall
Analysis</a>, IFIP Networking 2016.
[Iptables_Semantics]
title = Iptables Semantics
author = Cornelius Diekmann <http://net.in.tum.de/~diekmann>, Lars Hupel <https://www21.in.tum.de/~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 <a
href="https://www.isa-afp.org/entries/Simple_Firewall.html">Simple_Firewall</a>)
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 <a
href="http://iptables.isabelle.systems">fffuu</a>. The tool does not
require any input &mdash;except for the <tt>iptables-save</tt> dump of
the analyzed firewall&mdash; 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 <http://liftm.de>, Cornelius Diekmann <http://net.in.tum.de/~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 <http://peteg.org>
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 <mailto:tjm1983@gmail.com>
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.
<p>
An earlier version of this work was the subject of the author's
<a href="http://researcharchive.vuw.ac.nz/handle/10063/2315">MSc thesis</a>,
which contains natural-language explanations of some of the
more interesting proofs.
notify = tjm1983@gmail.com
[General-Triangle]
title = The General Triangle Is Unique
author = Joachim Breitner <mailto:mail@joachim-breitner.de>
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 <http://rok.strnisa.com/lj/>, Matthew Parkinson <http://research.microsoft.com/people/mattpark/>
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 <mailto:grechukbogdan@yandex.ru>
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 <mailto:immler@in.tum.de>
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 <http://www.in.tum.de/~krauss>, Tobias Nipkow <http://www21.in.tum.de/~nipkow>
contributors = Manuel Eberl <https://www21.in.tum.de/~eberlm>
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. <i>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.</i> <P> 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<br>
[2012-05-10]: Tobias Nipkow added extended regular expressions<br>
[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 <http://www21.in.tum.de/~nipkow>, Dmitriy Traytel <mailto:traytel@in.tum.de>
+author = Tobias Nipkow <http://www21.in.tum.de/~nipkow>, Dmitriy Traytel <https://traytel.bitbucket.io>
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.
<a href="http://www21.in.tum.de/~nipkow/pubs/itp14.html">
The formalization is described in a paper of the same name presented at
Interactive Theorem Proving 2014</a>.
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 <mailto:traytel@in.tum.de>, Tobias Nipkow <http://www21.in.tum.de/~nipkow>
+author = Dmitriy Traytel <https://traytel.bitbucket.io>, Tobias Nipkow <http://www21.in.tum.de/~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.
<p>
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.
<p>
The formalization is described in this <a href="http://www21.in.tum.de/~nipkow/pubs/icfp13.html">ICFP 2013 functional pearl</a>.
notify = traytel@in.tum.de, nipkow@in.tum.de
[Formula_Derivatives]
title = Derivatives of Logical Formulas
-author = Dmitriy Traytel <http://www21.in.tum.de/~traytel>
+author = Dmitriy Traytel <https://traytel.bitbucket.io>
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 <em>not</em> 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).
<p>
The WS1S instance is described in the draft paper <a
href="https://people.inf.ethz.ch/trayteld/papers/csl15-ws1s_derivatives/index.html">A
Coalgebraic Decision Procedure for WS1S</a> 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 <http://www.inf.kcl.ac.uk/staff/urbanc/>
contributors = Manuel Eberl <https://www21.in.tum.de/~eberlm>
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 <https://nms.kcl.ac.uk/christian.urban/>, Sebastiaan J. C. Joosten <http://sjcjoosten.nl/>
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 <mailto:Maksym.Bortin@nicta.com.au>
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 <http://www21.in.tum.de/~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 <http://www.in.tum.de/~berghofe>, 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 <http://www21.in.tum.de/~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 <mailto:helke@cs.tu-berlin.de>, Florian Kammüller <mailto:flokam@cs.tu-berlin.de>
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 <http://www.loria.fr/~merz>
topic = Computer science/Automata and formal languages
date = 2012-05-07
abstract = <p>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.</p> <p>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.</p>
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 <mailto:traytel@in.tum.de>
+author = Dmitriy Traytel <https://traytel.bitbucket.io>
topic = Computer science/Automata and formal languages
date = 2013-11-15
abstract = <p>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.</p>
<p>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.</p>
<p>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.</p>
notify = traytel@in.tum.de
[Tree-Automata]
title = Tree Automata
author = Peter Lammich <http://www21.in.tum.de/~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 <http://www21.in.tum.de/~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 <http://www21.in.tum.de/~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 <mailto:hoelzl@in.tum.de>
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.
<p>
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 <http://users.abo.fi/vpreotea/>, Ralph-Johan Back <http://users.abo.fi/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 <i>next</i> 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 <mailto:c.sternagel@gmail.com>
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.<br>
[2018-09-17]:
Added theory Efficient_Mergesort that works exclusively with the mutual
induction schemas generated by the function package.<br>
[2018-09-19]:
Added theory Mergesort_Complexity that proves an upper bound on the number of
comparisons that are required by mergesort.<br>
[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ć <http://poincare.matf.bg.ac.rs/~filip/>
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: <ul> <li> a solver based on classical DPLL procedure (using only a backtrack-search with unit propagation),</li> <li> a very general solver with backjumping and learning (similar to the description given in (Nieuwenhuis et al., 2006)), and</li> <li> a solver with a specific conflict analysis algorithm (similar to the description given in (Krstic et al., 2007)).</li> </ul> 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 <mailto:c.sternagel@gmail.com>, René Thiemann <mailto:rene.thiemann@uibk.ac.at>
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 <mailto:rene.thiemann@uibk.ac.at>
license = LGPL
abstract =
<p>
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.
</p><p>
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.
</p>
notify = rene.thiemann@uibk.ac.at
[MuchAdoAboutTwo]
title = Much Ado About Two
author = Sascha Böhme <http://www21.in.tum.de/~boehmes/>
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 <http://www.fceia.unr.edu.ar/~mauro/>, Stephan Merz <http://www.loria.fr/~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 <http://users.cecs.anu.edu.au/~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 <http://www.cs.famaf.unc.edu.ar/~damian/>
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 <a href="http://users.rsise.anu.edu.au/~tiu/clocksync.pdf">"Verification of Clock Synchronization Algorithms: Experiments on a combination of deductive tools"</a> in proceedings of AVOCS 2005. In this work the correctness of Schneider schema was also verified using Isabelle (entry <a href="GenClock.html">GenClock</a> 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 <mailto:henri.debrat@loria.fr>, Stephan Merz <http://www.loria.fr/~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".
<p>
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.
<p>
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 <mailto:sprenger@inf.ethz.ch>
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 <mailto:joseph.lallemand@loria.fr>, Christoph Sprenger <mailto:sprenger@inf.ethz.ch>
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 <mailto:sprenger@inf.ethz.ch>, 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 <mailto:rachid.guerraoui@epfl.ch>, Viktor Kuncak <http://lara.epfl.ch/~kuncak/>, Giuliano Losa <mailto:giuliano.losa@epfl.ch>
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 <http://www21.in.tum.de/~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.
<p>
A preliminary version of this work (without pairing heaps) is described
in a <a href="http://www21.in.tum.de/~nipkow/pubs/itp15.html">paper</a>
published in the proceedings of the conference on Interactive
Theorem Proving ITP 2015. An extended version of this publication
is available <a href="http://www21.in.tum.de/~nipkow/pubs/jfp16.html">here</a>.
extra-history =
Change history:
[2015-03-17]: Added pairing heaps by Hauke Brinkop.<br>
[2016-07-12]: Moved splay heaps from here to Splay_Tree<br>
[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 <http://www21.in.tum.de/~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.
<P>
A full description is found in a
<a href="http://www21.in.tum.de/~nipkow/pubs">companion paper</a>.
notify = nipkow@in.tum.de
[AVL-Trees]
title = AVL Trees
author = Tobias Nipkow <http://www21.in.tum.de/~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 <tt>gerwin.klein@nicta.com.au</tt>.
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 <http://lara.epfl.ch/~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 <http://www21.in.tum.de/~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).
<p>
The amortized complexity of splay trees and heaps is analyzed in the AFP entry
<a href="http://isa-afp.org/entries/Amortized_Complexity.html">Amortized Complexity</a>.
extra-history =
Change history:
[2016-07-12]: Moved splay heaps here from Amortized_Complexity
[Root_Balanced_Tree]
title = Root-Balanced Tree
author = Tobias Nipkow <http://www21.in.tum.de/~nipkow>
notify = nipkow@in.tum.de
date = 2017-08-20
topic = Computer science/Data structures
abstract =
<p>
Andersson introduced <em>general balanced trees</em>,
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 <em>root-balanced trees</em>. Using a lightweight model
of execution time, amortized logarithmic complexity is verified in
the theorem prover Isabelle.
</p>
<p>
This is the Isabelle formalization of the material decribed in the APLAS 2017 article
<a href="http://www21.in.tum.de/~nipkow/pubs/aplas17.html">Verified Root-Balanced Trees</a>
by the same author, which also presents experimental results that show
competitiveness of root-balanced with AVL and red-black trees.
</p>
[Skew_Heap]
title = Skew Heap
author = Tobias Nipkow <http://www21.in.tum.de/~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.
<p>
The amortized complexity of skew heaps is analyzed in the AFP entry
<a href="http://isa-afp.org/entries/Amortized_Complexity.html">Amortized Complexity</a>.
notify = nipkow@in.tum.de
[Pairing_Heap]
title = Pairing Heap
author = Hauke Brinkop <mailto:hauke.brinkop@googlemail.com>, Tobias Nipkow <http://www21.in.tum.de/~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.
<p>
The amortized complexity of pairing heaps is analyzed in the AFP article
<a href="http://isa-afp.org/entries/Amortized_Complexity.html">Amortized Complexity</a>.
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 <http://www21.in.tum.de/~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 <mailto:neumannr@in.tum.de>
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 <mailto:rene.meis@uni-muenster.de>, Finn Nielsen <mailto:finn.nielsen@uni-muenster.de>, Peter Lammich <http://www21.in.tum.de/~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 <em>findMin</em>, <em>deleteMin</em>,
<em>insert</em>, and <em>meld</em> operations,
skew binomial heaps have constant time <em>findMin</em>, <em>insert</em>,
and <em>meld</em> operations, and only the <em>deleteMin</em>-operation is
logarithmic. This is achieved by using <em>skew links</em> to avoid
cascading linking on <em>insert</em>-operations, and <em>data-structural
bootstrapping</em> to get constant-time <em>findMin</em> and <em>meld</em>
operations. Our implementation follows the paper by Brodal and Okasaki.
notify = peter.lammich@uni-muenster.de
[Finger-Trees]
title = Finger Trees
author = Benedikt Nordhoff <mailto:b_nord01@uni-muenster.de>, Stefan Körner <mailto:s_koer03@uni-muenster.de>, Peter Lammich <http://www21.in.tum.de/~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
<em>monotone predicate</em> 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 <http://www.andreas-lochbihler.de>, Tobias Nipkow <http://www21.in.tum.de/~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 <http://www.andreas-lochbihler.de>
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)<br>
[2010-11-04]:
new conversion function from FinFun to list of elements in the domain
(revision 0c167102e6ed)<br>
[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 <http://www21.in.tum.de/~lammich>
contributors = Andreas Lochbihler <http://www.andreas-lochbihler.de>, 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.<br>
[2010-12-01]: New Interfaces: Priority Queues, Annotated Lists. Implemented by finger trees, (skew) binomial queues.<br>
[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<br>
[2012-04-25]: New iterator foundation by Tuerk. Various maintenance changes.<br>
[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.<br>
[2013-09]: Added Generic Collection Framework based on Autoref. The GenCF provides: Arbitrary nesting, full integration with Autoref.<br>
[2014-06]: Maintenace changes to GenCF: Optimized inj_image on list_set. op_set_cart (Cartesian product). big-Union operation. atLeastLessThan - operation ({a..&lt;b})<br>
notify = lammich@in.tum.de
[Containers]
title = Light-weight Containers
author = Andreas Lochbihler <http://www.andreas-lochbihler.de>
contributors = René Thiemann <mailto:rene.thiemann@uibk.ac.at>
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.
<p>
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)<br>
[2013-09-20]:
provide generators for canonical type class instantiations
(revision 159f4401f4a8 by René Thiemann)<br>
[2014-07-08]: add support for going from partial functions to mappings (revision 7a6fc957e8ed)<br>
[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 <http://www.mit.edu/~kkz/>, Viktor Kuncak <http://lara.epfl.ch/~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 <mailto:rene.thiemann@uibk.ac.at>
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.
<p>
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.
<p>
Our formalization was performed as part of the <a href="http://cl-informatik.uibk.ac.at/software/ceta">IsaFoR/CeTA</a> project.
With our new tactic we could completely remove
tedious proofs for linear orders of two datatypes.
<p>
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 <mailto:c.sternagel@gmail.com>, René Thiemann <mailto:rene.thiemann@uibk.ac.at>
date = 2015-03-11
topic = Computer science/Data structures
abstract =
<p>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.</p>
<p>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.</p>
<p>Our formalization was performed as part of the <a href="http://cl-informatik.uibk.ac.at/software/ceta">IsaFoR/CeTA</a> 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.</p>
notify = rene.thiemann@uibk.ac.at
[List-Index]
title = List Index
date = 2010-02-20
author = Tobias Nipkow <http://www21.in.tum.de/~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 <mailto:c.sternagel@gmail.com>, René Thiemann <http://cl-informatik.uibk.ac.at/~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 <a
href="http://cl-informatik.uibk.ac.at/software/ceta">CeTA</a> 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 <mailto:prathamesh@imsc.res.in>
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 <http://www21.in.tum.de/~blanchet>
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 <mailto:rene.thiemann@uibk.ac.at>
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 <mailto:rene.thiemann@uibk.ac.at>
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 <tt>{x :: 'a. P x}</tt>,
provided the definition is of the form
<tt>f ys = (if check ys then Some(generate ys :: 'a) else None)</tt> where
<tt>ys</tt> is a list of variables <tt>y1 ... yn</tt> and
<tt>check ys ==> P(generate ys)</tt> can be proved.
<p>
In principle, such a definition is also directly possible using the
<tt>lift_definition</tt> 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 <tt>check ys</tt> 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 <http://www.andreas-lochbihler.de>
contributors = Johannes Hölzl <mailto:hoelzl@in.tum.de>
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.<br>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)<br>
[2010-06-28]:
new codatatype terminated lazy lists
(revision e12de475c558)<br>
[2010-08-04]:
terminated lazy lists: setup for quotient package;
more lemmas
(revision 6ead626f1d01)<br>
[2010-08-17]:
Koenig's lemma as an example application for coinductive lists
(revision f81ce373fa96)<br>
[2011-02-01]:
lazy implementation of coinductive (terminated) lists for the code generator
(revision 6034973dce83)<br>
[2011-07-20]:
new codatatype resumption
(revision 811364c776c7)<br>
[2012-06-27]:
new codatatype stream with operations (with contributions by Peter Gammie)
(revision dd789a56473c)<br>
[2013-03-13]:
construct codatatypes with the BNF package and adjust the definitions and proofs,
setup for lifting and transfer packages
(revision f593eda5b2c0)<br>
[2013-09-20]:
stream theory uses type and operations from HOL/BNF/Examples/Stream
(revision 692809b2b262)<br>
[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)<br>
notify = mail@andreas-lochbihler.de
[Stream-Fusion]
title = Stream Fusion
author = Brian Huffman <http://cs.pdx.edu/~brianh>
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 <a href="http://hackage.haskell.org/package/stream-fusion">online</a>.)<br><br>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 <mailto:huffman@in.tum.de>
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 <i>Formal Verification of Monad
Transformers</i> by the author. The formalization is a revised and
updated version of earlier joint work with Matthews and White.
<P>
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 <http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php>
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 <http://www.cs.cornell.edu/~jnfoster/>, Dimitrios Vytiniotis <http://research.microsoft.com/en-us/people/dimitris/>
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 <http://www.cse.unsw.edu.au/~kleing/>, Tobias Nipkow <http://www21.in.tum.de/~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 <http://www.andreas-lochbihler.de>
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)<br>
[2009-04-27]:
added verified compiler from source code to bytecode;
encapsulate native methods in separate semantics
(revision e4f26541e58a)<br>
[2009-11-30]:
extended compiler correctness proof to infinite and deadlocking computations
(revision e50282397435)<br>
[2010-06-08]:
added thread interruption;
new abstract memory model with sequential consistency as implementation
(revision 0cb9e8dbd78d)<br>
[2010-06-28]:
new thread interruption model
(revision c0440d0a1177)<br>
[2010-10-15]:
preliminary version of the Java memory model for source code
(revision 02fee0ef3ca2)<br>
[2010-12-16]:
improved version of the Java memory model, also for bytecode
executable scheduler for source code semantics
(revision 1f41c1842f5a)<br>
[2011-02-02]:
simplified code generator setup
new random scheduler
(revision 3059dafd013f)<br>
[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)<br>
[2012-02-16]:
added example programs
(revision bf0b06c8913d)<br>
[2012-11-21]:
type safety proof for the Java memory model,
allow spurious wake-ups
(revision 76063d860ae0)<br>
[2013-05-16]:
support for non-deterministic memory allocators
(revision cc3344a49ced)<br>
[2017-10-20]:
add an atomic compare-and-swap operation for volatile fields
(revision a6189b1d6b30)<br>
notify = mail@andreas-lochbihler.de
[Locally-Nameless-Sigma]
title = Locally Nameless Sigma Calculus
author = Ludovic Henrio <mailto:Ludovic.Henrio@sophia.inria.fr>, Florian Kammüller <mailto:flokam@cs.tu-berlin.de>, Bianca Lutz <mailto:sowilo@cs.tu-berlin.de>, Henry Sudhof <mailto:hsudhof@cs.tu-berlin.de>
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 <http://www.cs.mdx.ac.uk/people/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 <mailto:maria.spichkova@rmit.edu.au>
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 <mailto:tuong@users.gforge.inria.fr>, Burkhart Wolff <https://www.lri.fr/~wolff/>
date = 2015-09-16
topic = Computer science/Programming languages/Language definitions
abstract =
We represent a theory <i>of</i> (a fragment of) Isabelle/HOL <i>in</i>
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.
<p>
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.
<p>
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.
<p>
This theory is drawn from the
<a href="http://isa-afp.org/entries/Featherweight_OCL.html">Featherweight OCL</a>
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.
<p>
Gained experience from this project shows that the compiled code is sufficiently
efficient for practical purposes while being based on a formal <i>model</i>
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 <https://www.lri.fr/~ftuong/>, Burkhart Wolff <https://www.lri.fr/~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 <mailto:peteg42@gmail.com>
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 <http://www.in.tum.de/~berghofe>
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<sub>&lt;:</sub>. 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<sub>&lt;:</sub>, 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 <mailto:doczkal@ps.uni-saarland.de>
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 <http://www21.in.tum.de/~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 <i>W</i> for MiniML (simply-typed lambda terms with <tt>let</tt>) due to Milner. It proves the soundness and completeness of <i>W</i> 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 <mailto:kleing@cse.unsw.edu.au>, Rafal Kolanski <mailto:rafal.kolanski@nicta.com.au>, Andrew Boyton <mailto:andrew.boyton@nicta.com.au>
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. <P> The ex directory contains example instantiations that include structures such as a heap or virtual memory. <P> 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. <P> 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 <http://www21.in.tum.de/~lammich>, Rene Meis <mailto:rene.meis@uni-due.de>
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.
<br>
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 <http://www.dmi.unict.it/~giamp/>
date = 2012-05-02
topic = Computer science/Security
abstract = This document contains the full theory files accompanying article <i>Inductive Study of Confidentiality --- for Everyone</i> in <i>Formal Aspects of Computing</i>. 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 <mailto:uuomul@yahoo.com>, Johannes Hölzl <mailto:hoelzl@in.tum.de>
+author = Andrei Popescu <https://www.andreipopescu.uk>, Johannes Hölzl <mailto:hoelzl@in.tum.de>
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.
<p>
An <a href="http://www21.in.tum.de/~nipkow/pubs/cpp12.html">article</a>
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 <mailto:grewe@cs.tu-darmstadt.de>, Heiko Mantel <mailto:mantel@mais.informatik.tu-darmstadt.de>, Daniel Schoepe <mailto:daniel@schoepe.org>
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.
<p>
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 <http://people.eng.unimelb.edu.au/tobym/>, Robert Sison<>, Edward Pierzchalski<>, Christine Rizkallah<https://www.mpi-inf.mpg.de/~crizkall/>
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 <http://people.eng.unimelb.edu.au/tobym/>, Robert Sison<>, Edward Pierzchalski<>, Christine Rizkallah<https://www.mpi-inf.mpg.de/~crizkall/>
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 <https://people.eng.unimelb.edu.au/tobym/>
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 <mailto:grewe@cs.tu-darmstadt.de>, Alexander Lux <mailto:lux@mais.informatik.tu-darmstadt.de>, Heiko Mantel <mailto:mantel@mais.informatik.tu-darmstadt.de>, Jens Sauer <mailto:sauer@mais.informatik.tu-darmstadt.de>
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.
<p>
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.
<p>
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 <mailto:grewe@cs.tu-darmstadt.de>, Alexander Lux <mailto:lux@mais.informatik.tu-darmstadt.de>, Heiko Mantel <mailto:mantel@mais.informatik.tu-darmstadt.de>, Jens Sauer <mailto:sauer@mais.informatik.tu-darmstadt.de>
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.
<p>
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.
<p>
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.
<p>
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 <http://pp.info.uni-karlsruhe.de/personhp/gregor_snelting.php>, Daniel Wasserrab <http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php>
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 <http://www21.in.tum.de/~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 <http://www.cosc.canterbury.ac.nz/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 <http://staffwww.dcs.shef.ac.uk/people/G.Struth/>, Tjark Weber <http://user.it.uu.se/~tjawe125/>
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.
<p>
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).
<p>
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 <http://www.dcs.shef.ac.uk/~victor>, Georg Struth <http://www.dcs.shef.ac.uk/~georg>
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 <http://www.dcs.shef.ac.uk/~victor>, Walter Guttmann <http://www.cosc.canterbury.ac.nz/walter.guttmann/>, Peter Höfner <http://www.hoefner-online.de/>, Georg Struth <http://www.dcs.shef.ac.uk/~georg>, Tjark Weber <http://user.it.uu.se/~tjawe125/>
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 <http://www-users.cs.york.ac.uk/~simonf>, Georg Struth <http://www.dcs.shef.ac.uk/~georg>
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 <http://www.tcs.informatik.uni-muenchen.de/~mhofmann>
date = 2008-12-12
topic = Computer science/Programming languages/Logics
abstract = This document contains the Isabelle/HOL sources underlying the paper <i>A bytecode logic for JML and types</i> 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 <http://users.abo.fi/vpreotea/>, Ralph-Johan Back <http://users.abo.fi/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 <mailto:viorel.preoteasa@aalto.fi>
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 <http://www.tcs.informatik.uni-muenchen.de/~mhofmann>
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.<br><br>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 <http://homepages.inf.ed.ac.uk/ggrov>, Stephan Merz <http://www.loria.fr/~merz>
date = 2011-11-19
topic = Computer science/Programming languages/Logics
abstract = We mechanise the logic TLA*
<a href="http://www.springerlink.com/content/ax3qk557qkdyt7n6/">[Merz 1999]</a>,
an extension of Lamport's Temporal Logic of Actions (TLA)
<a href="http://dl.acm.org/citation.cfm?doid=177492.177726">[Lamport 1994]</a>
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:
<ul>
<li>a theory of infinite sequences, including a formalisation of the concepts of stuttering invariance central to TLA and TLA*;
<li>a definition of the semantics of TLA*, which extends TLA by a mutually-recursive definition of formulas and pre-formulas, generalising TLA action formulas;
<li>a substantial set of derived proof rules, including the TLA* axioms and Lamport's proof rules for system verification;
<li>a set of examples illustrating the usage of Isabelle/TLA* for reasoning about systems.
</ul>
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 <a href="http://www.springerlink.com/content/354026160p14j175/">[Chaudhuri et al 2010]</a>.
notify = ggrov@inf.ed.ac.uk
[Compiling-Exceptions-Correctly]
title = Compiling Exceptions Correctly
author = Tobias Nipkow <http://www21.in.tum.de/~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 <a href="http://www.cs.nott.ac.uk/~gmh/">Hutton</a> and Wright.
notify = nipkow@in.tum.de
[NormByEval]
title = Normalization by Evaluation
author = Klaus Aehlig <http://www.linta.de/~aehlig/>, Tobias Nipkow <http://www21.in.tum.de/~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 <http://www21.in.tum.de/~lammich>, Markus Müller-Olm <http://cs.uni-muenster.de/u/mmo/>
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 <mailto:mail@joachim-breitner.de>
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 <http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php>
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.<br><br>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 <http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php>
date = 2009-11-13
topic = Computer science/Programming languages/Static analysis
abstract = After verifying <a href="Slicing.html">dynamic and static interprocedural slicing</a>, 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 <http://peteg.org>
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 <mailto:rauch@informatik.uni-kl.de>, 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 <http://www21.in.tum.de/~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 <http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php>
date = 2010-03-23
topic = Computer science/Security
abstract =
<p>
In this contribution, we show how correctness proofs for <a
href="Slicing.html">intra-</a> and <a
href="HRB-Slicing.html">interprocedural slicing</a> 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.
</p>
<p>
This entry contains the part for intra-procedural slicing. See entry
<a href="InformationFlowSlicing_Inter.html">InformationFlowSlicing_Inter</a>
for the inter-procedural part.
</p>
extra-history =
Change history:
[2016-06-10]: The original entry <a
href="InformationFlowSlicing.html">InformationFlowSlicing</a> contained both
the <a href="InformationFlowSlicing_Inter.html">inter-</a> and <a
href="InformationFlowSlicing.html">intra-procedural</a> case was split into
two for easier maintenance.
notify =
[InformationFlowSlicing_Inter]
title = Inter-Procedural Information Flow Noninterference via Slicing
author = Daniel Wasserrab <http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php>
date = 2010-03-23
topic = Computer science/Security
abstract =
<p>
In this contribution, we show how correctness proofs for <a
href="Slicing.html">intra-</a> and <a
href="HRB-Slicing.html">interprocedural slicing</a> 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.
</p>
<p>
This entry contains the part for inter-procedural slicing. See entry
<a href="InformationFlowSlicing.html">InformationFlowSlicing</a>
for the intra-procedural part.
</p>
extra-history =
Change history:
[2016-06-10]: The original entry <a
href="InformationFlowSlicing.html">InformationFlowSlicing</a> contained both
the <a href="InformationFlowSlicing_Inter.html">inter-</a> and <a
href="InformationFlowSlicing.html">intra-procedural</a> case was split into
two for easier maintenance.
notify =
[ComponentDependencies]
title = Formalisation and Analysis of Component Dependencies
author = Maria Spichkova <mailto:maria.spichkova@rmit.edu.au>
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 <i>Proof Theory</i> 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 <a href="Completeness-paper.pdf">[pdf]</a>.
notify = lp15@cam.ac.uk
[Ordinal]
title = Countable Ordinals
author = Brian Huffman <http://web.cecs.pdx.edu/~brianh/>
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 <>
+author = Andrei Popescu <https://www.andreipopescu.uk>
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 <http://www.in.tum.de/~berghofe>
contributors = Asta Halkjær From <https://people.compute.dtu.dk/ahfrom/>
date = 2007-08-02
topic = Logic/General logic/Classical first-order logic
abstract = We present a formalization of parts of Melvin Fitting's book "First-Order Logic and Automated Theorem Proving". The formalization covers the syntax of first-order logic, its semantics, the model existence theorem, a natural deduction proof calculus together with a proof of correctness and completeness, as well as the Löwenheim-Skolem theorem.
extra-history =
Change history:
[2018-07-21]: Proved completeness theorem for open formulas. Proofs are now written in the declarative style. Enumeration of pairs and datatypes is automated using the Countable theory.
notify = berghofe@in.tum.de
[Epistemic_Logic]
title = Epistemic Logic
author = Asta Halkjær From <https://people.compute.dtu.dk/ahfrom/>
topic = Logic/General logic/Logics of knowledge and belief
date = 2018-10-29
notify = ahfrom@dtu.dk
abstract =
This work is a formalization of epistemic logic with countably many
agents. It includes proofs of soundness and completeness for the axiom
system K. The completeness proof is based on the textbook
"Reasoning About Knowledge" by Fagin, Halpern, Moses and
Vardi (MIT Press 1995).
[SequentInvertibility]
title = Invertibility in Sequent Calculi
author = Peter Chapman <>
date = 2009-08-28
topic = Logic/Proof theory
license = LGPL
abstract = The invertibility of the rules of a sequent calculus is important for guiding proof search and can be used in some formalised proofs of Cut admissibility. We present sufficient conditions for when a rule is invertible with respect to a calculus. We illustrate the conditions with examples. It must be noted we give purely syntactic criteria; no guarantees are given as to the suitability of the rules.
notify = pc@cs.st-andrews.ac.uk, nipkow@in.tum.de
[LinearQuantifierElim]
title = Quantifier Elimination for Linear Arithmetic
author = Tobias Nipkow <http://www21.in.tum.de/~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 <http://web.cecs.pdx.edu/~brianh/>
date = 2010-03-29
abstract = This theory defines a type constructor representing the free Boolean algebra over a set of generators. Values of type (α)<i>formula</i> 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 <http://www21.in.tum.de/~blanchet>, Andrei Popescu <http://www21.in.tum.de/~popescua>
+author = Jasmin Christian Blanchette <http://www21.in.tum.de/~blanchet>, Andrei Popescu <https://www.andreipopescu.uk>
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.
<p>
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.
<p>
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 <mailto:jasmin.blanchette@gmail.com>, Uwe Waldmann <mailto:waldmann@mpi-inf.mpg.de>, Daniel Wand <mailto:dwand@mpi-inf.mpg.de>
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 <mailto:hbecker@mpi-sws.org>, Jasmin Christian Blanchette <mailto:jasmin.blanchette@gmail.com>, Uwe Waldmann <mailto:waldmann@mpi-inf.mpg.de>, Daniel Wand <mailto:dwand@mpi-inf.mpg.de>
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 <https://www.cs.vu.nl/~abp290/>
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 <mailto:jasmin.blanchette@gmail.com>, Mathias Fleury <mailto:fleury@mpi-inf.mpg.de>, Dmitriy Traytel <mailto:traytel@inf.ethz.ch>
+author = Jasmin Christian Blanchette <mailto:jasmin.blanchette@gmail.com>, Mathias Fleury <mailto:fleury@mpi-inf.mpg.de>, Dmitriy Traytel <https://traytel.bitbucket.io>
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 <mailto:c.sternagel@gmail.com>, René Thiemann <http://cl-informatik.uibk.ac.at/~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
<i>joinability</i>, <i>meetability</i>, <i>conversion</i>, 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 <a
href="http://cl-informatik.uibk.ac.at/software/ceta">CeTA</a> (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. <br>
[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 <mailto:c.sternagel@gmail.com>, René Thiemann <http://cl-informatik.uibk.ac.at/users/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 <i>Isabelle
Formalization of Rewriting</i> <a
href="http://cl-informatik.uibk.ac.at/isafor">IsaFoR</a>,
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 <mailto:mail@joachim-breitner.de>
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 <http://kasterma.net>
date = 2009-08-04
topic = Mathematics/Algebra
abstract = We formalize the usual proof that the group generated by the function k -> k + 1 on the integers gives rise to a cofinitary group.
notify = nipkow@in.tum.de
[Group-Ring-Module]
title = Groups, Rings and Modules
author = Hidetsune Kobayashi <>, L. Chen <>, H. Murao <>
date = 2004-05-18
topic = Mathematics/Algebra
abstract = The theory of groups, rings and modules is developed to a great depth. Group theory results include Zassenhaus's theorem and the Jordan-Hoelder theorem. The ring theory development includes ideals, quotient rings and the Chinese remainder theorem. The module development includes the Nakayama lemma, exact sequences and Tensor products.
notify = lp15@cam.ac.uk
[Robbins-Conjecture]
title = A Complete Proof of the Robbins Conjecture
author = Matthew Wampler-Doty <>
date = 2010-05-22
topic = Mathematics/Algebra
abstract = This document gives a formalization of the proof of the Robbins conjecture, following A. Mann, <i>A Complete Proof of the Robbins Conjecture</i>, 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 <http://www.unirioja.es/cu/jodivaso>, Jesús Aransay <http://www.unirioja.es/cu/jearansa>
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 <i>Linear Algebra Done Right</i>. 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 <http://www21.in.tum.de/~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<br>
[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 <https://home.in.tum.de/~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 <http://www-lti.informatik.rwth-aachen.de/~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 <http://www21.in.tum.de/~immler>, Johannes Hölzl <http://in.tum.de/~hoelzl>
topic = Mathematics/Analysis
date = 2012-04-26
abstract =
<p>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 <i>flow</i> of ODEs.</p>
<p>
Not in the generated document are the following sessions:
<ul>
<li> 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.</li>
<li> HOL-ODE-Examples:
Applications of the numerical algorithms to concrete systems of ODEs.</li>
<li> Lorenz_C0, Lorenz_C1:
Verified algorithms for checking C1-information according to Tucker's proof,
computation of C0-information.</li>
</ul>
</p>
extra-history =
Change history:
[2014-02-13]: added an implementation of the Euler method based on affine arithmetic<br>
[2016-04-14]: added flow and variational equation<br>
[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<br>
[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 <mailto:c.sternagel@gmail.com>, René Thiemann <http://cl-informatik.uibk.ac.at/~thiemann>, Alexander Maletzky <https://risc.jku.at/m/alexander-maletzky/>, Fabian Immler <http://www21.in.tum.de/~immler>, Florian Haftmann <http://isabelle.in.tum.de/~haftmann>, Andreas Lochbihler <http://www.andreas-lochbihler.de>, Alexander Bentkamp <mailto:bentkamp@gmail.com>
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 <a
href="http://cl-informatik.uibk.ac.at/software/ceta">IsaFoR/CeTA-system</a>
which contains several termination techniques. The provided theories have
been essential to formalize polynomial interpretations.
<p>
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.<br>
[2016-10-28]: Added abstract representation of polynomials and authors Maletzky/Immler.<br>
[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".<br>
[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 <mailto:rene.thiemann@uibk.ac.at>
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 <https://www21.in.tum.de/~eberlm>
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
&#8712; &#8477;”.
notify = eberlm@in.tum.de
[Sturm_Tarski]
title = The Sturm-Tarski Theorem
author = Wenda Li <mailto:wl302@cam.ac.uk>
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 <http://in.tum.de/~hoelzl>, Tobias Nipkow <http://www21.in.tum.de/~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.
<p>
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.
<a href="http://arxiv.org/abs/1212.3870">See here for the corresponding paper.</a>
notify = hoelzl@in.tum.de
[Probabilistic_System_Zoo]
title = A Zoo of Probabilistic Systems
author = Johannes Hölzl <http://in.tum.de/~hoelzl>,
Andreas Lochbihler <http://www.andreas-lochbihler.de>,
- Dmitriy Traytel <http://www21.in.tum.de/~traytel>
+ Dmitriy Traytel <https://traytel.bitbucket.io>
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.
<p>
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 <https://www21.in.tum.de/~eberlm>, Johannes Hölzl <http://in.tum.de/~hoelzl>, Tobias Nipkow <http://www21.in.tum.de/~nipkow>
date = 2014-10-09
topic = Mathematics/Probability theory, Computer science/Programming languages/Compiling
abstract =
<a href="https://doi.org/10.1007/978-3-642-36742-7_35">Bhat et al. [TACAS 2013]</a> 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.
<p>
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 <http://www21.in.tum.de/~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.
<p>
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.
<p>
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.
<p>
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 <https://www7.in.tum.de/~sickert>
contributors = Benedikt Seidl <mailto:benedikt.seidl@tum.de>
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. <br>
notify = sickert@in.tum.de
[LTL_to_GBA]
title = Converting Linear-Time Temporal Logic to Generalized Büchi Automata
author = Alexander Schimpf <mailto:schimpfa@informatik.uni-freiburg.de>, Peter Lammich <http://www21.in.tum.de/~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.
<p>
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 <http://www21.in.tum.de/~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 <mailto:rene.neumann@in.tum.de>
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 <https://www7.in.tum.de/~esparza/>,
Peter Lammich <http://www21.in.tum.de/~lammich>,
René Neumann <mailto:rene.neumann@in.tum.de>,
Tobias Nipkow <http://www21.in.tum.de/~nipkow>,
Alexander Schimpf <mailto:schimpfa@informatik.uni-freiburg.de>,
Jan-Georg Smaus <http://www.irit.fr/~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.
<p>
An early version of this model checker is described in the
<a href="http://www21.in.tum.de/~nipkow/pubs/cav13.html">CAV 2013 paper</a>
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<ul><li>Fermat's Last Theorem for exponents 3 and 4 and</li><li>the parametrisation of Pythagorean Triples.</li></ul>
notify = nipkow@in.tum.de, roelofoosterhuis@gmail.com
[Perfect-Number-Thm]
title = Perfect Number Theorem
author = Mark Ijbema <mailto:ijbema@fmf.nl>
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:<ul><li>any prime number of the form 4m+1 can be written as the sum of two squares;</li><li>any natural number can be written as the sum of four squares</li></ul>
notify = nipkow@in.tum.de, roelofoosterhuis@gmail.com
[Lehmer]
title = Lehmer's Theorem
author = Simon Wimmer <mailto:simon.wimmer@tum.de>, Lars Noschinski <http://www21.in.tum.de/~noschinl/>
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.
<p>
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 <mailto:simon.wimmer@tum.de>, Lars Noschinski <http://www21.in.tum.de/~noschinl/>
date = 2013-07-22
topic = Mathematics/Number theory
abstract = In 1975, Pratt introduced a proof system for certifying primes. He showed that a number <i>p</i> is prime iff a primality certificate for <i>p</i> 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 <http://home.in.tum.de/~wimmers/>, Shuwei Hu <mailto:shuwei.hu@tum.de>, Tobias Nipkow <http://www21.in.tum.de/~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 <http://in.tum.de/~wimmers>, Johannes Hölzl <http://home.in.tum.de/~hoelzl>
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 <http://in.tum.de/~wimmers>
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 <http://www21.in.tum.de/~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.<br><br>An article about these proofs is found <a href="http://www21.in.tum.de/~nipkow/pubs/arrow.html">here</a>.
notify = nipkow@in.tum.de
[SenSocialChoice]
title = Some classical results in Social Choice Theory
author = Peter Gammie <http://peteg.org>
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 <http://www.cs.bham.ac.uk/~mmk>, Christoph Lange<mailto:math.semantic.web@gmail.com>, Colin Rowat<mailto:c.rowat@bham.ac.uk>
date = 2015-04-30
topic = Mathematics/Games and economics
abstract =
A VCG auction (named after their inventors Vickrey, Clarke, and
Groves) is a generalization of the single-good, second price Vickrey
auction to the case of a combinatorial auction (multiple goods, from
which any participant can bid on each possible combination). We
formalize in this entry VCG auctions, including tie-breaking and prove
that the functions for the allocation and the price determination are
well-defined. Furthermore we show that the allocation function
allocates goods only to participants, only goods in the auction are
allocated, and no good is allocated twice. We also show that the price
function is non-negative. These properties also hold for the
automatically extracted Scala code.
notify = mnfrd.krbr@gmail.com
[Topology]
title = Topology
author = Stefan Friedrich <>
date = 2004-04-26
topic = Mathematics/Topology
abstract = This entry contains two theories. The first, <tt>Topology</tt>, develops the basic notions of general topology. The second, which can be viewed as a demonstration of the first, is called <tt>LList_Topology</tt>. It develops the topology of lazy lists.
notify = lcp@cl.cam.ac.uk
[Knot_Theory]
title = Knot Theory
author = T.V.H. Prathamesh <mailto:prathamesh@imsc.res.in>
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 <http://www21.in.tum.de/~noschinl/>
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.
<p>
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 <http://www21.in.tum.de/~noschinl/>
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 <https://www.mpi-inf.mpg.de/~crizkall/>
date = 2011-07-21
topic = Mathematics/Graph theory
abstract =
<p>
A <em>matching</em> in a graph <i>G</i> is a subset <i>M</i> of the
edges of <i>G</i> 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 <em>odd-set cover</em> <i>OSC</i> of a graph <i>G</i> is a
labeling of the nodes of <i>G</i> with integers such that every edge of
<i>G</i> is either incident to a node labeled 1 or connects two nodes
labeled with the same number <i>i &ge; 2</i>.
</p><p>
This article proves Edmonds theorem:<br>
Let <i>M</i> be a matching in a graph <i>G</i> and let <i>OSC</i> be an
odd-set cover of <i>G</i>.
For any <i>i &ge; 0</i>, let <var>n(i)</var> be the number of nodes
labeled <i>i</i>. If <i>|M| = n(1) +
&sum;<sub>i &ge; 2</sub>(n(i) div 2)</i>,
then <i>M</i> is a maximum cardinality matching.
</p>
notify = nipkow@in.tum.de
[Girth_Chromatic]
title = A Probabilistic Proof of the Girth-Chromatic Number Theorem
author = Lars Noschinski <http://www21.in.tum.de/~noschinl/>
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 <mailto:hupel@in.tum.de>
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 <http://www21.in.tum.de/~nipkow>
date = 2006-05-22
topic = Mathematics/Graph theory
abstract =
These theories present the verified enumeration of <i>tame</i> plane graphs
as defined by Thomas C. Hales in his proof of the Kepler Conjecture in his
book <i>Dense Sphere Packings. A Blueprint for Formal Proofs.</i> [CUP 2012].
The values of the constants in the definition of tameness are identical to
those in the <a href="https://code.google.com/p/flyspeck/">Flyspeck project</a>.
The <a href="http://www21.in.tum.de/~nipkow/pubs/Flyspeck/">IJCAR 2006 paper by Nipkow, Bauer and Schultz</a> refers to the original version of Hales' proof,
the <a href="http://www21.in.tum.de/~nipkow/pubs/itp11.html">ITP 2011 paper by Nipkow</a> 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.<br>
[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 <mailto:c.sternagel@gmail.com>
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:
<ul>
<li>If the sets A and B are wqo then their Cartesian product is wqo.</li>
<li>If the set A is wqo then the set of finite lists over A is wqo.</li>
<li>If the set A is wqo then the set of finite trees over A is wqo.</li>
</ul>
The research was funded by the Austrian Science Fund (FWF): J3202.
extra-history =
Change history:
[2012-06-11]: Added Kruskal's Tree Theorem.<br>
[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.<br>
[2013-05-16]: Simplified construction of minimal bad sequences.<br>
[2014-07-09]: Simplified proofs of Higman's lemma and Kruskal's tree theorem,
based on homogeneous sequences.<br>
[2016-01-03]: An alternative proof of Higman's lemma by open induction.<br>
[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 <mailto:dongchenjiang@googlemail.com>, Tobias Nipkow <http://www21.in.tum.de/~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 <http://www.andrew.cmu.edu/user/avigad/>, Stefan Hetzl <http://www.logic.at/people/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, <i>Computability and Logic</i>, 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 <mailto:lukas.bulwahn@gmail.com>
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
``<a href="http://www.cs.ru.nl/~freek/100/">Top 100 Mathematical Theorems</a>''.
notify = lukas.bulwahn@gmail.com
[Euler_Partition]
title = Euler's Partition Theorem
author = Lukas Bulwahn <mailto:lukas.bulwahn@gmail.com>
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 <http://isabelle.in.tum.de/~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 <mailto:c.sternagel@gmail.com>
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, <i>Information Processing Letters</i> 29, 1988, pp.19-23.
<p>This research was supported by the Austrian Science Fund (FWF): J3202.</p>
notify = c.sternagel@gmail.com
[Category]
title = Category Theory to Yoneda's Lemma
author = Greg O'Keefe <http://users.rsise.anu.edu.au/~okeefe/>
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 <tt>equinumerous</tt> was slightly too weak in the original submission and has been fixed in revision <a href="https://foss.heptapod.net/isa-afp/afp-devel/-/commit/3498bb1e4c7ba468db8588eb7184c1849641f7d3">8c2b5b3c995f</a>.
notify = lcp@cl.cam.ac.uk
[Category2]
title = Category Theory
author = Alexander Katovsky <mailto:apk32@cam.ac.uk>
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 <a href="http://www.srcf.ucam.org/~apk32/Isabelle/Category/Cat.pdf">here [pdf]</a>.
notify = alexander.katovsky@cantab.net
[FunWithFunctions]
title = Fun With Functions
author = Tobias Nipkow <http://www21.in.tum.de/~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 <http://www21.in.tum.de/~nipkow>, Lawrence C. Paulson <http://www.cl.cam.ac.uk/~lp15/>
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 <a href="http://www.cl.cam.ac.uk/~lp15/">Larry Paulson</a>, 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. <p> 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 <mailto:wl302@cam.ac.uk>
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 <http://logic.las.tu-berlin.de/Members/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 <mailto:isabelle@christoph-d.de>
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 <mailto:ly271@cam.ac.uk>
contributors = Fabian Hellauer <mailto:hellauer@in.tum.de>, Fabian Immler <http://www21.in.tum.de/~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).<br>
[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 <http://www.andreas-lochbihler.de>
contributors = Peter Lammich <http://www21.in.tum.de/~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)<br>
[2014-03-31]:
added words of default size in the target language (by Peter Lammich)
(revision 25caf5065833)<br>
[2014-10-06]:
proper test setup with compilation and execution of tests in all target languages
(revision 5d7a1c9ae047)<br>
[2017-09-02]:
added 64-bit words (revision c89f86244e3c)<br>
[2018-07-15]:
added cast operators for default-size words (revision fc1f1fb8dd30)<br>
notify = mail@andreas-lochbihler.de
[XML]
title = XML
author = Christian Sternagel <mailto:c.sternagel@gmail.com>, René Thiemann <mailto:rene.thiemann@uibk.ac.at>
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 <http://www.cl.cam.ac.uk/~lp15/>
date = 2013-11-17
topic = Logic/Set theory
abstract = The theory of hereditarily finite sets is formalised, following
the <a href="http://journals.impan.gov.pl/dm/Inf/422-0-1.html">development</a> 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 <a href="Incompleteness.html">formalised separately</a>.
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 <http://www.cl.cam.ac.uk/~lp15/>
date = 2013-11-17
topic = Logic/Proof theory
abstract = Gödel's two incompleteness theorems are formalised, following a careful <a href="http://journals.impan.gov.pl/dm/Inf/422-0-1.html">presentation</a> by Swierczkowski, in the theory of <a href="HereditarilyFinite.html">hereditarily finite sets</a>. 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 <http://www.cl.cam.ac.uk/~lp15/>
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 <http://cl-informatik.uibk.ac.at/users/hzankl>
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 <mailto:bertram.felgenhauer@uibk.ac.at>
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 <http://page.mi.fu-berlin.de/cbenzmueller/>, Bruno Woltzenlogel Paleo <http://www.logic.at/staff/bruno/>
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 <mailto:davfuenmayor@gmail.com>, Christoph Benzmüller <http://www.christoph-benzmueller.de>
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 <mailto:davfuenmayor@gmail.com>, Christoph Benzmüller <http://christoph-benzmueller.de>
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)<br>
[Lowe_Ontological_Argument]
title = Computer-assisted Reconstruction and Assessment of E. J. Lowe's Modal Ontological Argument
author = David Fuenmayor <mailto:davfuenmayor@gmail.com>, Christoph Benzmüller <http://www.christoph-benzmueller.de>
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 <https://philpapers.org/profile/805>
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 <mailto:pasquale.noce.lavoro@gmail.com>
date = 2013-12-01
topic = Computer science/Functional programming
abstract =
<p>
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.
</p><p>
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.
</p>
notify = pasquale.noce.lavoro@gmail.com
[CryptoBasedCompositionalProperties]
title = Compositional Properties of Crypto-Based Components
author = Maria Spichkova <mailto:maria.spichkova@rmit.edu.au>
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 <mailto:brucker@spamfence.net>, Frédéric Tuong <mailto:tuong@users.gforge.inria.fr>, Burkhart Wolff <mailto:wolff@lri.fr>
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]:
<a href="https://foss.heptapod.net/isa-afp/afp-devel/-/commit/e68e1996d5d4926397c9244e786446e99ab17e63">afp-devel@ea3b38fc54d6</a> and
<a href="https://projects.brucker.ch/hol-testgen/log/trunk?rev=12148">hol-testgen@12148</a><br>
&nbsp;&nbsp;&nbsp;Update of Featherweight OCL including a change in the abstract.<br>
[2014-01-16]:
<a href="https://foss.heptapod.net/isa-afp/afp-devel/-/commit/6217cc5b29c560f24ecc64c81047778becb69f51">afp-devel@9091ce05cb20</a> and
<a href="https://projects.brucker.ch/hol-testgen/log/trunk?rev=10241">hol-testgen@10241</a><br>
&nbsp;&nbsp;&nbsp;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 <mailto:simon.foster@york.ac.uk>,
Georg Struth <http://staffwww.dcs.shef.ac.uk/people/G.Struth/>,
Tjark Weber <http://user.it.uu.se/~tjawe125/>
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 <mailto:brijesh.dongol@brunel.ac.uk>, Victor B. F. Gomes <mailto:victor.gomes@cl.cam.ac.uk>, Ian J. Hayes <mailto:ian.hayes@itee.uq.edu.au>, Georg Struth <mailto:g.struth@sheffield.ac.uk>
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 <mailto:psxjv4@nottingham.ac.uk>
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 <mailto:psxjv4@nottingham.ac.uk>
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 <http://nm.wu.ac.at/nm/sadelsbe>,
Stefan Hetzl <http://www.logic.at/people/hetzl/>,
Florian Pollak <mailto:florian.pollak@gmail.com>
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 <http://www21.in.tum.de/~popescua>, Johannes Hölzl <http://in.tum.de/~hoelzl>
+author = Andrei Popescu <https://www.andreipopescu.uk>, Johannes Hölzl <http://in.tum.de/~hoelzl>
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 <http://www.react.uni-saarland.de/people/rabe.html>, Peter Lammich <http://www21.in.tum.de/~lammich>, Andrei Popescu <http://www21.in.tum.de/~popescua>
+author = Markus N. Rabe <http://www.react.uni-saarland.de/people/rabe.html>, Peter Lammich <http://www21.in.tum.de/~lammich>, Andrei Popescu <https://www.andreipopescu.uk>
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 <http://www21.in.tum.de/~popescua>, Peter Lammich <http://www21.in.tum.de/~lammich>
+author = Andrei Popescu <https://www.andreipopescu.uk>, Peter Lammich <http://www21.in.tum.de/~lammich>
date = 2014-04-22
topic = Computer science/Security
abstract = This is a formalization of bounded-deducibility security (BD
security), a flexible notion of information-flow security applicable
to arbitrary input-output automata. It generalizes Sutherland's
classic notion of nondeducibility by factoring in declassification
bounds and trigger, whereas nondeducibility states that, in a
system, information cannot flow between specified sources and sinks,
BD security indicates upper bounds for the flow and triggers under
which these upper bounds are no longer guaranteed.
notify = uuomul@yahoo.com, lammich@in.tum.de
[Network_Security_Policy_Verification]
title = Network Security Policy Verification
author = Cornelius Diekmann <http://net.in.tum.de/~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.
<ul>
<li>Secure auto-completion of scenario-specific knowledge, which eases usability.</li>
<li>Security violations can be repaired by tightening the policy iff the
security invariants hold for the deny-all policy.</li>
<li>An algorithm to compute a security policy.</li>
<li>A formalization of stateful connection semantics in network security mechanisms.</li>
<li>An algorithm to compute a secure stateful implementation of a policy.</li>
<li>An executable implementation of all the theory.</li>
<li>Examples, ranging from an aircraft cabin data network to the analysis
of a large real-world firewall.</li>
<li>More examples: A fully automated translation of high-level security goals to both
firewall and SDN configurations (see Examples/Distributed_WebApp.thy).</li>
</ul>
For a detailed description, see
<ul>
<li>C. Diekmann, A. Korsten, and G. Carle.
<a href="http://www.net.in.tum.de/fileadmin/bibtex/publications/papers/diekmann2015mansdnnfv.pdf">Demonstrating
topoS: Theorem-prover-based synthesis of secure network configurations.</a>
In 2nd International Workshop on Management of SDN and NFV Systems, manSDN/NFV, Barcelona, Spain, November 2015.</li>
<li>C. Diekmann, S.-A. Posselt, H. Niedermayer, H. Kinkelin, O. Hanka, and G. Carle.
<a href="http://www.net.in.tum.de/pub/diekmann/forte14.pdf">Verifying Security Policies using Host Attributes.</a>
In FORTE, 34th IFIP International Conference on Formal Techniques for Distributed Objects,
Components and Systems, Berlin, Germany, June 2014.</li>
<li>C. Diekmann, L. Hupel, and G. Carle. Directed Security Policies:
<a href="http://rvg.web.cse.unsw.edu.au/eptcs/paper.cgi?ESSS2014.3">A Stateful Network Implementation.</a>
In J. Pang and Y. Liu, editors, Engineering Safety and Security Systems,
volume 150 of Electronic Proceedings in Theoretical Computer Science,
pages 20-34, Singapore, May 2014. Open Publishing Association.</li>
</ul>
extra-history =
Change history:
[2015-04-14]:
Added Distributed WebApp example and improved graphviz visualization
(revision 4dde08ca2ab8)<br>
notify = diekmann@net.in.tum.de
[Abstract_Completeness]
title = Abstract Completeness
-author = Jasmin Christian Blanchette <http://www21.in.tum.de/~blanchet>, Andrei Popescu <http://www21.in.tum.de/~popescua>, Dmitriy Traytel <http://www21.in.tum.de/~traytel>
+author = Jasmin Christian Blanchette <http://www21.in.tum.de/~blanchet>, Andrei Popescu <https://www.andreipopescu.uk>, Dmitriy Traytel <https://traytel.bitbucket.io>
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 <http://www.kestrel.edu/~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 <mailto:holdenl@princeton.edu>
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 <http://www.cl.cam.ac.uk/~lp15/>
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 <https://www21.in.tum.de/~eberlm>
date = 2015-07-14
topic = Mathematics/Analysis
abstract = This entry provides Landau symbols to describe and reason about the asymptotic growth of functions for sufficiently large inputs. A number of simplification procedures are provided for additional convenience: cancelling of dominated terms in sums under a Landau symbol, cancelling of common factors in products, and a decision procedure for Landau expressions containing products of powers of functions like x, ln(x), ln(ln(x)) etc.
notify = eberlm@in.tum.de
[Error_Function]
title = The Error Function
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Analysis
date = 2018-02-06
notify = eberlm@in.tum.de
abstract =
<p> 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. </p>
[Akra_Bazzi]
title = The Akra-Bazzi theorem and the Master theorem
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
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.
<p>
Some proof methods that facilitate applying the Master theorem are also
included. For a more detailed explanation of the formalisation and the
proof methods, see the accompanying paper (publication forthcoming).
notify = eberlm@in.tum.de
[Dirichlet_Series]
title = Dirichlet Series
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory
date = 2017-10-12
notify = eberlm@in.tum.de
abstract =
This entry is a formalisation of much of Chapters 2, 3, and 11 of
Apostol's &ldquo;Introduction to Analytic Number
Theory&rdquo;. This includes: <ul> <li>Definitions and
basic properties for several number-theoretic functions (Euler's
&phi;, M&ouml;bius &mu;, Liouville's &lambda;,
the divisor function &sigma;, von Mangoldt's
&Lambda;)</li> <li>Executable code for most of these
functions, the most efficient implementations using the factoring
algorithm by Thiemann <i>et al.</i></li>
<li>Dirichlet products and formal Dirichlet series</li>
<li>Analytic results connecting convergent formal Dirichlet
series to complex functions</li> <li>Euler product
expansions</li> <li>Asymptotic estimates of
number-theoretic functions including the density of squarefree
integers and the average number of divisors of a natural
number</li> </ul> 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 <https://people.epfl.ch/rodrigo.raya>, Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory
date = 2019-12-10
notify = manuel.eberl@tum.de
abstract =
<p>This article provides a full formalisation of Chapter 8 of
Apostol's <em><a
href="https://www.springer.com/de/book/9780387901633">Introduction
to Analytic Number Theory</a></em>. Subjects that are
covered are:</p> <ul> <li>periodic arithmetic
functions and their finite Fourier series</li>
<li>(generalised) Ramanujan sums</li> <li>Gauss sums
and separable characters</li> <li>induced moduli and
primitive characters</li> <li>the
Pólya&mdash;Vinogradov inequality</li> </ul>
[Zeta_Function]
title = The Hurwitz and Riemann ζ Functions
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory, Mathematics/Analysis
date = 2017-10-12
notify = eberlm@in.tum.de
abstract =
<p>This entry builds upon the results about formal and analytic Dirichlet
series to define the Hurwitz &zeta; function &zeta;(<em>a</em>,<em>s</em>) and,
based on that, the Riemann &zeta; function &zeta;(<em>s</em>).
This is done by first defining them for &real;(<em>z</em>) > 1
and then successively extending the domain to the left using the
Euler&ndash;MacLaurin formula.</p>
<p>Apart from the most basic facts such as analyticity, the following
results are provided:</p>
<ul>
<li>the Stieltjes constants and the Laurent expansion of
&zeta;(<em>s</em>) at <em>s</em> = 1</li>
<li>the non-vanishing of &zeta;(<em>s</em>)
for &real;(<em>z</em>) &ge; 1</li>
<li>the relationship between &zeta;(<em>a</em>,<em>s</em>) and &Gamma;</li>
<li>the special values at negative integers and positive even integers</li>
<li>Hurwitz's formula and the reflection formula for &zeta;(<em>s</em>)</li>
<li>the <a href="https://arxiv.org/abs/math/0405478">
Hadjicostas&ndash;Chapman formula</a></li>
</ul>
<p>The entry also contains Euler's analytic proof of the infinitude of primes,
based on the fact that &zeta;(<i>s</i>) has a pole at <i>s</i> = 1.</p>
[Linear_Recurrences]
title = Linear Recurrences
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Analysis
date = 2017-10-12
notify = eberlm@in.tum.de
abstract =
<p> 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 <i>f</i>(<i>n</i>) =
<i>f</i>(<i>n</i>-1) +
<i>f</i>(<i>n</i> - 2) and the quite
non-obvious closed form
(<i>&phi;</i><sup><i>n</i></sup>
-
(-<i>&phi;</i>)<sup>-<i>n</i></sup>)
/ &radic;<span style="text-decoration:
overline">5</span> where &phi; is the golden ratio.
</p> <p> In this work, I build on existing tools in
Isabelle &ndash; such as formal power series and polynomial
factorisation algorithms &ndash; to develop a theory of these
recurrences and derive a fully executable solver for them that can be
exported to programming languages like Haskell. </p>
[Lambert_W]
title = The Lambert W Function on the Reals
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Analysis
date = 2020-04-24
notify = eberlm@in.tum.de
abstract =
<p>The Lambert <em>W</em> function is a multi-valued
function defined as the inverse function of <em>x</em>
&#x21A6; <em>x</em>
e<sup><em>x</em></sup>. Besides numerous
applications in combinatorics, physics, and engineering, it also
frequently occurs when solving equations containing both
e<sup><em>x</em></sup> and
<em>x</em>, or both <em>x</em> and log
<em>x</em>.</p> <p>This article provides a
definition of the two real-valued branches
<em>W</em><sub>0</sub>(<em>x</em>)
and
<em>W</em><sub>-1</sub>(<em>x</em>)
and proves various properties such as basic identities and
inequalities, monotonicity, differentiability, asymptotic expansions,
and the MacLaurin series of
<em>W</em><sub>0</sub>(<em>x</em>)
at <em>x</em> = 0.</p>
[Cartan_FP]
title = The Cartan Fixed Point Theorems
author = Lawrence C. Paulson <http://www.cl.cam.ac.uk/~lp15/>
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 C<sup>n</sup>. 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 <http://www.unirioja.es/cu/jodivaso>, Jesús Aransay <http://www.unirioja.es/cu/jearansa>
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 <http://www.unirioja.es/cu/jodivaso>, Jesús Aransay <http://www.unirioja.es/cu/jearansa>
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 <http://www.unirioja.es/cu/jodivaso>, Jesús Aransay <http://www.unirioja.es/cu/jearansa>
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 <http://www.unirioja.es/cu/jodivaso>, Jesús Aransay <http://www.unirioja.es/cu/jearansa>
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 <mailto:c.sternagel@gmail.com>
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 <http://www.andreas-lochbihler.de>, Alexandra Maximova <mailto:amaximov@student.ethz.ch>
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 <a href="http://isa-afp.org/entries/Stream-Fusion.html">AFP entry</a> 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 <http://www21.in.tum.de/~noschinl/>
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 <tt>casify</tt>, 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 <tt>casify</tt>.
<p>
As examples, this work contains verification condition generators
producing named cases for three languages: The Hoare language from
<tt>HOL/Library</tt>, 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 <tt>DPT_SAT_Solver</tt>, 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 <http://ualberta.ca/~jsylvest/>
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 <mailto:pasquale.noce.lavoro@gmail.com>
date = 2015-08-18
abstract =
<p>
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.
</p><p>
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.
</p>
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 <mailto:pasquale.noce.lavoro@gmail.com>
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 <mailto:rene.thiemann@uibk.ac.at>, Akihisa Yamada <mailto:akihisa.yamada@uibk.ac.at>
contributors = Alexander Bentkamp <mailto:bentkamp@gmail.com>
date = 2015-08-21
abstract =
<p>
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.
</p><p>
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.
</p><p>
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.
</p><p>
All the results have been applied to improve CeTA, our certifier to validate termination and complexity proof certificates.
</p>
extra-history =
Change history:
[2016-01-07]: Added Schur-decomposition, Gram-Schmidt orthogonalization, uniqueness of Jordan normal forms<br/>
[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 <mailto:sickert@in.tum.de>
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.<br>
[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 <http://in.tum.de/~wimmers>
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 <http://logic.las.tu-berlin.de/Members/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 <mailto:sebastien.gouezel@univ-rennes1.fr>
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 <mailto:bentkamp@gmail.com>
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 <mailto:bentkamp@gmail.com>
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 <mailto:frank-balbach@gmx.de>
topic = Logic/Computability, Computer science/Machine learning
date = 2020-08-31
notify = frank-balbach@gmx.de
abstract =
<p> This entry formalizes some classical concepts and results
from inductive inference of recursive functions. In the basic setting
a partial recursive function ("strategy") must identify
("learn") all functions from a set ("class") of
recursive functions. To that end the strategy receives more and more
values $f(0), f(1), f(2), \ldots$ of some function $f$ from the given
class and in turn outputs descriptions of partial recursive functions,
for example, Gödel numbers. The strategy is considered successful if
the sequence of outputs ("hypotheses") converges to a
description of $f$. A class of functions learnable in this sense is
called "learnable in the limit". The set of all these
classes is denoted by LIM. </p> <p> Other types of
inference considered are finite learning (FIN), behaviorally correct
learning in the limit (BC), and some variants of LIM with restrictions
on the hypotheses: total learning (TOTAL), consistent learning (CONS),
and class-preserving learning (CP). The main results formalized are
the proper inclusions $\mathrm{FIN} \subset \mathrm{CP} \subset
\mathrm{TOTAL} \subset \mathrm{CONS} \subset \mathrm{LIM} \subset
\mathrm{BC} \subset 2^{\mathcal{R}}$, where $\mathcal{R}$ is the set
of all total recursive functions. Further results show that for all
these inference types except CONS, strategies can be assumed to be
total recursive functions; that all inference types but CP are closed
under the subset relation between classes; and that no inference type
is closed under the union of classes. </p> <p> The above
is based on a formalization of recursive functions heavily inspired by
the <a
href="https://www.isa-afp.org/entries/Universal_Turing_Machine.html">Universal
Turing Machine</a> entry by Xu et al., but different in that it
models partial functions with codomain <em>nat
option</em>. The formalization contains a construction of a
universal partial recursive function, without resorting to Turing
machines, introduces decidability and recursive enumerability, and
proves some standard results: existence of a Kleene normal form, the
<em>s-m-n</em> theorem, Rice's theorem, and assorted
fixed-point theorems (recursion theorems) by Kleene, Rogers, and
Smullyan. </p>
[Applicative_Lifting]
title = Applicative Lifting
author = Andreas Lochbihler <http://www.andreas-lochbihler.de>, 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.
</p><p>
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.
</p><p>
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.
</p><p>
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.
</p>
extra-history =
Change history:
[2016-03-03]: added formalisation of lifting with combinators<br>
[2016-06-10]:
implemented automatic derivation of lifted combinator reductions;
support arbitrary lifted relations using relators;
improved compatibility with locale interpretation
(revision ec336f354f37)<br>
notify = mail@andreas-lochbihler.de
[Stern_Brocot]
title = The Stern-Brocot Tree
author = Peter Gammie <http://peteg.org>, Andreas Lochbihler <http://www.andreas-lochbihler.de>
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.
</p><p>
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.
</p>
notify = mail@andreas-lochbihler.de
[Algebraic_Numbers]
title = Algebraic Numbers in Isabelle/HOL
topic = Mathematics/Algebra
author = René Thiemann <mailto:rene.thiemann@uibk.ac.at>, Akihisa Yamada <mailto:akihisa.yamada@uibk.ac.at>, Sebastiaan Joosten <mailto:sebastiaan.joosten@uibk.ac.at>
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.
</p><p>
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.
</p>
extra-history =
Change history:
[2016-01-29]: Split off Polynomial Interpolation and Polynomial Factorization<br>
[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 <mailto:rene.thiemann@uibk.ac.at>, Akihisa Yamada <mailto:akihisa.yamada@uibk.ac.at>
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 <i>p</i> such that
<i>p(0) = 0</i> and <i>p(2) = 1</i>. 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.
<p>
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 <mailto:rene.thiemann@uibk.ac.at>, Akihisa Yamada <mailto:akihisa.yamada@uibk.ac.at>
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.
<p>
As side products, we developed division algorithms for polynomials over integral domains,
as well as primality-testing and prime-factorization algorithms for integers.
notify = rene.thiemann@uibk.ac.at, ayamada@trs.cm.is.nagoya-u.ac.jp
[Perron_Frobenius]
title = Perron-Frobenius Theorem for Spectral Radius Analysis
author = Jose Divasón <http://www.unirioja.es/cu/jodivaso>, Ondřej Kunčar <http://www21.in.tum.de/~kuncar/>, René Thiemann <mailto:rene.thiemann@uibk.ac.at>, Akihisa Yamada <mailto:akihisa.yamada@uibk.ac.at>
notify = rene.thiemann@uibk.ac.at
date = 2016-05-20
topic = Mathematics/Algebra
abstract =
<p>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 A<sup>n</sup> 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
<em>complex</em> eigenvalues. In case A contains only non-negative
real values, a simplification is possible with the help of the
Perron&ndash;Frobenius theorem, which tells us that it suffices to consider only
the <em>real</em> eigenvalues of A, i.e., applying Sturm's method can
decide the polynomial growth of A<sup>n</sup>. </p><p> We formalize
the Perron&ndash;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 A<sup>n</sup> is polynomially bounded in n. </p>
extra-history =
Change history:
[2017-10-18]:
added Perron-Frobenius theorem for irreducible matrices with generalization
(revision bda1f1ce8a1c)<br/>
[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 <http://cl-informatik.uibk.ac.at/~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&ndash;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&ndash;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 <mailto:sebasti@nullri.ch>, Denis Lohner <http://pp.ipd.kit.edu/person.php?id=88>
date = 2016-02-05
topic = Computer science/Algorithms, Computer science/Programming languages/Transformations
abstract =
<p>
We define a functional variant of the static single assignment (SSA)
form construction algorithm described by <a
href="https://doi.org/10.1007/978-3-642-37051-9_6">Braun et al.</a>,
which combines simplicity and efficiency. The definition is based on a
general, abstract control flow graph representation using Isabelle locales.
</p>
<p>
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.
</p>
<p>
Furthermore, we use a generic instantiation based on typedefs in order
to extract OCaml code and replace the unverified SSA construction
algorithm of the <a href="https://doi.org/10.1145/2579080">CompCertSSA
project</a> with it.
</p>
<p>
A more detailed description of the verified SSA construction can be found
in the paper <a href="https://doi.org/10.1145/2892208.2892211">Verified
Construction of Static Single Assignment Form</a>, CC 2016.
</p>
notify = denis.lohner@kit.edu
[Minimal_SSA]
title = Minimal Static Single Assignment Form
author = Max Wagner <mailto:max@trollbu.de>, Denis Lohner <http://pp.ipd.kit.edu/person.php?id=88>
topic = Computer science/Programming languages/Transformations
date = 2017-01-17
notify = denis.lohner@kit.edu
abstract =
<p>This formalization is an extension to <a
href="https://www.isa-afp.org/entries/Formal_SSA.html">"Verified
Construction of Static Single Assignment Form"</a>. In
their work, the authors have shown that <a
href="https://doi.org/10.1007/978-3-642-37051-9_6">Braun
et al.'s static single assignment (SSA) construction
algorithm</a> 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.<br> In this
formalization we support that claim by giving a mechanized proof.
</p>
<p>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 <a href="https://doi.org/10.1145/115372.115320">Cytron et
al.</a>.</p>
[PropResPI]
title = Propositional Resolution and Prime Implicates Generation
author = Nicolas Peltier <http://membres-lig.imag.fr/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 <http://membres-lig.imag.fr/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 <http://www.inf.kcl.ac.uk/staff/urbanc/>, Stefan Berghofer <http://www.in.tum.de/~berghofe>, Cezary Kaliszyk <http://cl-informatik.uibk.ac.at/users/cek/>
date = 2013-02-21
topic = Tools
abstract =
<p>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.
</p><p>
This entry can be used as a more advanced replacement for
HOL/Nominal in the Isabelle distribution.
</p>
notify = christian.urban@kcl.ac.uk
[First_Welfare_Theorem]
title = Microeconomics and the First Welfare Theorem
author = Julian Parsert <mailto:julian.parsert@gmail.com>, Cezary Kaliszyk<http://cl-informatik.uibk.ac.at/users/cek/>
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
<i>First Theorem of Welfare Economics</i> holds within
both. The theorem is the mathematical formulation of Adam Smith's
famous <i>invisible hand</i> 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.
<br>
[Noninterference_Sequential_Composition]
title = Conservation of CSP Noninterference Security under Sequential Composition
author = Pasquale Noce <mailto:pasquale.noce.lavoro@gmail.com>
date = 2016-04-26
topic = Computer science/Security, Computer science/Concurrency/Process calculi
abstract =
<p>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.</p>
<p>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.</p>
notify = pasquale.noce.lavoro@gmail.com
[Noninterference_Concurrent_Composition]
title = Conservation of CSP Noninterference Security under Concurrent Composition
author = Pasquale Noce <mailto:pasquale.noce.lavoro@gmail.com>
notify = pasquale.noce.lavoro@gmail.com
date = 2016-06-13
topic = Computer science/Security, Computer science/Concurrency/Process calculi
abstract =
<p>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.</p>
<p>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.</p>
[ROBDD]
title = Algorithms for Reduced Ordered Binary Decision Diagrams
author = Julius Michaelis <http://liftm.de>, Maximilian Haslbeck <http://cl-informatik.uibk.ac.at/users/mhaslbeck//>, Peter Lammich <http://www21.in.tum.de/~lammich>, Lars Hupel <https://www21.in.tum.de/~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 <mailto:m.stannett@sheffield.ac.uk>, István Németi <http://www.renyi.hu/~nemeti/>
date = 2016-04-28
topic = Mathematics/Physics
abstract =
We provide a formal proof within First Order Relativity Theory that no
observer can travel faster than the speed of light. Originally
reported in Stannett & Németi (2014) "Using Isabelle/HOL to verify
first-order relativity theory", Journal of Automated Reasoning 52(4),
pp. 361-378.
notify = m.stannett@sheffield.ac.uk
[Groebner_Bases]
title = Gröbner Bases Theory
author = Fabian Immler <http://www21.in.tum.de/~immler>, Alexander Maletzky <https://risc.jku.at/m/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.<br>
notify = alexander.maletzky@risc.jku.at
[Nullstellensatz]
title = Hilbert's Nullstellensatz
author = Alexander Maletzky <https://risc.jku.at/m/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 <a
href="https://link.springer.com/book/10.1007/978-0-387-35651-8">Ideals,
Varieties, and Algorithms</a> by Cox, Little and O'Shea.
[Bell_Numbers_Spivey]
title = Spivey's Generalized Recurrence for Bell Numbers
author = Lukas Bulwahn <mailto:lukas.bulwahn@gmail.com>
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.
<p>
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 <mailto:eberlm@in.tum.de>
date = 2016-05-05
topic = Mathematics/Games and economics
abstract =
This work contains a formalisation of basic Randomised Social Choice,
including Stochastic Dominance and Social Decision Schemes (SDSs)
along with some of their most important properties (Anonymity,
Neutrality, ex-post- and SD-Efficiency, SD-Strategy-Proofness) and two
particular SDSs – Random Dictatorship and Random Serial Dictatorship
(with proofs of the properties that they satisfy). Many important
properties of these concepts are also proven – such as the two
equivalent characterisations of Stochastic Dominance and the fact that
SD-efficiency of a lottery only depends on the support. The entry
also provides convenient commands to define Preference Profiles, prove
their well-formedness, and automatically derive restrictions that
sufficiently nice SDSs need to satisfy on the defined profiles.
Currently, the formalisation focuses on weak preferences and
Stochastic Dominance, but it should be easy to extend it to other
domains – such as strict preferences – or other lottery extensions –
such as Bilinear Dominance or Pairwise Comparison.
notify = eberlm@in.tum.de
[SDS_Impossibility]
title = The Incompatibility of SD-Efficiency and SD-Strategy-Proofness
author = Manuel Eberl <mailto:eberlm@in.tum.de>
date = 2016-05-04
topic = Mathematics/Games and economics
abstract =
This formalisation contains the proof that there is no anonymous and
neutral Social Decision Scheme for at least four voters and
alternatives that fulfils both SD-Efficiency and SD-Strategy-
Proofness. The proof is a fully structured and quasi-human-redable
one. It was derived from the (unstructured) SMT proof of the case for
exactly four voters and alternatives by Brandl et al. Their proof
relies on an unverified translation of the original problem to SMT,
and the proof that lifts the argument for exactly four voters and
alternatives to the general case is also not machine-checked. In this
Isabelle proof, on the other hand, all of these steps are fully
proven and machine-checked. This is particularly important seeing as a
previously published informal proof of a weaker statement contained a
mistake in precisely this lifting step.
notify = eberlm@in.tum.de
[Median_Of_Medians_Selection]
title = The Median-of-Medians Selection Algorithm
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Computer science/Algorithms
date = 2017-12-21
notify = eberlm@in.tum.de
abstract =
<p>This entry provides an executable functional implementation
of the Median-of-Medians algorithm for selecting the
<em>k</em>-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. </p>
[Mason_Stothers]
title = The Mason–Stothers Theorem
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Algebra
date = 2017-12-21
notify = eberlm@in.tum.de
abstract =
<p>This article provides a formalisation of Snyder’s simple and
elegant proof of the Mason&ndash;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.</p> <p>In short, the statement of the
theorem is that three non-zero coprime polynomials
<em>A</em>, <em>B</em>, <em>C</em>
over a field which sum to 0 and do not all have vanishing derivatives
fulfil max{deg(<em>A</em>), deg(<em>B</em>),
deg(<em>C</em>)} < deg(rad(<em>ABC</em>))
where the rad(<em>P</em>) denotes the
<em>radical</em> of <em>P</em>,
i.&thinsp;e. the product of all unique irreducible factors of
<em>P</em>.</p> <p>This theorem also implies a
kind of polynomial analogue of Fermat’s Last Theorem for polynomials:
except for trivial cases,
<em>A<sup>n</sup></em> +
<em>B<sup>n</sup></em> +
<em>C<sup>n</sup></em> = 0 implies
n&nbsp;&le;&nbsp;2 for coprime polynomials
<em>A</em>, <em>B</em>, <em>C</em>
over a field.</em></p>
[FLP]
title = A Constructive Proof for FLP
author = Benjamin Bisping <mailto:benjamin.bisping@campus.tu-berlin.de>, Paul-David Brodmann <mailto:p.brodmann@tu-berlin.de>, Tim Jungnickel <mailto:tim.jungnickel@tu-berlin.de>, Christina Rickmann <mailto:c.rickmann@tu-berlin.de>, Henning Seidler <mailto:henning.seidler@mailbox.tu-berlin.de>, Anke Stüber <mailto:anke.stueber@campus.tu-berlin.de>, Arno Wilhelm-Weidner <mailto:arno.wilhelm-weidner@tu-berlin.de>, Kirstin Peters <mailto:kirstin.peters@tu-berlin.de>, Uwe Nestmann <https://www.mtv.tu-berlin.de/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 <mailto:tim.jungnickel@tu-berlin.de>, 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 <http://pp.ipd.kit.edu/~breitner>, Denis Lohner <http://pp.ipd.kit.edu/person.php?id=88>
date = 2016-05-20
topic = Logic/Proof theory
abstract =
The <a href="http://incredible.pm">Incredible Proof Machine</a> 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 <http://www.cse.unsw.edu.au/~kleing/>, 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 <https://www21.in.tum.de/~eberlm>
notify = eberlm@in.tum.de
date = 2016-06-21
topic = Mathematics/Combinatorics
abstract =
<p>In this work, we define the Catalan numbers <em>C<sub>n</sub></em>
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 <em>n</em>), prove the asymptotic growth
approximation <em>C<sub>n</sub> &sim; 4<sup>n</sup> / (&radic;<span
style="text-decoration: overline">&pi;</span> &middot;
n<sup>1.5</sup>)</em>, and provide reasonably efficient executable
code to compute them.</p> <p>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.</p>
[Fisher_Yates]
title = Fisher–Yates shuffle
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
notify = eberlm@in.tum.de
date = 2016-09-30
topic = Computer science/Algorithms
abstract =
<p>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.</p>
[Bertrands_Postulate]
title = Bertrand's postulate
author = Julian Biendarra<>, Manuel Eberl <https://www21.in.tum.de/~eberlm>
contributors = Lawrence C. Paulson <http://www.cl.cam.ac.uk/~lp15/>
topic = Mathematics/Number theory
date = 2017-01-17
notify = eberlm@in.tum.de
abstract =
<p>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. </p>
[Rewriting_Z]
title = The Z Property
author = Bertram Felgenhauer<>, Julian Nagele<>, Vincent van Oostrom<>, Christian Sternagel <mailto:c.sternagel@gmail.com>
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 <https://people.compute.dtu.dk/andschl/>
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]. <p>
<a name="Sch18"></a>[Sch18] Anders Schlichtkrull. "Formalization of the
Resolution Calculus for First-Order Logic". Journal of Automated
Reasoning, 2018.<br> <a name="Sch16"></a>[Sch16] Anders
Schlichtkrull. "Formalization of the Resolution Calculus for First-Order
Logic". In: ITP 2016. Vol. 9807. LNCS. Springer, 2016.<br>
<a name="Sch15"></a>[Sch15] Anders Schlichtkrull. <a href="https://people.compute.dtu.dk/andschl/Thesis.pdf">
"Formalization of Resolution Calculus in Isabelle"</a>.
<a href="https://people.compute.dtu.dk/andschl/Thesis.pdf">https://people.compute.dtu.dk/andschl/Thesis.pdf</a>.
MSc thesis. Technical University of Denmark, 2015.<br>
<a name="BA12"></a>[BA12] Mordechai Ben-Ari. <i>Mathematical Logic for
Computer Science</i>. 3rd. Springer, 2012.<br> <a
name="CL73"></a>[CL73] Chin-Liang Chang and Richard Char-Tung Lee.
<i>Symbolic Logic and Mechanical Theorem Proving</i>. 1st. Academic
Press, Inc., 1973.<br> <a name="Lei97"></a>[Lei97] Alexander
Leitsch. <i>The Resolution Calculus</i>. Texts in theoretical computer
science. Springer, 1997.<br> <a name="IsaFoL"></a>[IsaFoL]
IsaFoL authors. <a href="https://bitbucket.org/jasmin_blanchette/isafol">
IsaFoL: Isabelle Formalization of Logic</a>.
<a href="https://bitbucket.org/jasmin_blanchette/isafol">https://bitbucket.org/jasmin_blanchette/isafol</a>.
extra-history =
Change history:
[2018-01-24]: added several new versions of the soundness and completeness theorems as described in the paper [Sch18]. <br>
[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 <http://pp.ipd.kit.edu/~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 <mailto:lukas.bulwahn@gmail.com>
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 <mailto:lukas.bulwahn@gmail.com>
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 <mailto:wolff@lri.fr>
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 <https://www21.in.tum.de/~eberlm>
notify = eberlm@in.tum.de
date = 2016-09-01
topic = Mathematics/Analysis
abstract =
<p>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 <a
href="http://www.maths.lancs.ac.uk/~jameson/stirlgamma.pdf">Graham Jameson</a>.</p>
<p>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 &Gamma; is also extended to complex arguments.</p>
[Lp]
title = Lp spaces
author = Sebastien Gouezel <http://www.math.sciences.univ-nantes.fr/~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 <http://www.unirioja.es/cu/jodivaso>, Sebastiaan Joosten <mailto:sebastiaan.joosten@uibk.ac.at>, René Thiemann <mailto:rene.thiemann@uibk.ac.at>, Akihisa Yamada <mailto:akihisa.yamada@uibk.ac.at>
notify = rene.thiemann@uibk.ac.at
date = 2016-10-14
topic = Mathematics/Algebra
abstract =
<p>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.
</p>
<p>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.
</p>
<p>Through experiments we verify that our algorithm factors polynomials of degree
100 within seconds.
</p>
[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 <mailto:qh225@cl.cam.ac.uk>, Lawrence C. Paulson <mailto:lp15@cam.ac.uk>
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 <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Probability theory, Mathematics/Geometry
date = 2017-06-06
notify = eberlm@in.tum.de
abstract =
In the 18th century, Georges-Louis Leclerc, Comte de Buffon posed and
later solved the following problem, which is often called the first
problem ever solved in geometric probability: Given a floor divided
into vertical strips of the same width, what is the probability that a
needle thrown onto the floor randomly will cross two strips? This
entry formally defines the problem in the case where the needle's
position is chosen uniformly at random in a single strip around the
origin (which is equivalent to larger arrangements due to symmetry).
It then provides proofs of the simple solution in the case where the
needle's length is no greater than the width of the strips and
the more complicated solution in the opposite case.
[SPARCv8]
title = A formal model for the SPARCv8 ISA and a proof of non-interference for the LEON3 processor
author = Zhe Hou <mailto:zhe.hou@ntu.edu.sg>, David Sanan <mailto:sanan@ntu.edu.sg>, Alwen Tiu <mailto:ATiu@ntu.edu.sg>, Yang Liu <mailto:yangliu@ntu.edu.sg>
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 <mailto:zhe.hou@ntu.edu.sg>, David Sanan <mailto:sanan@ntu.edu.sg>, Alwen Tiu <mailto:ATiu@ntu.edu.sg>, Rajeev Gore <mailto:rajeev.gore@anu.edu.au>, Ranald Clouston <mailto:ranald.clouston@cs.au.dk>
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 <http://liftm.de>, Cornelius Diekmann <http://net.in.tum.de/~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 <http://peteg.org>
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 <mailto:tjark.weber@it.uu.se>, Lars-Henrik Eriksson <mailto:lhe@it.uu.se>, Joachim Parrow <mailto:joachim.parrow@it.uu.se>, Johannes Borgström <mailto:johannes.borgstrom@it.uu.se>, Ramunas Gutkovas <mailto:ramunas.gutkovas@it.uu.se>
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 <http://www21.in.tum.de/~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 <a href="https://doi.org/10.1007/978-3-642-32347-8_9">ITP 2012 paper</a>.
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
<a href="https://doi.org/10.1007/978-3-319-10542-0">Concrete Semantics</a>.
[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 <https://people.compute.dtu.dk/andschl/>, Jørgen Villadsen <https://people.compute.dtu.dk/jovi/>
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 <mailto:julian.fell@uq.net.au>, Ian J. Hayes <mailto:ian.hayes@itee.uq.edu.au>, Andrius Velykis <http://andrius.velykis.lt>
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 <i>c</i> and
<i>i</i> is the process that, if executed in parallel with
<i>i</i> implements <i>c</i>. 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 <https://people.compute.dtu.dk/aleje/>, Anders Schlichtkrull <https://people.compute.dtu.dk/andschl/>, Jørgen Villadsen <https://people.compute.dtu.dk/jovi/>
topic = Logic/General logic/Mechanization of proofs
date = 2017-01-01
notify = aleje@dtu.dk, andschl@dtu.dk, jovi@dtu.dk
abstract =
<p>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.</p>
<p>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. <a href="https://content.iospress.com/articles/ai-communications/aic764">
https://content.iospress.com/articles/ai-communications/aic764</a></p>
<p>See also: Students' Proof Assistant (SPA).
<a href=https://github.com/logic-tools/spa>
https://github.com/logic-tools/spa</a></p>
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<mailto:lukas.bulwahn@gmail.com>, Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Analysis, Mathematics/Number theory
date = 2017-01-24
notify = eberlm@in.tum.de
abstract =
<p>Bernoulli numbers were first discovered in the closed-form
expansion of the sum 1<sup>m</sup> +
2<sup>m</sup> + &hellip; + n<sup>m</sup>
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.</p>
<p>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.</p>
<p>We also prove the correctness of the
Akiyama&ndash;Tanigawa algorithm for computing Bernoulli numbers
with reasonable efficiency, and we define the periodic Bernoulli
polynomials (which appear e.g. in the Euler&ndash;MacLaurin
summation formula and the expansion of the log-Gamma function) and
prove their basic properties.</p>
[Stone_Relation_Algebras]
title = Stone Relation Algebras
author = Walter Guttmann <http://www.cosc.canterbury.ac.nz/walter.guttmann/>
topic = Mathematics/Algebra
date = 2017-02-07
notify = walter.guttmann@canterbury.ac.nz
abstract =
We develop Stone relation algebras, which generalise relation algebras
by replacing the underlying Boolean algebra structure with a Stone
algebra. We show that finite matrices over extended real numbers form
an instance. As a consequence, relation-algebraic concepts and methods
can be used for reasoning about weighted graphs. We also develop a
fixpoint calculus and apply it to compare different definitions of
reflexive-transitive closures in semirings.
[Stone_Kleene_Relation_Algebras]
title = Stone-Kleene Relation Algebras
author = Walter Guttmann <http://www.cosc.canterbury.ac.nz/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 <mailto:jasmin.blanchette@gmail.com>, Andrei Popescu <mailto:uuomul@yahoo.com>, Dmitriy Traytel <mailto:traytel@inf.ethz.ch>
+author = Jasmin Christian Blanchette <mailto:jasmin.blanchette@gmail.com>, Andrei Popescu <https://www.andreipopescu.uk>, Dmitriy Traytel <https://traytel.bitbucket.io>
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 <em>Journal of Automated
Reasoning</em>. The abstract proof can be instantiated for
various formalisms, including first-order logic with inductive
predicates.
[Differential_Dynamic_Logic]
title = Differential Dynamic Logic
author = Brandon Bohrer <mailto:bbohrer@cs.cmu.edu>
topic = Logic/General logic/Modal logic, Computer science/Programming languages/Logics
date = 2017-02-13
notify = bbohrer@cs.cmu.edu
abstract =
We formalize differential dynamic logic, a logic for proving
properties of hybrid systems. The proof calculus in this formalization
is based on the uniform substitution principle. We show it is sound
with respect to our denotational semantics, which provides increased
confidence in the correctness of the KeYmaera X theorem prover based
on this calculus. As an application, we include a proof term checker
embedded in Isabelle/HOL with several example proofs. Published in:
Brandon Bohrer, Vincent Rahli, Ivana Vukotic, Marcus Völp, André
Platzer: Formally verified differential dynamic logic. CPP 2017.
[Syntax_Independent_Logic]
title = Syntax-Independent Logic Infrastructure
author = Andrei Popescu <https://www.andreipopescu.uk>, Dmitriy Traytel <https://traytel.bitbucket.io>
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 <a
href="https://www.isa-afp.org/entries/Robinson_Arithmetic.html">Robinson_Arithmetic</a>
and to hereditarily finite set theory in the AFP entries <a
href="https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html">Goedel_HFSet_Semantic</a>
and <a
href="https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html">Goedel_HFSet_Semanticless</a>,
which are part of our formalization of G&ouml;del's
Incompleteness Theorems described in our CADE-27 paper <a
href="https://dx.doi.org/10.1007/978-3-030-29436-6_26">A
Formally Verified Abstract Account of Gödel's Incompleteness
Theorems</a>.
[Goedel_Incompleteness]
title = An Abstract Formalization of G&ouml;del's Incompleteness Theorems
author = Andrei Popescu <https://www.andreipopescu.uk>, Dmitriy Traytel <https://traytel.bitbucket.io>
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&ouml;del's
incompleteness theorems. We analyze sufficient conditions for the
theorems' applicability to a partially specified logic. Our
abstract perspective enables a comparison between alternative
approaches from the literature. These include Rosser's variation
of the first theorem, Jeroslow's variation of the second theorem,
and the Swierczkowski&ndash;Paulson semantics-based approach. This
AFP entry is the main entry point to the results described in our
CADE-27 paper <a
href="https://dx.doi.org/10.1007/978-3-030-29436-6_26">A
Formally Verified Abstract Account of Gödel's Incompleteness
Theorems</a>. As part of our abstract formalization's
validation, we instantiate our locales twice in the separate AFP
entries <a
href="https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html">Goedel_HFSet_Semantic</a>
and <a
href="https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html">Goedel_HFSet_Semanticless</a>.
[Goedel_HFSet_Semantic]
title = From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part I
author = Andrei Popescu <https://www.andreipopescu.uk>, Dmitriy Traytel <https://traytel.bitbucket.io>
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&ouml;del's First and
Second Incompleteness Theorems from a <a
href="https://www.isa-afp.org/entries/Goedel_Incompleteness.html">separate
AFP entry</a> by instantiating them to the case of
<i>finite sound extensions of the Hereditarily Finite (HF) Set
theory</i>, i.e., FOL theories extending the HF Set theory with
a finite set of axioms that are sound in the standard model. The
concrete results had been previously formalised in an <a
href="https://www.isa-afp.org/entries/Incompleteness.html">AFP
entry by Larry Paulson</a>; our instantiation reuses the
infrastructure developed in that entry.
[Goedel_HFSet_Semanticless]
title = From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part II
author = Andrei Popescu <https://www.andreipopescu.uk>, Dmitriy Traytel <https://traytel.bitbucket.io>
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&ouml;del's Second
Incompleteness Theorem from a <a
href="https://www.isa-afp.org/entries/Goedel_Incompleteness.html">separate
AFP entry</a> by instantiating it to the case of <i>finite
consistent extensions of the Hereditarily Finite (HF) Set
theory</i>, i.e., consistent FOL theories extending the HF Set
theory with a finite set of axioms. The instantiation draws heavily
on infrastructure previously developed by Larry Paulson in his <a
href="https://www.isa-afp.org/entries/Incompleteness.html">direct
formalisation of the concrete result</a>. It strengthens
Paulson's formalization of G&ouml;del's Second from that
entry by <i>not</i> assuming soundness, and in fact not
relying on any notion of model or semantic interpretation. The
strengthening was obtained by first replacing some of Paulson’s
semantic arguments with proofs within his HF calculus, and then
plugging in some of Paulson's (modified) lemmas to instantiate
our soundness-free G&ouml;del's Second locale.
[Robinson_Arithmetic]
title = Robinson Arithmetic
author = Andrei Popescu <https://www.andreipopescu.uk>, Dmitriy Traytel <https://traytel.bitbucket.io>
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
href="https://www.isa-afp.org/entries/Syntax_Independent_Logic.html">a
separate AFP entry</a> to the FOL theory of Robinson arithmetic
(also known as Q). The latter was formalised using Nominal Isabelle by
adapting <a
href="https://www.isa-afp.org/entries/Incompleteness.html">Larry
Paulson’s formalization of the Hereditarily Finite Set
theory</a>.
[Elliptic_Curves_Group_Law]
title = The Group Law for Elliptic Curves
author = Stefan Berghofer <http://www.in.tum.de/~berghofe>
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 <http://www.cse.unsw.edu.au/~kleing/>
topic = Mathematics/Analysis, Mathematics/Number theory
date = 2004-02-25
notify = kleing@cse.unsw.edu.au
abstract =
<p>This is an example submission to the Archive of Formal Proofs. It shows
submission requirements and explains the structure of a simple typical
submission.</p>
<p>Note that you can use <em>HTML tags</em> 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
<a href="../submitting.html">submission guidelines</a> before using this.</p>
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 <mailto:vb358@cam.ac.uk>, Martin Kleppmann<mailto:martin.kleppmann@cl.cam.ac.uk>, Dominic P. Mulligan<mailto:dominic.p.mulligan@googlemail.com>, Alastair R. Beresford<mailto:arb33@cam.ac.uk>
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<mailto:joachim@cis.upenn.edu>, Brian Huffman<>, Neil Mitchell<>, Christian Sternagel<mailto:c.sternagel@gmail.com>
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 <http://homes.soic.indiana.edu/jsiek/>
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.
<br>
The paper that accompanies these Isabelle theories is <a href="https://arxiv.org/abs/1707.03762">available on arXiv</a>.
[DynamicArchitectures]
title = Dynamic Architectures
author = Diego Marmsoler <http://marmsoler.com>
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)<br>
[Stewart_Apollonius]
title = Stewart's Theorem and Apollonius' Theorem
author = Lukas Bulwahn <mailto:lukas.bulwahn@gmail.com>
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 <mailto:cris.matache@gmail.com>, Victor B. F. Gomes <mailto:victorborgesfg@gmail.com>, Dominic P. Mulligan <mailto:dominic.p.mulligan@googlemail.com>
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 <mailto:jonas.raedle@tum.de>
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 <mailto:daniel@ekpyron.org>
topic = Logic/Philosophical aspects
date = 2017-09-17
notify = daniel@ekpyron.org
abstract =
<p> We present an embedding of the second-order fragment of the
Theory of Abstract Objects as described in Edward Zalta's
upcoming work <a
href="https://mally.stanford.edu/principia.pdf">Principia
Logico-Metaphysica (PLM)</a> 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
<b>abstract objects</b> 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 <a
href="https://mally.stanford.edu/Papers/rtt.pdf">known to
be challenging</a>. </p> <p> 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.
</p> <p> Our work thereby supports the concept of shallow
semantical embeddings of logical systems in HOL as a universal tool
for logical reasoning <a
href="http://www.mi.fu-berlin.de/inf/groups/ag-ki/publications/Universal-Reasoning/1703_09620_pd.pdf">as
promoted by Christoph Benzm&uuml;ller</a>. </p>
<p> 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. </p>
[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 <a
href="https://dl.acm.org/citation.cfm?doid=361002.361007">Multidimensional
binary search trees used for associative searching</a> and <a
href="https://dl.acm.org/citation.cfm?doid=355744.355745">
An Algorithm for Finding Best Matches in Logarithmic Expected
Time</a>.
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 <mailto:martin.rau@tum.de>, Tobias Nipkow <http://www.in.tum.de/~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 <em>Closest Pair of Points</em>
problem in Computational Geometry. Functional correctness and the
optimal running time of <em>O</em>(<em>n</em> log <em>n</em>) are
proved. Executable code is generated which is empirically competitive
with handwritten reference implementations.
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 <mailto:robin.essmann@tum.de>, Tobias Nipkow <http://www.in.tum.de/~nipkow/>, Simon Robillard <https://simon-robillard.net/>
topic = Computer science/Algorithms/Approximation
date = 2020-01-16
notify = nipkow@in.tum.de
abstract =
We present the first formal verification of approximation algorithms
for NP-complete optimization problems: vertex cover, independent set,
load balancing, and bin packing. The proofs correct incompletenesses
in existing proofs and improve the approximation ratio in one case.
[Diophantine_Eqns_Lin_Hom]
title = Homogeneous Linear Diophantine Equations
author = Florian Messner <mailto:florian.g.messner@uibk.ac.at>, Julian Parsert <mailto:julian.parsert@gmail.com>, Jonas Schöpf <mailto:jonas.schoepf@uibk.ac.at>, Christian Sternagel <mailto:c.sternagel@gmail.com>
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 <https://www.cl.cam.ac.uk/~wl302/>
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 <https://www.cl.cam.ac.uk/~wl302/>
topic = Mathematics/Analysis
date = 2017-10-17
notify = wl302@cam.ac.uk, liwenda1990@hotmail.com
abstract =
Based on evaluating Cauchy indices through remainder sequences, this
entry provides an effective procedure to count the number of complex
roots (with multiplicity) of a polynomial within a rectangle box or a
half-plane. Potential applications of this entry include certified
complex root isolation (of a polynomial) and testing the Routh-Hurwitz
stability criterion (i.e., to check whether all the roots of some
characteristic polynomial have negative real parts).
[Buchi_Complementation]
title = Büchi Complementation
author = Julian Brunner <http://www21.in.tum.de/~brunnerj/>
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: <ol>
<li>Definition of odd rankings and proof that an automaton
rejects a word iff there exists an odd ranking for it.</li>
<li>Definition of the complement automaton and proof that it
accepts exactly those words for which there is an odd
ranking.</li> <li>Verified implementation of the
complement automaton using the Isabelle Collections
Framework.</li> </ol>
[Transition_Systems_and_Automata]
title = Transition Systems and Automata
author = Julian Brunner <http://www21.in.tum.de/~brunnerj/>
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 <http://peteg.org>, 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 <mailto:s.linker@liverpool.ac.uk>
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 <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory, Mathematics/Algebra
date = 2017-12-21
notify = eberlm@in.tum.de
abstract =
<p>This article provides a formalisation of Dirichlet characters
and Dirichlet <em>L</em>-functions including proofs of
their basic properties &ndash; most notably their analyticity,
their areas of convergence, and their non-vanishing for &Re;(s)
&ge; 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.</p> <p>This
also leads to a relatively short proof of Dirichlet’s Theorem, which
states that, if <em>h</em> and <em>n</em> are
coprime, there are infinitely many primes <em>p</em> with
<em>p</em> &equiv; <em>h</em> (mod
<em>n</em>).</p>
[Symmetric_Polynomials]
title = Symmetric Polynomials
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Algebra
date = 2018-09-25
notify = eberlm@in.tum.de
abstract =
<p>A symmetric polynomial is a polynomial in variables
<em>X</em><sub>1</sub>,&hellip;,<em>X</em><sub>n</sub>
that does not discriminate between its variables, i.&thinsp;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.</p> <p>This article provides a definition of
symmetric polynomials and the elementary symmetric polynomials
e<sub>1</sub>,&hellip;,e<sub>n</sub> and
proofs of their basic properties, including three notable
ones:</p> <ul> <li> Vieta's formula, which
gives an explicit expression for the <em>k</em>-th
coefficient of a univariate monic polynomial in terms of its roots
<em>x</em><sub>1</sub>,&hellip;,<em>x</em><sub>n</sub>,
namely
<em>c</em><sub><em>k</em></sub> = (-1)<sup><em>n</em>-<em>k</em></sup>&thinsp;e<sub><em>n</em>-<em>k</em></sub>(<em>x</em><sub>1</sub>,&hellip;,<em>x</em><sub>n</sub>).</li>
<li>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.</li> <li>Third, as a corollary of the
previous two, that given a polynomial over some ring
<em>R</em>, any symmetric polynomial combination of its
roots is also in <em>R</em> even when the roots are not.
</ul> <p> Both the symmetry property itself and the
witness for the Fundamental Theorem are executable. </p>
[Taylor_Models]
title = Taylor Models
author = Christoph Traut<>, Fabian Immler <http://www21.in.tum.de/~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 <mailto:mohammad.abdulaziz8@gmail.com>, Lawrence C. Paulson <http://www.cl.cam.ac.uk/~lp15/>
+author = Mohammad Abdulaziz <http://home.in.tum.de/~mansour/>, Lawrence C. Paulson <http://www.cl.cam.ac.uk/~lp15/>
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 <http://home.in.tum.de/~mansour/>, Peter Lammich <http://www21.in.tum.de/~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 <http://home.in.tum.de/~mansour/>, 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 <https://people.compute.dtu.dk/andschl/>, Jasmin Christian Blanchette <mailto:j.c.blanchette@vu.nl>, Dmitriy Traytel <mailto:traytel@inf.ethz.ch>, Uwe Waldmann <mailto:uwe@mpi-inf.mpg.de>
+author = Anders Schlichtkrull <https://people.compute.dtu.dk/andschl/>, Jasmin Christian Blanchette <mailto:j.c.blanchette@vu.nl>, Dmitriy Traytel <https://traytel.bitbucket.io>, Uwe Waldmann <mailto:uwe@mpi-inf.mpg.de>
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
<em>Handbook of Automated Reasoning</em>. 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 <mailto:ben.fiedler@inf.ethz.ch>, Dmitriy Traytel <https://people.inf.ethz.ch/trayteld/>
+author = Ben Fiedler <mailto:ben.fiedler@inf.ethz.ch>, Dmitriy Traytel <https://traytel.bitbucket.io>
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 <mailto:jasmin.blanchette@gmail.com>, Andrei Popescu <mailto:uuomul@yahoo.com>, Dmitriy Traytel <mailto:traytel@inf.ethz.ch>
+author = Jasmin Christian Blanchette <mailto:jasmin.blanchette@gmail.com>, Andrei Popescu <https://www.andreipopescu.uk>, Dmitriy Traytel <https://traytel.bitbucket.io>
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 <http://www.unirioja.es/cu/jodivaso/>, Maximilian Haslbeck <http://cl-informatik.uibk.ac.at/users/mhaslbeck/>, Sebastiaan Joosten <http://sjcjoosten.nl/>, René Thiemann <http://cl-informatik.uibk.ac.at/users/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 <http://www.unirioja.es/cu/jodivaso/>, Sebastiaan Joosten <http://sjcjoosten.nl/>, René Thiemann <http://cl-informatik.uibk.ac.at/users/thiemann/>, Akihisa Yamada <mailto:ayamada@trs.cm.is.nagoya-u.ac.jp>
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 <http://cl-informatik.uibk.ac.at/users/mhaslbeck/>, Manuel Eberl <https://www.in.tum.de/~eberlm>, Tobias Nipkow <https://www.in.tum.de/~nipkow>
topic = Computer science/Data structures
date = 2018-02-06
notify = eberlm@in.tum.de
abstract =
<p> 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. </p>
<p> In particular, by choosing these priorities at random upon
insertion of an element, we can pretend that we inserted the elements
in <em>random order</em>, 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.</p>
[Skip_Lists]
title = Skip Lists
author = Max W. Haslbeck <http://cl-informatik.uibk.ac.at/users/mhaslbeck/>, Manuel Eberl <https://www21.in.tum.de/~eberlm/>
topic = Computer science/Data structures
date = 2020-01-09
notify = max.haslbeck@gmx.de
abstract =
<p> Skip lists are sorted linked lists enhanced with shortcuts
and are an alternative to binary search trees. A skip lists consists
of multiple levels of sorted linked lists where a list on level n is a
subsequence of the list on level n − 1. In the ideal case, elements
are skipped in such a way that a lookup in a skip lists takes O(log n)
time. In a randomised skip list the skipped elements are choosen
randomly. </p> <p> This entry contains formalized proofs
of the textbook results about the expected height and the expected
length of a search path in a randomised skip list. </p>
[Mersenne_Primes]
title = Mersenne primes and the Lucas–Lehmer test
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory
date = 2020-01-17
notify = eberlm@in.tum.de
abstract =
<p>This article provides formal proofs of basic properties of
Mersenne numbers, i. e. numbers of the form
2<sup><em>n</em></sup> - 1, and especially of
Mersenne primes.</p> <p>In particular, an efficient,
verified, and executable version of the Lucas&ndash;Lehmer test is
developed. This test decides primality for Mersenne numbers in time
polynomial in <em>n</em>.</p>
[Hoare_Time]
title = Hoare Logics for Time Bounds
author = Maximilian P. L. Haslbeck <http://www.in.tum.de/~haslbema>, Tobias Nipkow <https://www.in.tum.de/~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 <i>et al.</i> and a <i>separation
logic</i> 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 <http://marmsoler.com>
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)<br>
[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 <https://www.in.tum.de/~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 <a
href="https://doi.org/10.1017/S0956796811000104">Hirai
and Yamamoto</a> 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 <http://dss.in.tum.de/staff/brandt.html>, Manuel Eberl <https://www21.in.tum.de/~eberlm>, Christian Saile <http://dss.in.tum.de/staff/christian-saile.html>, Christian Stricker <http://dss.in.tum.de/staff/christian-stricker.html>
topic = Mathematics/Games and economics
date = 2018-03-22
notify = eberlm@in.tum.de
abstract =
<p>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 <a
href="http://dss.in.tum.de/files/brandt-research/stratset.pdf">Brandt
<em>et al.</em></a>, 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.</p>
[BNF_CC]
title = Bounded Natural Functors with Covariance and Contravariance
author = Andreas Lochbihler <http://www.andreas-lochbihler.de>, Joshua Schneider <mailto:joshua.schneider@inf.ethz.ch>
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 BNF<sub>CC</sub> that extends the mapper
and relator to covariant and contravariant parameters. We show that
<ol> <li> BNF<sub>CC</sub>s are closed under
functor composition and least and greatest fixpoints,</li>
<li> subtypes inherit the BNF<sub>CC</sub> structure
under conditions that generalise those for the BNF case,
and</li> <li> BNF<sub>CC</sub>s preserve
quotients under mild conditions.</li> </ol> These proofs
are carried out for abstract BNF<sub>CC</sub>s similar to
the AFP entry BNF Operations. In addition, we apply the
BNF<sub>CC</sub> 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 <mailto:bracevac@st.informatik.tu-darmstadt.de>, Richard Gay <mailto:gay@mais.informatik.tu-darmstadt.de>, Sylvia Grewe <mailto:grewe@st.informatik.tu-darmstadt.de>, Heiko Mantel <mailto:mantel@mais.informatik.tu-darmstadt.de>, Henning Sudbrock <mailto:sudbrock@mais.informatik.tu-darmstadt.de>, Markus Tasch <mailto:tasch@mais.informatik.tu-darmstadt.de>
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 <http://christoph-benzmueller.de>, Dana Scott <http://www.cs.cmu.edu/~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 <mailto:mk428@cl.cam.ac.uk>, Victor B. F. Gomes <mailto:vb358@cl.cam.ac.uk>, Dominic P. Mulligan <mailto:Dominic.Mulligan@arm.com>, Alastair R. Beresford <mailto:arb33@cl.cam.ac.uk>
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 <http://www.cl.cam.ac.uk/~ak2110/>, Wenda Li <http://www.cl.cam.ac.uk/~wl302/>
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 <https://www.in.tum.de/~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
<a href="Monad_Memo_DP.html">Monadification, Memoization and Dynamic Programming</a>,
thus yielding dynamic programming algorithms.
[Projective_Geometry]
title = Projective Geometry
author = Anthony Bordg <https://sites.google.com/site/anthonybordg/>
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 <https://sites.google.com/site/anthonybordg/>
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 =
<p> We formalize undecidablity results for Minsky machines. To
this end, we also formalize recursive inseparability.
</p><p> 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. </p><p> 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. </p><p> We do
<em>not</em> prove that recursive functions can simulate
Minsky machines. </p>
[Neumann_Morgenstern_Utility]
title = Von-Neumann-Morgenstern Utility Theorem
author = Julian Parsert<mailto:julian.parsert@gmail.com>, Cezary Kaliszyk<http://cl-informatik.uibk.ac.at/users/cek/>
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ć <mailto:filip@matf.bg.ac.rs>, Mirko Spasić <mailto:mirko@matf.bg.ac.rs>, René Thiemann <http://cl-informatik.uibk.ac.at/~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 <https://www.cl.cam.ac.uk/~wl302/>
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 <https://www.cl.cam.ac.uk/~lp15/>
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 <http://www.cl.cam.ac.uk/~ak2110/>
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 <http://www.cosc.canterbury.ac.nz/walter.guttmann/>
topic = Mathematics/Algebra
date = 2018-09-15
notify = walter.guttmann@canterbury.ac.nz
abstract =
We develop algebras for aggregation and minimisation for weight
matrices and for edge weights in graphs. We verify the correctness of
Prim's and Kruskal's minimum spanning tree algorithms based
on these algebras. We also show numerous instances of these algebras
based on linearly ordered commutative semigroups.
[Prime_Number_Theorem]
title = The Prime Number Theorem
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>, Lawrence C. Paulson <https://www.cl.cam.ac.uk/~lp15/>
topic = Mathematics/Number theory
date = 2018-09-19
notify = eberlm@in.tum.de
abstract =
<p>This article provides a short proof of the Prime Number
Theorem in several equivalent forms, most notably
&pi;(<em>x</em>) ~ <em>x</em>/ln
<em>x</em> where &pi;(<em>x</em>) is the
number of primes no larger than <em>x</em>. It also
defines other basic number-theoretic functions related to primes like
Chebyshev's functions &thetasym; and &psi; and the
&ldquo;<em>n</em>-th prime number&rdquo; function
p<sub><em>n</em></sub>. We also show various
bounds and relationship between these functions are shown. Lastly, we
derive Mertens' First and Second Theorem, i.&thinsp;e.
&sum;<sub><em>p</em>&le;<em>x</em></sub>
ln <em>p</em>/<em>p</em> = ln
<em>x</em> + <em>O</em>(1) and
&sum;<sub><em>p</em>&le;<em>x</em></sub>
1/<em>p</em> = ln ln <em>x</em> + M +
<em>O</em>(1/ln <em>x</em>). We also give
explicit bounds for the remainder terms.</p> <p>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
&sum;<sub><em>p</em>&le;<em>x</em></sub>
ln <em>p</em>/<em>p</em> = ln
<em>x</em> + c + <em>o</em>(1).</p>
<p>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 <em>et al.</em> 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.</p>
[Signature_Groebner]
title = Signature-Based Gröbner Basis Algorithms
author = Alexander Maletzky <https://risc.jku.at/m/alexander-maletzky/>
topic = Mathematics/Algebra, Computer science/Algorithms/Mathematical
date = 2018-09-20
notify = alexander.maletzky@risc.jku.at
abstract =
<p>This article formalizes signature-based algorithms for computing
Gr&ouml;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.</p>
<p>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&ouml;bner bases if an input parameter is chosen in
the right way.</p><p>The formalization follows the recent survey article by
Eder and Faug&egrave;re.</p>
[Factored_Transition_System_Bounding]
title = Upper Bounding Diameters of State Spaces of Factored Transition Systems
author = Friedrich Kurz <>, Mohammad Abdulaziz <http://home.in.tum.de/~mansour/>
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 <http://home.in.tum.de/~immler/>, Bohua Zhan <http://lcs.ios.ac.cn/~bzhan/>
topic = Mathematics/Analysis, Mathematics/Topology
date = 2018-10-22
notify = immler@in.tum.de, bzhan@ios.ac.cn
abstract =
We formalize the definition and basic properties of smooth manifolds
in Isabelle/HOL. Concepts covered include partition of unity, tangent
and cotangent spaces, and the fundamental theorem of path integrals.
We also examine some concrete manifolds such as spheres and projective
spaces. The formalization makes extensive use of the analysis and
linear algebra libraries in Isabelle/HOL, in particular its
“types-to-sets” mechanism.
[Matroids]
title = Matroids
author = Jonas Keinholz<>
topic = Mathematics/Combinatorics
date = 2018-11-16
notify = eberlm@in.tum.de
abstract =
<p>This article defines the combinatorial structures known as
<em>Independence Systems</em> and
<em>Matroids</em> 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
<a href="http://www.math.lsu.edu/~oxley/survey4.pdf">`What
is a Matroid?'</a>.</p>
[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 <a href="https://doi.org/10.1016/j.jlamp.2018.06.005">paper by the author</a> 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 <https://people.compute.dtu.dk/andschl/>, Jasmin Christian Blanchette <mailto:j.c.blanchette@vu.nl>, Dmitriy Traytel <mailto:traytel@inf.ethz.ch>
+author = Anders Schlichtkrull <https://people.compute.dtu.dk/andschl/>, Jasmin Christian Blanchette <mailto:j.c.blanchette@vu.nl>, Dmitriy Traytel <https://traytel.bitbucket.io>
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
<i>Handbook of Automated Reasoning</i>. The result is a
functional implementation of a first-order prover.
[Auto2_HOL]
title = Auto2 Prover
author = Bohua Zhan <http://lcs.ios.ac.cn/~bzhan/>
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 <http://staffwww.dcs.shef.ac.uk/people/G.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 <http://staffwww.dcs.shef.ac.uk/people/G.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 <http://staffwww.dcs.shef.ac.uk/people/G.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 <mailto:Roy.Overbeek@cwi.nl>
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 <em>determinacy</em>:
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 <https://www.brucker.ch/>, Michael Herzberg <http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.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 <https://www.brucker.ch>, Michael Herzberg <http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.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 <https://www.brucker.ch>, Michael Herzberg <http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.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 <https://www.brucker.ch>, Michael Herzberg <http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.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 <mailto:ecohen@amazon.com>, Norbert Schirmer <mailto:norbert.schirmer@web.de>
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&iuml;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 <http://www21.in.tum.de/~lammich>, Simon Wimmer <http://in.tum.de/~wimmers>
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: <ul> <li>Bisection
Square Root, </li> <li>Extended Euclid, </li>
<li>Exponentiation by Squaring, </li> <li>Binary
Search, </li> <li>Insertion Sort, </li>
<li>Quicksort, </li> <li>Depth First Search.
</li> </ul> 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 <http://cl-informatik.uibk.ac.at/users/bottesch/>, Max W. Haslbeck <http://cl-informatik.uibk.ac.at/users/mhaslbeck/>, René Thiemann <http://cl-informatik.uibk.ac.at/~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 <http://lcs.ios.ac.cn/~bzhan/>
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 <https://www-users.cs.york.ac.uk/~simonf/>, Frank Zeyda<>, Yakoub Nemouchi <mailto:yakoub.nemouchi@york.ac.uk>, Pedro Ribeiro<>, Burkhart Wolff<mailto:wolff@lri.fr>
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 <mailto:safouan.taha@lri.fr>, Lina Ye <mailto:lina.ye@lri.fr>, Burkhart Wolff<mailto:wolff@lri.fr>
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 <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory
date = 2019-02-11
notify = eberlm@in.tum.de
abstract =
<p>The most efficient known primality tests are
<em>probabilistic</em> in the sense that they use
randomness and may, with some probability, mistakenly classify a
composite number as prime &ndash; but never a prime number as
composite. Examples of this are the Miller&ndash;Rabin test, the
Solovay&ndash;Strassen test, and (in most cases) Fermat's
test.</p> <p>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.</p>
[Kruskal]
title = Kruskal's Algorithm for Minimum Spanning Forest
author = Maximilian P.L. Haslbeck <http://in.tum.de/~haslbema/>, Peter Lammich <http://www21.in.tum.de/~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 <https://www21.in.tum.de/~eberlm>
topic = Computer science/Algorithms
date = 2019-02-01
notify = eberlm@in.tum.de
abstract =
<p>This entry defines the set of <em>inversions</em>
of a list, i.e. the pairs of indices that violate sortedness. It also
proves the correctness of the well-known
<em>O</em>(<em>n log n</em>)
divide-and-conquer algorithm to compute the number of
inversions.</p>
[Prime_Distribution_Elementary]
title = Elementary Facts About the Distribution of Primes
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory
date = 2019-02-21
notify = eberlm@in.tum.de
abstract =
<p>This entry is a formalisation of Chapter 4 (and parts of
Chapter 3) of Apostol's <a
href="https://www.springer.com/de/book/9780387901633"><em>Introduction
to Analytic Number Theory</em></a>. The main topics that
are addressed are properties of the distribution of prime numbers that
can be shown in an elementary way (i.&thinsp;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
<em>n</em>, the divisor function
<em>d(n)</em>, Euler's totient function
<em>&phi;(n)</em>, and
lcm(1,&hellip;,<em>n</em>).</p>
[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 =
<p>The theory is a formalization of the
<a href="https://www.omg.org/spec/OCL/">OCL</a> type system, its abstract
syntax and expression typing rules. The theory does not define a concrete
syntax and a semantics. In contrast to
<a href="https://www.isa-afp.org/entries/Featherweight_OCL.html">Featherweight OCL</a>,
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.</p>
<p>The Safe OCL distincts nullable and non-nullable types. Also the theory gives a
formal definition of <a href="http://ceur-ws.org/Vol-1512/paper07.pdf">safe
navigation operations</a>. 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.</p>
<p>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.</p>
<p>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.</p>
[QHLProver]
title = Quantum Hoare Logic
author = Junyi Liu<>, Bohua Zhan <http://lcs.ios.ac.cn/~bzhan/>, 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 <https://www.cl.cam.ac.uk/~ak2110/>, Wenda Li <https://www.cl.cam.ac.uk/~wl302/>
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 <mailto:lor.gheri@gmail.com>, Andrei Popescu <mailto:a.popescu@mdx.ac.uk>
+author = Lorenzo Gheri <mailto:lor.gheri@gmail.com>, Andrei Popescu <https://www.andreipopescu.uk>
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 <mailto:benedikt.seidl@tum.de>, Salomon Sickert <mailto:s.sickert@tum.de>
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.
<p>
[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 <http://people.inf.ethz.ch/trayteld/>
+author = Matthias Brun<>, Dmitriy Traytel <https://traytel.bitbucket.io>
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. <a
href="https://doi.org/10.1145/2535838.2535851">Miller et
al.</a> introduced &lambda;&bull; (pronounced
<i>lambda auth</i>)&mdash;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 &lambda;&bull; and prove its
correctness and security properties. With Isabelle's help, we
uncover and repair several mistakes in the informal proofs and lemma
statements. Our findings are summarized in a <a
href="http://people.inf.ethz.ch/trayteld/papers/lambdaauth/lambdaauth.pdf">paper
draft</a>.
[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 <https://risc.jku.at/m/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 <http://cl-informatik.uibk.ac.at/users/bottesch/>, Alban Reynaud <>, René Thiemann <http://cl-informatik.uibk.ac.at/~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 <http://www.parsert.com/>, Cezary Kaliszyk <http://cl-informatik.uibk.ac.at/cek/>
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 <http://www.cs.cmu.edu/~aplatzer/>
topic = Computer science/Programming languages/Logics
date = 2019-06-03
notify = aplatzer@cs.cmu.edu
abstract =
This formalization provides differential game logic (dGL), a logic for
proving properties of hybrid game. In addition to the syntax and
semantics, it formalizes a uniform substitution calculus for dGL.
Church's uniform substitutions substitute a term or formula for a
function or predicate symbol everywhere. The uniform substitutions for
dGL also substitute hybrid games for a game symbol everywhere. We
prove soundness of one-pass uniform substitutions and the axioms of
differential game logic with respect to their denotational semantics.
One-pass uniform substitutions are faster by postponing
soundness-critical admissibility checks with a linear pass homomorphic
application and regain soundness by a variable condition at the
replacements. The formalization is based on prior non-mechanized
soundness proofs for dGL.
[Complete_Non_Orders]
title = Complete Non-Orders and Fixed Points
author = Akihisa Yamada <http://group-mmm.org/~ayamada/>, Jérémy Dubut <http://group-mmm.org/~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 <http://www21.in.tum.de/~lammich>, Tobias Nipkow <http://www21.in.tum.de/~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 <em>priority search tree</em>. 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 <em>Purely Functional, Simple and Efficient Priority
Search Trees and Applications to Prim and Dijkstra</em>.
[Prim_Dijkstra_Simple]
title = Purely Functional, Simple, and Efficient Implementation of Prim and Dijkstra
author = Peter Lammich <http://www21.in.tum.de/~lammich>, Tobias Nipkow <http://www21.in.tum.de/~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 <em>Purely Functional, Simple and Efficient
Priority Search Trees and Applications to Prim and Dijkstra</em>.
[MFOTL_Monitor]
title = Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic
-author = Joshua Schneider <mailto:joshua.schneider@inf.ethz.ch>, Dmitriy Traytel <http://people.inf.ethz.ch/trayteld/>
+author = Joshua Schneider <mailto:joshua.schneider@inf.ethz.ch>, Dmitriy Traytel <https://traytel.bitbucket.io>
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 <a href="https://doi.org/10.1007/978-3-030-32079-9_18">RV
2019 paper</a>, 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)<br>
[FOL_Seq_Calc1]
title = A Sequent Calculus for First-Order Logic
author = Asta Halkjær From <https://people.compute.dtu.dk/ahfrom/>
contributors = Alexander Birch Jensen <https://people.compute.dtu.dk/aleje/>,
Anders Schlichtkrull <https://people.compute.dtu.dk/andschl/>,
Jørgen Villadsen <https://people.compute.dtu.dk/jovi/>
topic = Logic/Proof theory
date = 2019-07-18
notify = ahfrom@dtu.dk
abstract =
This work formalizes soundness and completeness of a one-sided sequent
calculus for first-order logic. The completeness is shown via a
translation from a complete semantic tableau calculus, the proof of
which is based on the First-Order Logic According to Fitting theory.
The calculi and proof techniques are taken from Ben-Ari's
Mathematical Logic for Computer Science.
[Szpilrajn]
title = Szpilrajn Extension Theorem
author = Peter Zeller <mailto:p_zeller@cs.uni-kl.de>
topic = Mathematics/Order
date = 2019-07-27
notify = p_zeller@cs.uni-kl.de
abstract =
We formalize the Szpilrajn extension theorem, also known as
order-extension principal: Every strict partial order can be extended
to a strict linear order.
[TESL_Language]
title = A Formal Development of a Polychronous Polytimed Coordination Language
author = Hai Nguyen Van <mailto:hai.nguyenvan.phie@gmail.com>, Frédéric Boulanger <mailto:frederic.boulanger@centralesupelec.fr>, Burkhart Wolff <mailto:burkhart.wolff@lri.fr>
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:
<ul><li>the
behavior of the sub-systems is observed only at a series of discrete
instants,</li><li>events may occur in different sub-systems at unrelated
times, leading to polychronous systems, which do not necessarily have
a common base clock,</li><li>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,</li><li>the domain of time
(discrete, rational, continuous...) may be different in the
subsystems, leading to polytimed systems,</li><li>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).</li></ul>
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 <mailto:giuliano@galois.com>
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 <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Misc
date = 2019-08-05
notify = eberlm@in.tum.de
abstract =
<p>This entry contains formalisations of the answers to three of
the six problem of the International Mathematical Olympiad 2019,
namely Q1, Q4, and Q5.</p> <p>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.</p>
[Adaptive_State_Counting]
title = Formalisation of an Adaptive State Counting Algorithm
author = Robert Sachtleben <mailto:rob_sac@uni-bremen.de>
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 <a
href="https://doi.org/10.1109/TC.2004.85">Testing from a
Non-Deterministic Finite State Machine Using Adaptive State
Counting</a>. 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 <http://www21.in.tum.de/~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 <i>Basic Algebra</i>
leading to the respective fundamental homomorphism theorems. The
study is not intended as a library base for abstract algebra. It
rather explores an approach towards abstract algebra in Isabelle.
[Hybrid_Systems_VCs]
title = Verification Components for Hybrid Systems
author = Jonathan Julian Huerta y Munive <>
topic = Mathematics/Algebra, Mathematics/Analysis
date = 2019-09-10
notify = jjhuertaymunive1@sheffield.ac.uk, jonjulian23@gmail.com
abstract =
These components formalise a semantic framework for the deductive
verification of hybrid systems. They support reasoning about
continuous evolutions of hybrid programs in the style of differential
dynamics logic. Vector fields or flows model these evolutions, and
their verification is done with invariants for the former or orbits
for the latter. Laws of modal Kleene algebra or categorical predicate
transformers implement the verification condition generation. Examples
show the approach at work.
[Generic_Join]
title = Formalization of Multiway-Join Algorithms
author = Thibault Dardinier<>
topic = Computer science/Algorithms
date = 2019-09-16
notify = tdardini@student.ethz.ch, traytel@inf.ethz.ch
abstract =
Worst-case optimal multiway-join algorithms are recent seminal
achievement of the database community. These algorithms compute the
natural join of multiple relational databases and improve in the worst
case over traditional query plan optimizations of nested binary joins.
In 2014, <a
href="https://doi.org/10.1145/2590989.2590991">Ngo, Ré,
and Rudra</a> gave a unified presentation of different multi-way
join algorithms. We formalized and proved correct their "Generic
Join" algorithm and extended it to support negative joins.
[Aristotles_Assertoric_Syllogistic]
title = Aristotle's Assertoric Syllogistic
author = Angeliki Koutsoukou-Argyraki <https://www.cl.cam.ac.uk/~ak2110/>
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 <a
href="https://plato.stanford.edu/entries/aristotle-logic/">article from the Stanford Encyclopedia of Philosophy by Robin Smith.</a> To
this end, we use a set theoretic formulation (covering both individual
and general predication). In particular, we formalise the deductions
in the Figures and after that we present Aristotle's
metatheoretical observation that all deductions in the Figures can in
fact be reduced to either Barbara or Celarent. As the formal proofs
prove to be straightforward, the interest of this entry lies in
illustrating the functionality of Isabelle and high efficiency of
Sledgehammer for simple exercises in philosophy.
[VerifyThis2019]
title = VerifyThis 2019 -- Polished Isabelle Solutions
author = Peter Lammich<>, Simon Wimmer<http://home.in.tum.de/~wimmers/>
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 <https://www.cl.cam.ac.uk/~lp15/>
topic = Logic/Set theory
date = 2019-10-24
notify = lp15@cam.ac.uk
abstract =
<p>This entry is a new formalisation of ZFC set theory in Isabelle/HOL. It is
logically equivalent to Obua's HOLZF; the point is to have the closest
possible integration with the rest of Isabelle/HOL, minimising the amount of
new notations and exploiting type classes.</p>
<p>There is a type <em>V</em> of sets and a function <em>elts :: V =&gt; V
set</em> mapping a set to its elements. Classes simply have type <em>V
set</em>, and a predicate identifies the small classes: those that correspond
to actual sets. Type classes connected with orders and lattices are used to
minimise the amount of new notation for concepts such as the subset relation,
union and intersection. Basic concepts — Cartesian products, disjoint sums,
natural numbers, functions, etc. — are formalised.</p>
<p>More advanced set-theoretic concepts, such as transfinite induction,
ordinals, cardinals and the transitive closure of a set, are also provided.
The definition of addition and multiplication for general sets (not just
ordinals) follows Kirby.</p>
<p>The theory provides two type classes with the aim of facilitating
developments that combine <em>V</em> with other Isabelle/HOL types:
<em>embeddable</em>, the class of types that can be injected into <em>V</em>
(including <em>V</em> itself as well as <em>V*V</em>, etc.), and
<em>small</em>, the class of types that correspond to some ZF set.</p>
extra-history =
Change history:
[2020-01-28]: Generalisation of the "small" predicate and order types to arbitrary sets;
ordinal exponentiation;
introduction of the coercion ord_of_nat :: "nat => V";
numerous new lemmas. (revision 6081d5be8d08)
[Interval_Arithmetic_Word32]
title = Interval Arithmetic on 32-bit Words
author = Brandon Bohrer <mailto:bbohrer@cs.cmu.edu>
topic = Computer science/Data structures
date = 2019-11-27
notify = bjbohrer@gmail.com, bbohrer@cs.cmu.edu
abstract =
Interval_Arithmetic implements conservative interval arithmetic
computations, then uses this interval arithmetic to implement a simple
programming language where all terms have 32-bit signed word values,
with explicit infinities for terms outside the representable bounds.
Our target use case is interpreters for languages that must have a
well-understood low-level behavior. We include a formalization of
bounded-length strings which are used for the identifiers of our
language. Bounded-length identifiers are useful in some applications,
for example the <a href="https://www.isa-afp.org/entries/Differential_Dynamic_Logic.html">Differential_Dynamic_Logic</a> article,
where a Euclidean space indexed by identifiers demands that identifiers
are finitely many.
[Generalized_Counting_Sort]
title = An Efficient Generalization of Counting Sort for Large, possibly Infinite Key Ranges
author = Pasquale Noce <mailto:pasquale.noce.lavoro@gmail.com>
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 <http://home.in.tum.de/~immler/>, Yong Kiam Tan <https://www.cs.cmu.edu/~yongkiat/>
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 <https://www.lri.fr/~ftuong/>, Burkhart Wolff <https://www.lri.fr/~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 <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory
date = 2019-12-27
notify = manuel.eberl@tum.de
abstract =
<p>This article provides a formalisation of Beukers's
straightforward analytic proof that ζ(3) is irrational. This was first
proven by Apéry (which is why this result is also often called
‘Apéry's Theorem’) using a more algebraic approach. This
formalisation follows <a
href="http://people.math.sc.edu/filaseta/gradcourses/Math785/Math785Notes4.pdf">Filaseta's
presentation</a> of Beukers's proof.</p>
[Hybrid_Logic]
title = Formalizing a Seligman-Style Tableau System for Hybrid Logic
author = Asta Halkjær From <https://people.compute.dtu.dk/ahfrom/>
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 <mailto:stark@cs.stonybrook.edu>
topic = Mathematics/Category theory
date = 2020-01-06
notify = stark@cs.stonybrook.edu
abstract =
Taking as a starting point the author's previous work on
developing aspects of category theory in Isabelle/HOL, this article
gives a compatible formalization of the notion of
"bicategory" and develops a framework within which formal
proofs of facts about bicategories can be given. The framework
includes a number of basic results, including the Coherence Theorem,
the Strictness Theorem, pseudofunctors and biequivalence, and facts
about internal equivalences and adjunctions in a bicategory. As a
driving application and demonstration of the utility of the framework,
it is used to give a formal proof of a theorem, due to Carboni,
Kasangian, and Street, that characterizes up to biequivalence the
bicategories of spans in a category with pullbacks. The formalization
effort necessitated the filling-in of many details that were not
evident from the brief presentation in the original paper, as well as
identifying a few minor corrections along the way.
extra-history =
Change history:
[2020-02-15]:
Move ConcreteCategory.thy from Bicategory to Category3 and use it systematically.
Make other minor improvements throughout.
(revision a51840d36867)<br>
[Subset_Boolean_Algebras]
title = A Hierarchy of Algebras for Boolean Subsets
author = Walter Guttmann <http://www.cosc.canterbury.ac.nz/walter.guttmann/>, Bernhard Möller <https://www.informatik.uni-augsburg.de/en/chairs/dbis/pmi/staff/moeller/>
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 &lambda;-Calculus
author = Bertram Felgenhauer <mailto:int-e@gmx.de>
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 &lambda;-calculus, linked to a concise, self-contained
specification. The implementation works on a Church-encoded
representation of countable ordinals. The initial conversion to
hereditary base 2 is not covered, but the material is sufficient to
compute the particular value G(16), and easily extends to other fixed
arguments.
[VeriComp]
title = A Generic Framework for Verified Compilers
author = Martin Desharnais <https://martin.desharnais.me>
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 <http://net.in.tum.de/~diekmann>, Lars Hupel <https://www21.in.tum.de/~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 <https://orcid.org/0000-0003-3290-5034>, Edgar Gonzàlez <mailto:edgargip@google.com>
topic = Computer science/Algorithms/Distributed
date = 2020-03-25
notify = eminkarayel@google.com, edgargip@google.com, me@eminkarayel.de
abstract =
Commutative Replicated Data Types (CRDTs) are a promising new class of
data structures for large-scale shared mutable content in applications
that only require eventual consistency. The WithOut Operational
Transforms (WOOT) framework is a CRDT for collaborative text editing
introduced by Oster et al. (CSCW 2006) for which the eventual
consistency property was verified only for a bounded model to date. We
contribute a formal proof for WOOTs strong eventual consistency.
[Furstenberg_Topology]
title = Furstenberg's topology and his proof of the infinitude of primes
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory
date = 2020-03-22
notify = manuel.eberl@tum.de
abstract =
<p>This article gives a formal version of Furstenberg's
topological proof of the infinitude of primes. He defines a topology
on the integers based on arithmetic progressions (or, equivalently,
residue classes). Using some fairly obvious properties of this
topology, the infinitude of primes is then easily obtained.</p>
<p>Apart from this, this topology is also fairly ‘nice’ in
general: it is second countable, metrizable, and perfect. All of these
(well-known) facts are formally proven, including an explicit metric
for the topology given by Zulfeqarr.</p>
[Saturation_Framework]
title = A Comprehensive Framework for Saturation Theorem Proving
author = Sophie Tourret <https://www.mpi-inf.mpg.de/departments/automation-of-logic/people/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 <a
href="http://matryoshka.gforge.inria.fr/pubs/satur_report.pdf">on
the Matryoshka website</a>. The names of the Isabelle lemmas and
theorems corresponding to the results in the report are indicated in
the margin of the report.
[Saturation_Framework_Extensions]
title = Extensions to the Comprehensive Framework for Saturation Theorem Proving
author = Jasmin Blanchette <https://www.cs.vu.nl/~jbe248/>, Sophie Tourret <https://www.mpi-inf.mpg.de/departments/automation-of-logic/people/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
<em>Saturation_Framework</em> with the following
contributions: <ul> <li>an application of the framework
to prove Bachmair and Ganzinger's resolution prover RP
refutationally complete, which was formalized in a more ad hoc fashion
by Schlichtkrull et al. in the AFP entry
<em>Ordered_Resultion_Prover</em>;</li>
<li>generalizations of various basic concepts formalized by
Schlichtkrull et al., which were needed to verify RP and could be
useful to formalize other calculi, such as superposition;</li>
<li>alternative proofs of fairness (and hence saturation and
ultimately refutational completeness) for the given clause procedures
GC and LGC, based on invariance.</li> </ul>
[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 <mailto:martin.raszyk@inf.ethz.ch>, Joshua Schneider <mailto:joshua.schneider@inf.ethz.ch>, Dmitriy Traytel <http://people.inf.ethz.ch/trayteld/>
+author = Thibault Dardinier<>, Lukas Heimes<>, Martin Raszyk <mailto:martin.raszyk@inf.ethz.ch>, Joshua Schneider <mailto:joshua.schneider@inf.ethz.ch>, Dmitriy Traytel <https://traytel.bitbucket.io>
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 <a
href="http://people.inf.ethz.ch/trayteld/papers/ijcar20-verimonplus/verimonplus.pdf">
forthcoming paper at IJCAR 2020</a>, significantly extends <a
href="https://www.isa-afp.org/entries/MFOTL_Monitor.html">previous
work on a verified monitor</a> for MFOTL. Apart from the
addition of regular expressions and aggregations, we implemented <a
href="https://www.isa-afp.org/entries/Generic_Join.html">multi-way
joins</a> and a specialized sliding window algorithm to further
optimize the monitor.
[Sliding_Window_Algorithm]
title = Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows
-author = Lukas Heimes<>, Dmitriy Traytel <http://people.inf.ethz.ch/trayteld/>, Joshua Schneider<>
+author = Lukas Heimes<>, Dmitriy Traytel <https://traytel.bitbucket.io>, 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 <a
href="https://doi.org/10.1016/j.ipl.2014.09.009">sliding
window algorithm (SWA)</a> is an algorithm for combining the
elements of subsequences of a sequence with an associative operator.
It is greedy and minimizes the number of operator applications. We
formalize the algorithm and verify its functional correctness. We
extend the algorithm with additional operations and provide an
alternative interface to the slide operation that does not require the
entire input sequence.
[Lucas_Theorem]
title = Lucas's Theorem
author = Chelsea Edmonds <mailto:cle47@cam.ac.uk>
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 <em>n</em>, an alternate binomial theorem statement,
and a formalised proof of the Freshman's dream (mod <em>p</em>) 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 <http://www.andreas-lochbihler.de>, Ognjen Marić <mailto:ogi.afp@mynosefroze.com>
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 <a
href="https://www.canton.io">Canton</a>, 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 <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Algebra
date = 2020-04-24
notify = eberlm@in.tum.de
abstract =
<p>This article provides a formalisation of the symmetric
multivariate polynomials known as <em>power sum
polynomials</em>. These are of the form
p<sub>n</sub>(<em>X</em><sub>1</sub>,&hellip;,
<em>X</em><sub><em>k</em></sub>) =
<em>X</em><sub>1</sub><sup>n</sup>
+ &hellip; +
X<sub><em>k</em></sub><sup>n</sup>.
A formal proof of the Girard–Newton Theorem is also given. This
theorem relates the power sum polynomials to the elementary symmetric
polynomials s<sub><em>k</em></sub> in the form
of a recurrence relation
(-1)<sup><em>k</em></sup>
<em>k</em> s<sub><em>k</em></sub>
=
&sum;<sub>i&isinv;[0,<em>k</em>)</sub>
(-1)<sup>i</sup> s<sub>i</sub>
p<sub><em>k</em>-<em>i</em></sub>&thinsp;.</p>
<p>As an application, this is then used to solve a generalised
form of a puzzle given as an exercise in Dummit and Foote's
<em>Abstract Algebra</em>: For <em>k</em>
complex unknowns <em>x</em><sub>1</sub>,
&hellip;,
<em>x</em><sub><em>k</em></sub>,
define p<sub><em>j</em></sub> :=
<em>x</em><sub>1</sub><sup><em>j</em></sup>
+ &hellip; +
<em>x</em><sub><em>k</em></sub><sup><em>j</em></sup>.
Then for each vector <em>a</em> &isinv;
&#x2102;<sup><em>k</em></sup>, show that
there is exactly one solution to the system p<sub>1</sub>
= a<sub>1</sub>, &hellip;,
p<sub><em>k</em></sub> =
a<sub><em>k</em></sub> up to permutation of
the
<em>x</em><sub><em>i</em></sub>
and determine the value of
p<sub><em>i</em></sub> for
i&gt;k.</p>
[Gaussian_Integers]
title = Gaussian Integers
author = Manuel Eberl <https://www21.in.tum.de/~eberlm>
topic = Mathematics/Number theory
date = 2020-04-24
notify = eberlm@in.tum.de
abstract =
<p>The Gaussian integers are the subring &#8484;[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.</p> <p>Lastly, this Gaussian integer
formalisation is used in two short applications:</p> <ol>
<li> The characterisation of all positive integers that can be
written as sums of two squares</li> <li> Euclid's
formula for primitive Pythagorean triples</li> </ol>
<p>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.</p>
[Forcing]
title = Formalization of Forcing in Isabelle/ZF
author = Emmanuel Gunther <mailto:gunther@famaf.unc.edu.ar>, Miguel Pagano <https://cs.famaf.unc.edu.ar/~mpagano/>, Pedro Sánchez Terraf <https://cs.famaf.unc.edu.ar/~pedro/home_en>
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.
[Recursion-Addition]
title = Recursion Theorem in ZF
author = Georgy Dunaev <mailto:georgedunaev@gmail.com>
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 <i>Introduction to
Set Theory</i>, 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 <mailto:s.sickert@tum.de>
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 <mailto:jjhuertaymunive1@sheffield.ac.uk>
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 <https://www.cl.cam.ac.uk/~ak2110/>, Wenda Li <https://www.cl.cam.ac.uk/~wl302/>
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
<a href="https://projecteuclid.org/euclid.pjm/1102911140">[1]</a>.
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 <mailto:c.sternagel@gmail.com>, René Thiemann <http://cl-informatik.uibk.ac.at/~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&ndash;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 <mailto:avhe@dtu.dk>, Sebastian Mödersheim <https://people.compute.dtu.dk/samo/>, Achim D. Brucker <https://www.brucker.ch/>
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 <mailto:avhe@dtu.dk>, Sebastian Mödersheim <https://people.compute.dtu.dk/samo/>, Achim D. Brucker <https://www.brucker.ch/>, Anders Schlichtkrull <https://people.compute.dtu.dk/andschl/>
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 <https://www.unirioja.es/cu/jodivaso/>
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 <https://www.cl.cam.ac.uk/~lp15/>
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 <mailto:albert.rizaldi@ntu.edu.sg>, Fabian Immler <http://home.in.tum.de/~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 <http://www.cosc.canterbury.ac.nz/walter.guttmann/>, Peter Höfner <http://www.hoefner-online.de/>
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 <https://www.cl.cam.ac.uk/~ak2110/>
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&#257;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 <https://www.cl.cam.ac.uk/~lp15/>
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 <http://www.cosc.canterbury.ac.nz/walter.guttmann/>
topic = Computer science/Data structures
date = 2020-08-26
notify = walter.guttmann@canterbury.ac.nz
abstract =
We give a simple relation-algebraic semantics of read and write
operations on associative arrays. The array operations seamlessly
integrate with assignments in the Hoare-logic library. Using relation
algebras and Kleene algebras we verify the correctness of an
array-based implementation of disjoint-set forests with a naive union
operation and a find operation with path compression.
[PAC_Checker]
title = Practical Algebraic Calculus Checker
author = Mathias Fleury <http://fmv.jku.at/fleury>, Daniela Kaufmann <http://fmv.jku.at/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 <http://peteg.org>
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 <mailto:jmafoster1@sheffield.ac.uk>, Achim D. Brucker <mailto:a.brucker@exeter.ac.uk>, Ramsay G. Taylor <mailto:r.g.taylor@sheffield.ac.uk>, John Derrick <mailto:j.derrick@sheffield.ac.uk>
topic = Computer science/Automata and formal languages
date = 2020-09-07
notify = jmafoster1@sheffield.ac.uk, adbrucker@0x5f.org
abstract =
In this AFP entry, we provide a formalisation of extended finite state
machines (EFSMs) where models are represented as finite sets of
transitions between states. EFSMs execute traces to produce observable
outputs. We also define various simulation and equality metrics for
EFSMs in terms of traces and prove their strengths in relation to each
other. Another key contribution is a framework of function definitions
such that LTL properties can be phrased over EFSMs. Finally, we
provide a simple example case study in the form of a drinks machine.
[Extended_Finite_State_Machine_Inference]
title = Inference of Extended Finite State Machines
author = Michael Foster <mailto:jmafoster1@sheffield.ac.uk>, Achim D. Brucker <mailto:a.brucker@exeter.ac.uk>, Ramsay G. Taylor <mailto:r.g.taylor@sheffield.ac.uk>, John Derrick <mailto:j.derrick@sheffield.ac.uk>
topic = Computer science/Automata and formal languages
date = 2020-09-07
notify = jmafoster1@sheffield.ac.uk, adbrucker@0x5f.org
abstract =
In this AFP entry, we provide a formal implementation of a
state-merging technique to infer extended finite state machines
(EFSMs), complete with output and update functions, from black-box
traces. In particular, we define the subsumption in context relation
as a means of determining whether one transition is able to account
for the behaviour of another. Building on this, we define the direct
subsumption relation, which lifts the subsumption in context relation
to EFSM level such that we can use it to determine whether it is safe
to merge a given pair of transitions. Key proofs include the
conditions necessary for subsumption to occur and that subsumption
and direct subsumption are preorder relations. We also provide a
number of different heuristics which can be used to abstract away
concrete values into registers so that more states and transitions can
be merged and provide proofs of the various conditions which must hold
for these abstractions to subsume their ungeneralised counterparts. A
Code Generator setup to create executable Scala code is also defined.
+
+[Physical_Quantities]
+title = A Sound Type System for Physical Quantities, Units, and Measurements
+author = Simon Foster <https://www-users.cs.york.ac.uk/~simonf/>, Burkhart Wolff <https://www.lri.fr/~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).
+
diff --git a/metadata/topics b/metadata/topics
--- a/metadata/topics
+++ b/metadata/topics
@@ -1,62 +1,63 @@
Computer science
+ Artificial intelligence
Automata and formal languages
Algorithms
Graph
Distributed
Concurrent
Online
Geometry
Approximation
Mathematical
Optimization
Concurrency
Process calculi
Data structures
Functional programming
Hardware
Machine learning
Networks
Programming languages
Language definitions
Lambda calculi
Type systems
Logics
Compiling
Static analysis
Transformations
Misc
Security
Cryptography
Semantics
System description languages
Logic
Philosophical aspects
General logic
Classical propositional logic
Classical first-order logic
Decidability of theories
Mechanization of proofs
Lambda calculus
Logics of knowledge and belief
Temporal logic
Modal logic
Paraconsistent logics
Computability
Set theory
Proof theory
Rewriting
Mathematics
Order
Algebra
Analysis
Probability theory
Number theory
Games and economics
Geometry
Topology
Graph theory
Combinatorics
Category theory
Physics
Misc
Tools
diff --git a/thys/AI_Planning_Languages_Semantics/Error_Monad_Add.thy b/thys/AI_Planning_Languages_Semantics/Error_Monad_Add.thy
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/Error_Monad_Add.thy
@@ -0,0 +1,52 @@
+theory Error_Monad_Add
+imports
+ "Certification_Monads.Check_Monad"
+ "Show.Show_Instances"
+begin
+ (* TODO: Move *)
+ abbreviation "assert_opt \<Phi> \<equiv> if \<Phi> then Some () else None"
+
+ definition "lift_opt m e \<equiv> case m of Some x \<Rightarrow> Error_Monad.return x | None \<Rightarrow> Error_Monad.error e"
+
+ lemma lift_opt_simps[simp]:
+ "lift_opt None e = error e"
+ "lift_opt (Some v) e = return v"
+ by (auto simp: lift_opt_def)
+
+ (* TODO: Move *)
+ lemma reflcl_image_iff[simp]: "R\<^sup>=``S = S\<union>R``S" by blast
+
+ named_theorems return_iff
+
+ lemma bind_return_iff[return_iff]: "Error_Monad.bind m f = Inr y \<longleftrightarrow> (\<exists>x. m = Inr x \<and> f x = Inr y)"
+ by auto
+
+ lemma lift_opt_return_iff[return_iff]: "lift_opt m e = Inr x \<longleftrightarrow> m=Some x"
+ unfolding lift_opt_def by (auto split: option.split)
+
+ lemma check_return_iff[return_iff]: "check \<Phi> e = Inr uu \<longleftrightarrow> \<Phi>"
+ by (auto simp: check_def)
+
+
+ lemma check_simps[simp]:
+ "check True e = succeed"
+ "check False e = error e"
+ by (auto simp: check_def)
+
+ lemma Let_return_iff[return_iff]: "(let x=v in f x) = Inr w \<longleftrightarrow> f v = Inr w" by simp
+
+
+ abbreviation ERR :: "shows \<Rightarrow> (unit \<Rightarrow> shows)" where "ERR s \<equiv> \<lambda>_. s"
+ abbreviation ERRS :: "String.literal \<Rightarrow> (unit \<Rightarrow> shows)" where "ERRS s \<equiv> ERR (shows s)"
+
+
+ lemma error_monad_bind_split: "P (bind m f) \<longleftrightarrow> (\<forall>v. m = Inl v \<longrightarrow> P (Inl v)) \<and> (\<forall>v. m = Inr v \<longrightarrow> P (f v))"
+ by (cases m) auto
+
+ lemma error_monad_bind_split_asm: "P (bind m f) \<longleftrightarrow> \<not> (\<exists>x. m = Inl x \<and> \<not> P (Inl x) \<or> (\<exists>x. m = Inr x \<and> \<not> P (f x)))"
+ by (cases m) auto
+
+ lemmas error_monad_bind_splits =error_monad_bind_split error_monad_bind_split_asm
+
+
+end
diff --git a/thys/AI_Planning_Languages_Semantics/Lifschitz_Consistency.thy b/thys/AI_Planning_Languages_Semantics/Lifschitz_Consistency.thy
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/Lifschitz_Consistency.thy
@@ -0,0 +1,416 @@
+section \<open>Soundness theorem for the STRIPS semantics\<close>
+text \<open>We prove the soundness theorem according to ~\cite{lifschitz1987semantics}.\<close>
+
+theory Lifschitz_Consistency
+imports PDDL_STRIPS_Semantics
+begin
+
+
+text \<open>States are modeled as valuations of our underlying predicate logic.\<close>
+type_synonym state = "(predicate\<times>object list) valuation"
+
+context ast_domain begin
+ text \<open>An action is a partial function from states to states. \<close>
+ type_synonym action = "state \<rightharpoonup> state"
+
+ text \<open>The Isabelle/HOL formula @{prop \<open>f s = Some s'\<close>} means
+ that \<open>f\<close> is applicable in state \<open>s\<close>, and the result is \<open>s'\<close>. \<close>
+
+ text \<open>Definition B (i)--(iv) in Lifschitz's paper~\cite{lifschitz1987semantics}\<close>
+
+ fun is_NegPredAtom where
+ "is_NegPredAtom (Not x) = is_predAtom x" | "is_NegPredAtom _ = False"
+
+ definition "close_eq s = (\<lambda>predAtm p xs \<Rightarrow> s (p,xs) | Eq a b \<Rightarrow> a=b)"
+
+ lemma close_eq_predAtm[simp]: "close_eq s (predAtm p xs) \<longleftrightarrow> s (p,xs)"
+ by (auto simp: close_eq_def)
+
+ lemma close_eq_Eq[simp]: "close_eq s (Eq a b) \<longleftrightarrow> a=b"
+ by (auto simp: close_eq_def)
+
+
+ abbreviation entail_eq :: "state \<Rightarrow> object atom formula \<Rightarrow> bool" (infix "\<Turnstile>\<^sub>=" 55)
+ where "entail_eq s f \<equiv> close_eq s \<Turnstile> f"
+
+
+ fun sound_opr :: "ground_action \<Rightarrow> action \<Rightarrow> bool" where
+ "sound_opr (Ground_Action pre (Effect add del)) f \<longleftrightarrow>
+ (\<forall>s. s \<Turnstile>\<^sub>= pre \<longrightarrow>
+ (\<exists>s'. f s = Some s' \<and> (\<forall>atm. is_predAtom atm \<and> atm \<notin> set del \<and> s \<Turnstile>\<^sub>= atm \<longrightarrow> s' \<Turnstile>\<^sub>= atm)
+ \<and> (\<forall>atm. is_predAtom atm \<and> atm \<notin> set add \<and> s \<Turnstile>\<^sub>= Not atm \<longrightarrow> s' \<Turnstile>\<^sub>= Not atm)
+ \<and> (\<forall>fmla. fmla \<in> set add \<longrightarrow> s' \<Turnstile>\<^sub>= fmla)
+ \<and> (\<forall>fmla. fmla \<in> set del \<and> fmla \<notin> set add \<longrightarrow> s' \<Turnstile>\<^sub>= (Not fmla))
+ ))
+ \<and> (\<forall>fmla\<in>set add. is_predAtom fmla)"
+
+ lemma sound_opr_alt:
+ "sound_opr opr f =
+ ((\<forall>s. s \<Turnstile>\<^sub>= (precondition opr) \<longrightarrow>
+ (\<exists>s'. f s = (Some s')
+ \<and> (\<forall>atm. is_predAtom atm \<and> atm \<notin> set(dels (effect opr)) \<and> s \<Turnstile>\<^sub>= atm \<longrightarrow> s' \<Turnstile>\<^sub>= atm)
+ \<and> (\<forall>atm. is_predAtom atm \<and> atm \<notin> set (adds (effect opr)) \<and> s \<Turnstile>\<^sub>= Not atm \<longrightarrow> s' \<Turnstile>\<^sub>= Not atm)
+ \<and> (\<forall>atm. atm \<in> set(adds (effect opr)) \<longrightarrow> s' \<Turnstile>\<^sub>= atm)
+ \<and> (\<forall>fmla. fmla \<in> set (dels (effect opr)) \<and> fmla \<notin> set(adds (effect opr)) \<longrightarrow> s' \<Turnstile>\<^sub>= (Not fmla))
+ \<and> (\<forall>a b. s \<Turnstile>\<^sub>= Atom (Eq a b) \<longrightarrow> s' \<Turnstile>\<^sub>= Atom (Eq a b))
+ \<and> (\<forall>a b. s \<Turnstile>\<^sub>= Not (Atom (Eq a b)) \<longrightarrow> s' \<Turnstile>\<^sub>= Not (Atom (Eq a b)))
+ ))
+ \<and> (\<forall>fmla\<in>set(adds (effect opr)). is_predAtom fmla))"
+ by (cases "(opr,f)" rule: sound_opr.cases) auto
+
+ text \<open>Definition B (v)--(vii) in Lifschitz's paper~\cite{lifschitz1987semantics}\<close>
+definition sound_system
+ :: "ground_action set
+ \<Rightarrow> world_model
+ \<Rightarrow> state
+ \<Rightarrow> (ground_action \<Rightarrow> action)
+ \<Rightarrow> bool"
+ where
+ "sound_system \<Sigma> M\<^sub>0 s\<^sub>0 f \<longleftrightarrow>
+ ((\<forall>fmla\<in>close_world M\<^sub>0. s\<^sub>0 \<Turnstile>\<^sub>= fmla)
+ \<and> wm_basic M\<^sub>0
+ \<and> (\<forall>\<alpha>\<in>\<Sigma>. sound_opr \<alpha> (f \<alpha>)))"
+
+ text \<open>Composing two actions\<close>
+ definition compose_action :: "action \<Rightarrow> action \<Rightarrow> action" where
+ "compose_action f1 f2 x = (case f2 x of Some y \<Rightarrow> f1 y | None \<Rightarrow> None)"
+
+ text \<open>Composing a list of actions\<close>
+ definition compose_actions :: "action list \<Rightarrow> action" where
+ "compose_actions fs \<equiv> fold compose_action fs Some"
+
+ text \<open>Composing a list of actions satisfies some natural lemmas: \<close>
+ lemma compose_actions_Nil[simp]:
+ "compose_actions [] = Some" unfolding compose_actions_def by auto
+
+ lemma compose_actions_Cons[simp]:
+ "f s = Some s' \<Longrightarrow> compose_actions (f#fs) s = compose_actions fs s'"
+ proof -
+ interpret monoid_add compose_action Some
+ apply unfold_locales
+ unfolding compose_action_def
+ by (auto split: option.split)
+ assume "f s = Some s'"
+ then show ?thesis
+ unfolding compose_actions_def
+ by (simp add: compose_action_def fold_plus_sum_list_rev)
+ qed
+
+ text \<open>Soundness Theorem in Lifschitz's paper~\cite{lifschitz1987semantics}.\<close>
+theorem STRIPS_sema_sound:
+ assumes "sound_system \<Sigma> M\<^sub>0 s\<^sub>0 f"
+ \<comment> \<open>For a sound system \<open>\<Sigma>\<close>\<close>
+ assumes "set \<alpha>s \<subseteq> \<Sigma>"
+ \<comment> \<open>And a plan \<open>\<alpha>s\<close>\<close>
+ assumes "ground_action_path M\<^sub>0 \<alpha>s M'"
+ \<comment> \<open>Which is accepted by the system, yielding result \<open>M'\<close>
+ (called \<open>R(\<alpha>s)\<close> in Lifschitz's paper~\cite{lifschitz1987semantics}.)\<close>
+ obtains s'
+ \<comment> \<open>We have that \<open>f(\<alpha>s)\<close> is applicable
+ in initial state, yielding state \<open>s'\<close> (called \<open>f\<^sub>\<alpha>\<^sub>s(s\<^sub>0)\<close> in Lifschitz's paper~\cite{lifschitz1987semantics}.)\<close>
+ where "compose_actions (map f \<alpha>s) s\<^sub>0 = Some s'"
+ \<comment> \<open>The result world model \<open>M'\<close> is satisfied in state \<open>s'\<close>\<close>
+ and "\<forall>fmla\<in>close_world M'. s' \<Turnstile>\<^sub>= fmla"
+proof -
+ have "(valuation M' \<Turnstile> fmla)" if "wm_basic M'" "fmla\<in>M'" for fmla
+ using that apply (induction fmla)
+ by (auto simp: valuation_def wm_basic_def split: atom.split)
+ have "\<exists>s'. compose_actions (map f \<alpha>s) s\<^sub>0 = Some s' \<and> (\<forall>fmla\<in>close_world M'. s' \<Turnstile>\<^sub>= fmla)"
+ using assms
+ proof(induction \<alpha>s arbitrary: s\<^sub>0 M\<^sub>0 )
+ case Nil
+ then show ?case by (auto simp add: close_world_def compose_action_def sound_system_def)
+ next
+ case ass: (Cons \<alpha> \<alpha>s)
+ then obtain pre add del where a: "\<alpha> = Ground_Action pre (Effect add del)"
+ using ground_action.exhaust ast_effect.exhaust by metis
+ let ?M\<^sub>1 = "execute_ground_action \<alpha> M\<^sub>0"
+ have "close_world M\<^sub>0 \<TTurnstile> precondition \<alpha>"
+ using ass(4)
+ by auto
+ moreover have s0_ent_cwM0: "\<forall>fmla\<in>(close_world M\<^sub>0). close_eq s\<^sub>0 \<Turnstile> fmla"
+ using ass(2)
+ unfolding sound_system_def
+ by auto
+ ultimately have s0_ent_alpha_precond: "close_eq s\<^sub>0 \<Turnstile> precondition \<alpha>"
+ unfolding entailment_def
+ by auto
+ then obtain s\<^sub>1 where s1: "(f \<alpha>) s\<^sub>0 = Some s\<^sub>1"
+ "(\<forall>atm. is_predAtom atm \<longrightarrow> atm \<notin> set(dels (effect \<alpha>))
+ \<longrightarrow> close_eq s\<^sub>0 \<Turnstile> atm
+ \<longrightarrow> close_eq s\<^sub>1 \<Turnstile> atm)"
+ "(\<forall>fmla. fmla \<in> set(adds (effect \<alpha>))
+ \<longrightarrow> close_eq s\<^sub>1 \<Turnstile> fmla)"
+ "(\<forall>atm. is_predAtom atm \<and> atm \<notin> set (adds (effect \<alpha>)) \<and> close_eq s\<^sub>0 \<Turnstile> Not atm \<longrightarrow> close_eq s\<^sub>1 \<Turnstile> Not atm)"
+ "(\<forall>fmla. fmla \<in> set (dels (effect \<alpha>)) \<and> fmla \<notin> set(adds (effect \<alpha>)) \<longrightarrow> close_eq s\<^sub>1 \<Turnstile> (Not fmla))"
+ "(\<forall>a b. close_eq s\<^sub>0 \<Turnstile> Atom (Eq a b) \<longrightarrow> close_eq s\<^sub>1 \<Turnstile> Atom (Eq a b))"
+ "(\<forall>a b. close_eq s\<^sub>0 \<Turnstile> Not (Atom (Eq a b)) \<longrightarrow> close_eq s\<^sub>1 \<Turnstile> Not (Atom (Eq a b)))"
+ using ass(2-4)
+ unfolding sound_system_def sound_opr_alt by force
+ have "close_eq s\<^sub>1 \<Turnstile> fmla" if "fmla\<in>close_world ?M\<^sub>1" for fmla
+ using ass(2)
+ using that s1 s0_ent_cwM0
+ unfolding sound_system_def execute_ground_action_def wm_basic_def
+ apply (auto simp: in_close_world_conv)
+ subgoal
+ by (metis (no_types, lifting) DiffE UnE a apply_effect.simps ground_action.sel(2) ast_effect.sel(1) ast_effect.sel(2) close_world_extensive subsetCE)
+ subgoal
+ by (metis Diff_iff Un_iff a ground_action.sel(2) ast_domain.apply_effect.simps ast_domain.close_eq_predAtm ast_effect.sel(1) ast_effect.sel(2) formula_semantics.simps(1) formula_semantics.simps(3) in_close_world_conv is_predAtom.simps(1))
+ done
+ moreover have "(\<forall>atm. fmla \<noteq> formula.Atom atm) \<longrightarrow> s \<Turnstile> fmla" if "fmla\<in>?M\<^sub>1" for fmla s
+ proof-
+ have alpha: "(\<forall>s.\<forall>fmla\<in>set(adds (effect \<alpha>)). \<not> is_predAtom fmla \<longrightarrow> s \<Turnstile> fmla)"
+ using ass(2,3)
+ unfolding sound_system_def ast_domain.sound_opr_alt
+ by auto
+ then show ?thesis
+ using that
+ unfolding a execute_ground_action_def
+ using ass.prems(1)[unfolded sound_system_def]
+ by(cases fmla; fastforce simp: wm_basic_def)
+
+ qed
+ moreover have "(\<forall>opr\<in>\<Sigma>. sound_opr opr (f opr))"
+ using ass(2) unfolding sound_system_def
+ by (auto simp add:)
+ moreover have "wm_basic ?M\<^sub>1"
+ using ass(2,3)
+ unfolding sound_system_def execute_ground_action_def
+ thm sound_opr.cases
+ apply (cases "(\<alpha>,f \<alpha>)" rule: sound_opr.cases)
+ apply (auto simp: wm_basic_def)
+ done
+ ultimately have "sound_system \<Sigma> ?M\<^sub>1 s\<^sub>1 f"
+ unfolding sound_system_def
+ by (auto simp: wm_basic_def)
+ from ass.IH[OF this] ass.prems obtain s' where
+ "compose_actions (map f \<alpha>s) s\<^sub>1 = Some s' \<and> (\<forall>a\<in>close_world M'. s' \<Turnstile>\<^sub>= a)"
+ by auto
+ thus ?case by (auto simp: s1(1))
+ qed
+ with that show ?thesis by blast
+qed
+
+ text \<open>More compact notation of the soundness theorem.\<close>
+ theorem STRIPS_sema_sound_compact_version:
+ "sound_system \<Sigma> M\<^sub>0 s\<^sub>0 f \<Longrightarrow> set \<alpha>s \<subseteq> \<Sigma>
+ \<Longrightarrow> ground_action_path M\<^sub>0 \<alpha>s M'
+ \<Longrightarrow> \<exists>s'. compose_actions (map f \<alpha>s) s\<^sub>0 = Some s'
+ \<and> (\<forall>fmla\<in>close_world M'. s' \<Turnstile>\<^sub>= fmla)"
+ using STRIPS_sema_sound by metis
+
+end \<comment> \<open>Context of \<open>ast_domain\<close>\<close>
+
+subsection \<open>Soundness Theorem for PDDL\<close>
+
+context wf_ast_problem begin
+
+ text \<open>Mapping world models to states\<close>
+ definition state_to_wm :: "state \<Rightarrow> world_model"
+ where "state_to_wm s = ({formula.Atom (predAtm p xs) | p xs. s (p,xs)})"
+ definition wm_to_state :: "world_model \<Rightarrow> state"
+ where "wm_to_state M = (\<lambda>(p,xs). (formula.Atom (predAtm p xs)) \<in> M)"
+
+
+ lemma wm_to_state_eq[simp]: "wm_to_state M (p, as) \<longleftrightarrow> Atom (predAtm p as) \<in> M"
+ by (auto simp: wm_to_state_def)
+
+
+
+
+ lemma wm_to_state_inv[simp]: "wm_to_state (state_to_wm s) = s"
+ by (auto simp: wm_to_state_def
+ state_to_wm_def image_def)
+
+ text \<open>Mapping AST action instances to actions\<close>
+ definition "pddl_opr_to_act g_opr s = (
+ let M = state_to_wm s in
+ if (wm_to_state (close_world M)) \<Turnstile>\<^sub>= (precondition g_opr) then
+ Some (wm_to_state (apply_effect (effect g_opr) M))
+ else
+ None)"
+
+definition "close_eq_M M = (M \<inter> {Atom (predAtm p xs) | p xs. True }) \<union> {Atom (Eq a a) | a. True} \<union> {\<^bold>\<not>(Atom (Eq a b)) | a b. a\<noteq>b}"
+
+ lemma atom_in_wm_eq:
+ "s \<Turnstile>\<^sub>= (formula.Atom atm)
+ \<longleftrightarrow> ((formula.Atom atm) \<in> close_eq_M (state_to_wm s))"
+ by (auto simp: wm_to_state_def
+ state_to_wm_def image_def close_eq_M_def close_eq_def split: atom.splits)
+
+lemma atom_in_wm_2_eq:
+ "close_eq (wm_to_state M) \<Turnstile> (formula.Atom atm)
+ \<longleftrightarrow> ((formula.Atom atm) \<in> close_eq_M M)"
+ by (auto simp: wm_to_state_def
+ state_to_wm_def image_def close_eq_def close_eq_M_def split:atom.splits)
+
+ lemma not_dels_preserved:
+ assumes "f \<notin> (set d)" " f \<in> M"
+ shows "f \<in> apply_effect (Effect a d) M"
+ using assms
+ by auto
+
+ lemma adds_satisfied:
+ assumes "f \<in> (set a)"
+ shows "f \<in> apply_effect (Effect a d) M"
+ using assms
+ by auto
+
+ lemma dels_unsatisfied:
+ assumes "f \<in> (set d)" "f \<notin> set a"
+ shows "f \<notin> apply_effect (Effect a d) M"
+ using assms
+ by auto
+
+ lemma dels_unsatisfied_2:
+ assumes "f \<in> set (dels eff)" "f \<notin> set (adds eff)"
+ shows "f \<notin> apply_effect eff M"
+ using assms
+ by (cases eff; auto)
+
+ lemma wf_fmla_atm_is_atom: "wf_fmla_atom objT f \<Longrightarrow> is_predAtom f"
+ by (cases f rule: wf_fmla_atom.cases) auto
+
+ lemma wf_act_adds_are_atoms:
+ assumes "wf_effect_inst effs" "ae \<in> set (adds effs)"
+ shows "is_predAtom ae"
+ using assms
+ by (cases effs) (auto simp: wf_fmla_atom_alt)
+
+ lemma wf_act_adds_dels_atoms:
+ assumes "wf_effect_inst effs" "ae \<in> set (dels effs)"
+ shows "is_predAtom ae"
+ using assms
+ by (cases effs) (auto simp: wf_fmla_atom_alt)
+
+ lemma to_state_close_from_state_eq[simp]: "wm_to_state (close_world (state_to_wm s)) = s"
+ by (auto simp: wm_to_state_def close_world_def
+ state_to_wm_def image_def)
+
+
+
+lemma wf_eff_pddl_ground_act_is_sound_opr:
+ assumes "wf_effect_inst (effect g_opr)"
+ shows "sound_opr g_opr ((pddl_opr_to_act g_opr))"
+ unfolding sound_opr_alt
+ apply(cases g_opr; safe)
+ subgoal for pre eff s
+ apply (rule exI[where x="wm_to_state(apply_effect eff (state_to_wm s))"])
+ apply (auto simp: pddl_opr_to_act_def Let_def split:if_splits)
+ subgoal for atm
+ by (cases eff; cases atm; auto simp: close_eq_def wm_to_state_def state_to_wm_def split: atom.splits)
+ subgoal for atm
+ by (cases eff; cases atm; auto simp: close_eq_def wm_to_state_def state_to_wm_def split: atom.splits)
+ subgoal for atm
+ using assms
+ by (cases eff; cases atm; force simp: close_eq_def wm_to_state_def state_to_wm_def split: atom.splits)
+ subgoal for fmla
+ using assms
+ by (cases eff; cases fmla rule: wf_fmla_atom.cases; force simp: close_eq_def wm_to_state_def state_to_wm_def split: atom.splits)
+ done
+ subgoal for pre eff fmla
+ using assms
+ by (cases eff; cases fmla rule: wf_fmla_atom.cases; force)
+ done
+
+
+
+ lemma wf_eff_impt_wf_eff_inst: "wf_effect objT eff \<Longrightarrow> wf_effect_inst eff"
+ by (cases eff; auto simp add: wf_fmla_atom_alt)
+
+ lemma wf_pddl_ground_act_is_sound_opr:
+ assumes "wf_ground_action g_opr"
+ shows "sound_opr g_opr (pddl_opr_to_act g_opr)"
+ using wf_eff_impt_wf_eff_inst wf_eff_pddl_ground_act_is_sound_opr assms
+ by (cases g_opr; auto)
+
+ lemma wf_action_schema_sound_inst:
+ assumes "action_params_match act args" "wf_action_schema act"
+ shows "sound_opr
+ (instantiate_action_schema act args)
+ ((pddl_opr_to_act (instantiate_action_schema act args)))"
+ using
+ wf_pddl_ground_act_is_sound_opr[
+ OF wf_instantiate_action_schema[OF assms]]
+ by blast
+
+ lemma wf_plan_act_is_sound:
+ assumes "wf_plan_action (PAction n args)"
+ shows "sound_opr
+ (instantiate_action_schema (the (resolve_action_schema n)) args)
+ ((pddl_opr_to_act
+ (instantiate_action_schema (the (resolve_action_schema n)) args)))"
+ using assms
+ using wf_action_schema_sound_inst wf_eff_pddl_ground_act_is_sound_opr
+ by (auto split: option.splits)
+
+ lemma wf_plan_act_is_sound':
+ assumes "wf_plan_action \<pi>"
+ shows "sound_opr
+ (resolve_instantiate \<pi>)
+ ((pddl_opr_to_act (resolve_instantiate \<pi>)))"
+ using assms wf_plan_act_is_sound
+ by (cases \<pi>; auto )
+
+ lemma wf_world_model_has_atoms: "f\<in>M \<Longrightarrow> wf_world_model M \<Longrightarrow> is_predAtom f"
+ using wf_fmla_atm_is_atom
+ unfolding wf_world_model_def
+ by auto
+
+ lemma wm_to_state_works_for_wf_wm_closed:
+ "wf_world_model M \<Longrightarrow> fmla\<in>close_world M \<Longrightarrow> close_eq (wm_to_state M) \<Turnstile> fmla"
+ apply (cases fmla rule: wf_fmla_atom.cases)
+ by (auto simp: wf_world_model_def close_eq_def wm_to_state_def close_world_def)
+
+ lemma wm_to_state_works_for_wf_wm: "wf_world_model M \<Longrightarrow> fmla\<in>M \<Longrightarrow> close_eq (wm_to_state M) \<Turnstile> fmla"
+ apply (cases fmla rule: wf_fmla_atom.cases)
+ by (auto simp: wf_world_model_def close_eq_def wm_to_state_def)
+
+
+
+ lemma wm_to_state_works_for_I_closed:
+ assumes "x \<in> close_world I"
+ shows "close_eq (wm_to_state I) \<Turnstile> x"
+ apply (rule wm_to_state_works_for_wf_wm_closed)
+ using assms wf_I by auto
+
+
+ lemma wf_wm_imp_basic: "wf_world_model M \<Longrightarrow> wm_basic M"
+ by (auto simp: wf_world_model_def wm_basic_def wf_fmla_atm_is_atom)
+
+theorem wf_plan_sound_system:
+ assumes "\<forall>\<pi>\<in> set \<pi>s. wf_plan_action \<pi>"
+ shows "sound_system
+ (set (map resolve_instantiate \<pi>s))
+ I
+ (wm_to_state I)
+ ((\<lambda>\<alpha>. pddl_opr_to_act \<alpha>))"
+ unfolding sound_system_def
+proof(intro conjI ballI)
+ show "close_eq(wm_to_state I) \<Turnstile> x" if "x \<in> close_world I" for x
+ using that[unfolded in_close_world_conv]
+ wm_to_state_works_for_I_closed wm_to_state_works_for_wf_wm
+ by (auto simp: wf_I)
+
+ show "wm_basic I" using wf_wm_imp_basic[OF wf_I] .
+
+ show "sound_opr \<alpha> (pddl_opr_to_act \<alpha>)" if "\<alpha> \<in> set (map resolve_instantiate \<pi>s)" for \<alpha>
+ using that
+ using wf_plan_act_is_sound' assms
+ by auto
+qed
+
+theorem wf_plan_soundness_theorem:
+ assumes "plan_action_path I \<pi>s M"
+ defines "\<alpha>s \<equiv> map (pddl_opr_to_act \<circ> resolve_instantiate) \<pi>s"
+ defines "s\<^sub>0 \<equiv> wm_to_state I"
+ shows "\<exists>s'. compose_actions \<alpha>s s\<^sub>0 = Some s' \<and> (\<forall>\<phi>\<in>close_world M. s' \<Turnstile>\<^sub>= \<phi>)"
+ apply (rule STRIPS_sema_sound)
+ apply (rule wf_plan_sound_system)
+ using assms
+ unfolding plan_action_path_def
+ by (auto simp add: image_def)
+
+end \<comment> \<open>Context of \<open>wf_ast_problem\<close>\<close>
+
+end
diff --git a/thys/AI_Planning_Languages_Semantics/Option_Monad_Add.thy b/thys/AI_Planning_Languages_Semantics/Option_Monad_Add.thy
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/Option_Monad_Add.thy
@@ -0,0 +1,101 @@
+theory Option_Monad_Add
+imports "HOL-Library.Monad_Syntax"
+begin
+ definition "oassert \<Phi> \<equiv> if \<Phi> then Some () else None"
+
+ fun omap :: "('a\<rightharpoonup>'b) \<Rightarrow> 'a list \<rightharpoonup> 'b list" where
+ "omap f [] = Some []"
+ | "omap f (x#xs) = do { y \<leftarrow> f x; ys \<leftarrow> omap f xs; Some (y#ys) }"
+
+ lemma omap_cong[fundef_cong]:
+ assumes "\<And>x. x\<in>set l' \<Longrightarrow> f x = f' x"
+ assumes "l=l'"
+ shows "omap f l = omap f' l'"
+ unfolding assms(2) using assms(1) by (induction l') (auto)
+
+ lemma assert_eq_iff[simp]:
+ "oassert \<Phi> = None \<longleftrightarrow> \<not>\<Phi>"
+ "oassert \<Phi> = Some u \<longleftrightarrow> \<Phi>"
+ unfolding oassert_def by auto
+
+ lemma omap_length[simp]: "omap f l = Some l' \<Longrightarrow> length l' = length l"
+ apply (induction l arbitrary: l')
+ apply (auto split: Option.bind_splits)
+ done
+
+ lemma omap_append[simp]: "omap f (xs@ys) = do {xs \<leftarrow> omap f xs; ys \<leftarrow> omap f ys; Some (xs@ys)}"
+ by (induction xs) (auto)
+
+
+ lemma omap_alt: "omap f l = Some l' \<longleftrightarrow> (l' = map (the o f) l \<and> (\<forall>x\<in>set l. f x \<noteq> None))"
+ apply (induction l arbitrary: l')
+ apply (auto split: Option.bind_splits)
+ done
+
+ lemma omap_alt_None: "omap f l = None \<longleftrightarrow> (\<exists>x\<in>set l. f x = None)"
+ apply (induction l)
+ apply (auto split: Option.bind_splits)
+ done
+
+ lemma omap_nth: "\<lbrakk>omap f l = Some l'; i<length l\<rbrakk> \<Longrightarrow> f (l!i) = Some (l'!i)"
+ apply (induction l arbitrary: l' i)
+ apply (auto split: Option.bind_splits simp: nth_Cons split: nat.splits)
+ done
+
+ lemma omap_eq_Nil_conv[simp]: "omap f xs = Some [] \<longleftrightarrow> xs=[]"
+ apply (cases xs)
+ apply (auto split: Option.bind_splits)
+ done
+
+ lemma omap_eq_Cons_conv[simp]: "omap f xs = Some (y#ys') \<longleftrightarrow> (\<exists>x xs'. xs=x#xs' \<and> f x = Some y \<and> omap f xs' = Some ys')"
+ apply (cases xs)
+ apply (auto split: Option.bind_splits)
+ done
+
+ lemma omap_eq_append_conv[simp]: "omap f xs = Some (ys\<^sub>1@ys\<^sub>2) \<longleftrightarrow> (\<exists>xs\<^sub>1 xs\<^sub>2. xs=xs\<^sub>1@xs\<^sub>2 \<and> omap f xs\<^sub>1 = Some ys\<^sub>1 \<and> omap f xs\<^sub>2 = Some ys\<^sub>2)"
+ apply (induction ys\<^sub>1 arbitrary: xs)
+ apply (auto 0 3 split: Option.bind_splits)
+ apply (metis append_Cons)
+ done
+
+ lemma omap_list_all2_conv: "omap f xs = Some ys \<longleftrightarrow> (list_all2 (\<lambda>x y. f x = Some y)) xs ys"
+ apply (induction xs arbitrary: ys)
+ apply (auto split: Option.bind_splits simp: )
+ apply (simp add: list_all2_Cons1)
+ apply (simp add: list_all2_Cons1)
+ apply (simp add: list_all2_Cons1)
+ apply clarsimp
+ by (metis option.inject)
+
+
+
+
+ fun omap_option where
+ "omap_option f None = Some None"
+ | "omap_option f (Some x) = do { x \<leftarrow> f x; Some (Some x) }"
+
+ lemma omap_option_conv:
+ "omap_option f xx = None \<longleftrightarrow> (\<exists>x. xx=Some x \<and> f x = None)"
+ "omap_option f xx = (Some (Some x')) \<longleftrightarrow> (\<exists>x. xx=Some x \<and> f x = Some x')"
+ "omap_option f xx = (Some None) \<longleftrightarrow> xx=None"
+ by (cases xx;auto split: Option.bind_splits)+
+
+ lemma omap_option_eq: "omap_option f x = (case x of None \<Rightarrow> Some None | Some x \<Rightarrow> do { x \<leftarrow> f x; Some (Some x) })"
+ by (auto split: option.split)
+
+ fun omap_prod where
+ "omap_prod f\<^sub>1 f\<^sub>2 (a,b) = do { a\<leftarrow>f\<^sub>1 a; b\<leftarrow>f\<^sub>2 b; Some (a,b) }"
+
+
+ (* Extend map function for datatype to option monad.
+ TODO: Show reasonable lemmas, like parametricity, etc.
+ Hopefully only depending on BNF-property of datatype
+ *)
+ definition "omap_dt setf mapf f obj \<equiv> do {
+ oassert (\<forall>x\<in>setf obj. f x \<noteq> None);
+ Some (mapf (the o f) obj)
+ }"
+
+
+
+end
diff --git a/thys/AI_Planning_Languages_Semantics/PDDL_STRIPS_Checker.thy b/thys/AI_Planning_Languages_Semantics/PDDL_STRIPS_Checker.thy
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/PDDL_STRIPS_Checker.thy
@@ -0,0 +1,406 @@
+section \<open>Executable PDDL Checker\<close>
+theory PDDL_STRIPS_Checker
+imports
+ PDDL_STRIPS_Semantics
+
+ Error_Monad_Add
+ "HOL.String"
+
+ (*"HOL-Library.Code_Char" TODO: This might lead to performance loss! CHECK! *)
+ "HOL-Library.Code_Target_Nat"
+
+ "HOL-Library.While_Combinator"
+
+ "Containers.Containers"
+begin
+
+subsection \<open>Generic DFS Reachability Checker\<close>
+text \<open>Used for subtype checks\<close>
+
+definition "E_of_succ succ \<equiv> { (u,v). v\<in>set (succ u) }"
+lemma succ_as_E: "set (succ x) = E_of_succ succ `` {x}"
+ unfolding E_of_succ_def by auto
+
+context
+ fixes succ :: "'a \<Rightarrow> 'a list"
+begin
+
+ private abbreviation (input) "E \<equiv> E_of_succ succ"
+
+
+definition "dfs_reachable D w \<equiv>
+ let (V,w,brk) = while (\<lambda>(V,w,brk). \<not>brk \<and> w\<noteq>[]) (\<lambda>(V,w,_).
+ case w of v#w \<Rightarrow>
+ if D v then (V,v#w,True)
+ else if v\<in>V then (V,w,False)
+ else
+ let V = insert v V in
+ let w = succ v @ w in
+ (V,w,False)
+ ) ({},w,False)
+ in brk"
+
+
+context
+ fixes w\<^sub>0 :: "'a list"
+ assumes finite_dfs_reachable[simp, intro!]: "finite (E\<^sup>* `` set w\<^sub>0)"
+begin
+
+ private abbreviation (input) "W\<^sub>0 \<equiv> set w\<^sub>0"
+
+definition "dfs_reachable_invar D V W brk \<longleftrightarrow>
+ W\<^sub>0 \<subseteq> W \<union> V
+ \<and> W \<union> V \<subseteq> E\<^sup>* `` W\<^sub>0
+ \<and> E``V \<subseteq> W \<union> V
+ \<and> Collect D \<inter> V = {}
+ \<and> (brk \<longrightarrow> Collect D \<inter> E\<^sup>* `` W\<^sub>0 \<noteq> {})"
+
+lemma card_decreases: "
+ \<lbrakk>finite V; y \<notin> V; dfs_reachable_invar D V (Set.insert y W) brk \<rbrakk>
+ \<Longrightarrow> card (E\<^sup>* `` W\<^sub>0 - Set.insert y V) < card (E\<^sup>* `` W\<^sub>0 - V)"
+ apply (rule psubset_card_mono)
+ apply (auto simp: dfs_reachable_invar_def)
+ done
+
+lemma all_neq_Cons_is_Nil[simp]: (* Odd term remaining in goal \<dots> *)
+ "(\<forall>y ys. x2 \<noteq> y # ys) \<longleftrightarrow> x2 = []" by (cases x2) auto
+
+lemma dfs_reachable_correct: "dfs_reachable D w\<^sub>0 \<longleftrightarrow> Collect D \<inter> E\<^sup>* `` set w\<^sub>0 \<noteq> {}"
+ unfolding dfs_reachable_def
+ apply (rule while_rule[where
+ P="\<lambda>(V,w,brk). dfs_reachable_invar D V (set w) brk \<and> finite V"
+ and r="measure (\<lambda>V. card (E\<^sup>* `` (set w\<^sub>0) - V)) <*lex*> measure length <*lex*> measure (\<lambda>True\<Rightarrow>0 | False\<Rightarrow>1)"
+ ])
+ subgoal by (auto simp: dfs_reachable_invar_def)
+ subgoal
+ apply (auto simp: neq_Nil_conv succ_as_E[of succ] split: if_splits)
+ by (auto simp: dfs_reachable_invar_def Image_iff intro: rtrancl.rtrancl_into_rtrancl)
+ subgoal by (fastforce simp: dfs_reachable_invar_def dest: Image_closed_trancl)
+ subgoal by blast
+ subgoal by (auto simp: neq_Nil_conv card_decreases)
+ done
+
+end
+
+definition "tab_succ l \<equiv> Mapping.lookup_default [] (fold (\<lambda>(u,v). Mapping.map_default u [] (Cons v)) l Mapping.empty)"
+
+
+lemma Some_eq_map_option [iff]: "(Some y = map_option f xo) = (\<exists>z. xo = Some z \<and> f z = y)"
+ by (auto simp add: map_option_case split: option.split)
+
+
+lemma tab_succ_correct: "E_of_succ (tab_succ l) = set l"
+proof -
+ have "set (Mapping.lookup_default [] (fold (\<lambda>(u,v). Mapping.map_default u [] (Cons v)) l m) u) = set l `` {u} \<union> set (Mapping.lookup_default [] m u)"
+ for m u
+ apply (induction l arbitrary: m)
+ by (auto
+ simp: Mapping.lookup_default_def Mapping.map_default_def Mapping.default_def
+ simp: lookup_map_entry' lookup_update' keys_is_none_rep Option.is_none_def
+ split: if_splits
+ )
+ from this[where m=Mapping.empty] show ?thesis
+ by (auto simp: E_of_succ_def tab_succ_def lookup_default_empty)
+qed
+
+end
+
+lemma finite_imp_finite_dfs_reachable:
+ "\<lbrakk>finite E; finite S\<rbrakk> \<Longrightarrow> finite (E\<^sup>*``S)"
+ apply (rule finite_subset[where B="S \<union> (Relation.Domain E \<union> Relation.Range E)"])
+ apply (auto simp: intro: finite_Domain finite_Range elim: rtranclE)
+ done
+
+lemma dfs_reachable_tab_succ_correct: "dfs_reachable (tab_succ l) D vs\<^sub>0 \<longleftrightarrow> Collect D \<inter> (set l)\<^sup>*``set vs\<^sub>0 \<noteq> {}"
+ apply (subst dfs_reachable_correct)
+ by (simp_all add: tab_succ_correct finite_imp_finite_dfs_reachable)
+
+
+
+subsection \<open>Implementation Refinements\<close>
+
+subsubsection \<open>Of-Type\<close>
+
+definition "of_type_impl G oT T \<equiv> (\<forall>pt\<in>set (primitives oT). dfs_reachable G ((=) pt) (primitives T))"
+
+
+fun ty_term' where
+ "ty_term' varT objT (term.VAR v) = varT v"
+| "ty_term' varT objT (term.CONST c) = Mapping.lookup objT c"
+
+lemma ty_term'_correct_aux: "ty_term' varT objT t = ty_term varT (Mapping.lookup objT) t"
+ by (cases t) auto
+
+lemma ty_term'_correct[simp]: "ty_term' varT objT = ty_term varT (Mapping.lookup objT)"
+ using ty_term'_correct_aux by auto
+
+context ast_domain begin
+
+ definition "of_type1 pt T \<longleftrightarrow> pt \<in> subtype_rel\<^sup>* `` set (primitives T)"
+
+ lemma of_type_refine1: "of_type oT T \<longleftrightarrow> (\<forall>pt\<in>set (primitives oT). of_type1 pt T)"
+ unfolding of_type_def of_type1_def by auto
+
+ definition "STG \<equiv> (tab_succ (map subtype_edge (types D)))"
+
+ lemma subtype_rel_impl: "subtype_rel = E_of_succ (tab_succ (map subtype_edge (types D)))"
+ by (simp add: tab_succ_correct subtype_rel_def)
+
+ lemma of_type1_impl: "of_type1 pt T \<longleftrightarrow> dfs_reachable (tab_succ (map subtype_edge (types D))) ((=)pt) (primitives T)"
+ by (simp add: subtype_rel_impl of_type1_def dfs_reachable_tab_succ_correct tab_succ_correct)
+
+ lemma of_type_impl_correct: "of_type_impl STG oT T \<longleftrightarrow> of_type oT T"
+ unfolding of_type1_impl STG_def of_type_impl_def of_type_refine1 ..
+
+ definition mp_constT :: "(object, type) mapping" where
+ "mp_constT = Mapping.of_alist (consts D)"
+
+ lemma mp_objT_correct[simp]: "Mapping.lookup mp_constT = constT"
+ unfolding mp_constT_def constT_def
+ by transfer (simp add: Map_To_Mapping.map_apply_def)
+
+
+
+
+
+
+ text \<open>Lifting the subtype-graph through wf-checker\<close>
+ context
+ fixes ty_ent :: "'ent \<rightharpoonup> type" \<comment> \<open>Entity's type, None if invalid\<close>
+ begin
+
+ definition "is_of_type' stg v T \<longleftrightarrow> (
+ case ty_ent v of
+ Some vT \<Rightarrow> of_type_impl stg vT T
+ | None \<Rightarrow> False)"
+
+ lemma is_of_type'_correct: "is_of_type' STG v T = is_of_type ty_ent v T"
+ unfolding is_of_type'_def is_of_type_def of_type_impl_correct ..
+
+ fun wf_pred_atom' where "wf_pred_atom' stg (p,vs) \<longleftrightarrow> (case sig p of
+ None \<Rightarrow> False
+ | Some Ts \<Rightarrow> list_all2 (is_of_type' stg) vs Ts)"
+
+ lemma wf_pred_atom'_correct: "wf_pred_atom' STG pvs = wf_pred_atom ty_ent pvs"
+ by (cases pvs) (auto simp: is_of_type'_correct[abs_def] split:option.split)
+
+ fun wf_atom' :: "_ \<Rightarrow> 'ent atom \<Rightarrow> bool" where
+ "wf_atom' stg (atom.predAtm p vs) \<longleftrightarrow> wf_pred_atom' stg (p,vs)"
+ | "wf_atom' stg (atom.Eq a b) = (ty_ent a \<noteq> None \<and> ty_ent b \<noteq> None)"
+
+ lemma wf_atom'_correct: "wf_atom' STG a = wf_atom ty_ent a"
+ by (cases a) (auto simp: wf_pred_atom'_correct is_of_type'_correct[abs_def] split: option.splits)
+
+ fun wf_fmla' :: "_ \<Rightarrow> ('ent atom) formula \<Rightarrow> bool" where
+ "wf_fmla' stg (Atom a) \<longleftrightarrow> wf_atom' stg a"
+ | "wf_fmla' stg \<bottom> \<longleftrightarrow> True"
+ | "wf_fmla' stg (\<phi>1 \<^bold>\<and> \<phi>2) \<longleftrightarrow> (wf_fmla' stg \<phi>1 \<and> wf_fmla' stg \<phi>2)"
+ | "wf_fmla' stg (\<phi>1 \<^bold>\<or> \<phi>2) \<longleftrightarrow> (wf_fmla' stg \<phi>1 \<and> wf_fmla' stg \<phi>2)"
+ | "wf_fmla' stg (\<phi>1 \<^bold>\<rightarrow> \<phi>2) \<longleftrightarrow> (wf_fmla' stg \<phi>1 \<and> wf_fmla' stg \<phi>2)"
+ | "wf_fmla' stg (\<^bold>\<not>\<phi>) \<longleftrightarrow> wf_fmla' stg \<phi>"
+
+ lemma wf_fmla'_correct: "wf_fmla' STG \<phi> \<longleftrightarrow> wf_fmla ty_ent \<phi>"
+ by (induction \<phi> rule: wf_fmla.induct) (auto simp: wf_atom'_correct)
+
+ fun wf_fmla_atom1' where
+ "wf_fmla_atom1' stg (Atom (predAtm p vs)) \<longleftrightarrow> wf_pred_atom' stg (p,vs)"
+ | "wf_fmla_atom1' stg _ \<longleftrightarrow> False"
+
+ lemma wf_fmla_atom1'_correct: "wf_fmla_atom1' STG \<phi> = wf_fmla_atom ty_ent \<phi>"
+ by (cases \<phi> rule: wf_fmla_atom.cases) (auto
+ simp: wf_atom'_correct is_of_type'_correct[abs_def] split: option.splits)
+
+ fun wf_effect' where
+ "wf_effect' stg (Effect a d) \<longleftrightarrow>
+ (\<forall>ae\<in>set a. wf_fmla_atom1' stg ae)
+ \<and> (\<forall>de\<in>set d. wf_fmla_atom1' stg de)"
+
+ lemma wf_effect'_correct: "wf_effect' STG e = wf_effect ty_ent e"
+ by (cases e) (auto simp: wf_fmla_atom1'_correct)
+
+ end \<comment> \<open>Context fixing \<open>ty_ent\<close>\<close>
+
+ fun wf_action_schema' :: "_ \<Rightarrow> _ \<Rightarrow> ast_action_schema \<Rightarrow> bool" where
+ "wf_action_schema' stg conT (Action_Schema n params pre eff) \<longleftrightarrow> (
+ let
+ tyv = ty_term' (map_of params) conT
+ in
+ distinct (map fst params)
+ \<and> wf_fmla' tyv stg pre
+ \<and> wf_effect' tyv stg eff)"
+
+ lemma wf_action_schema'_correct: "wf_action_schema' STG mp_constT s = wf_action_schema s"
+ by (cases s) (auto simp: wf_fmla'_correct wf_effect'_correct)
+
+ definition wf_domain' :: "_ \<Rightarrow> _ \<Rightarrow> bool" where
+ "wf_domain' stg conT \<equiv>
+ wf_types
+ \<and> distinct (map (predicate_decl.pred) (predicates D))
+ \<and> (\<forall>p\<in>set (predicates D). wf_predicate_decl p)
+ \<and> distinct (map fst (consts D))
+ \<and> (\<forall>(n,T)\<in>set (consts D). wf_type T)
+ \<and> distinct (map ast_action_schema.name (actions D))
+ \<and> (\<forall>a\<in>set (actions D). wf_action_schema' stg conT a)
+ "
+
+ lemma wf_domain'_correct: "wf_domain' STG mp_constT = wf_domain"
+ unfolding wf_domain_def wf_domain'_def
+ by (auto simp: wf_action_schema'_correct)
+
+
+end \<comment> \<open>Context of \<open>ast_domain\<close>\<close>
+
+subsubsection \<open>Application of Effects\<close>
+
+context ast_domain begin
+ text \<open>We implement the application of an effect by explicit iteration over
+ the additions and deletions\<close>
+ fun apply_effect_exec
+ :: "object ast_effect \<Rightarrow> world_model \<Rightarrow> world_model"
+ where
+ "apply_effect_exec (Effect a d) s
+ = fold (\<lambda>add s. Set.insert add s) a
+ (fold (\<lambda>del s. Set.remove del s) d s)"
+
+ lemma apply_effect_exec_refine[simp]:
+ "apply_effect_exec (Effect (a) (d)) s
+ = apply_effect (Effect (a) (d)) s"
+ proof(induction a arbitrary: s)
+ case Nil
+ then show ?case
+ proof(induction d arbitrary: s)
+ case Nil
+ then show ?case by auto
+ next
+ case (Cons a d)
+ then show ?case
+ by (auto simp add: image_def)
+ qed
+ next
+ case (Cons a a)
+ then show ?case
+ proof(induction d arbitrary: s)
+ case Nil
+ then show ?case by (auto; metis Set.insert_def sup_assoc insert_iff)
+ next
+ case (Cons a d)
+ then show ?case
+ by (auto simp: Un_commute minus_set_fold union_set_fold)
+ qed
+ qed
+
+ lemmas apply_effect_eq_impl_eq
+ = apply_effect_exec_refine[symmetric, unfolded apply_effect_exec.simps]
+
+end \<comment> \<open>Context of \<open>ast_domain\<close>\<close>
+
+subsubsection \<open>Well-Formedness\<close>
+
+context ast_problem begin
+
+ text \<open> We start by defining a mapping from objects to types. The container
+ framework will generate efficient, red-black tree based code for that
+ later. \<close>
+
+ type_synonym objT = "(object, type) mapping"
+
+ definition mp_objT :: "(object, type) mapping" where
+ "mp_objT = Mapping.of_alist (consts D @ objects P)"
+
+ lemma mp_objT_correct[simp]: "Mapping.lookup mp_objT = objT"
+ unfolding mp_objT_def objT_alt
+ by transfer (simp add: Map_To_Mapping.map_apply_def)
+
+ text \<open>We refine the typecheck to use the mapping\<close>
+
+ definition "is_obj_of_type_impl stg mp n T = (
+ case Mapping.lookup mp n of None \<Rightarrow> False | Some oT \<Rightarrow> of_type_impl stg oT T
+ )"
+
+ lemma is_obj_of_type_impl_correct[simp]:
+ "is_obj_of_type_impl STG mp_objT = is_obj_of_type"
+ apply (intro ext)
+ apply (auto simp: is_obj_of_type_impl_def is_obj_of_type_def of_type_impl_correct split: option.split)
+ done
+
+ text \<open>We refine the well-formedness checks to use the mapping\<close>
+
+ definition wf_fact' :: "objT \<Rightarrow> _ \<Rightarrow> fact \<Rightarrow> bool"
+ where
+ "wf_fact' ot stg \<equiv> wf_pred_atom' (Mapping.lookup ot) stg"
+
+ lemma wf_fact'_correct[simp]: "wf_fact' mp_objT STG = wf_fact"
+ by (auto simp: wf_fact'_def wf_fact_def wf_pred_atom'_correct[abs_def])
+
+
+ definition "wf_fmla_atom2' mp stg f
+ = (case f of formula.Atom (predAtm p vs) \<Rightarrow> (wf_fact' mp stg (p,vs)) | _ \<Rightarrow> False)"
+
+ lemma wf_fmla_atom2'_correct[simp]:
+ "wf_fmla_atom2' mp_objT STG \<phi> = wf_fmla_atom objT \<phi>"
+ apply (cases \<phi> rule: wf_fmla_atom.cases)
+ by (auto simp: wf_fmla_atom2'_def wf_fact_def split: option.splits)
+
+ definition "wf_problem' stg conT mp \<equiv>
+ wf_domain' stg conT
+ \<and> distinct (map fst (objects P) @ map fst (consts D))
+ \<and> (\<forall>(n,T)\<in>set (objects P). wf_type T)
+ \<and> distinct (init P)
+ \<and> (\<forall>f\<in>set (init P). wf_fmla_atom2' mp stg f)
+ \<and> wf_fmla' (Mapping.lookup mp) stg (goal P)"
+
+ lemma wf_problem'_correct:
+ "wf_problem' STG mp_constT mp_objT = wf_problem"
+ unfolding wf_problem_def wf_problem'_def wf_world_model_def
+ by (auto simp: wf_domain'_correct wf_fmla'_correct)
+
+
+ text \<open>Instantiating actions will yield well-founded effects.
+ Corollary of @{thm wf_instantiate_action_schema}.\<close>
+ lemma wf_effect_inst_weak:
+ fixes a args
+ defines "ai \<equiv> instantiate_action_schema a args"
+ assumes A: "action_params_match a args"
+ "wf_action_schema a"
+ shows "wf_effect_inst (effect ai)"
+ using wf_instantiate_action_schema[OF A] unfolding ai_def[symmetric]
+ by (cases ai) (auto simp: wf_effect_inst_alt)
+
+
+end \<comment> \<open>Context of \<open>ast_problem\<close>\<close>
+
+
+context wf_ast_domain begin
+ text \<open>Resolving an action yields a well-founded action schema.\<close>
+ (* TODO: This must be implicitly proved when showing that plan execution
+ preserves wf. Try to remove this redundancy!*)
+ lemma resolve_action_wf:
+ assumes "resolve_action_schema n = Some a"
+ shows "wf_action_schema a"
+ proof -
+ from wf_domain have
+ X1: "distinct (map ast_action_schema.name (actions D))"
+ and X2: "\<forall>a\<in>set (actions D). wf_action_schema a"
+ unfolding wf_domain_def by auto
+
+ show ?thesis
+ using assms unfolding resolve_action_schema_def
+ by (auto simp add: index_by_eq_Some_eq[OF X1] X2)
+ qed
+
+end \<comment> \<open>Context of \<open>ast_domain\<close>\<close>
+
+
+subsubsection \<open>Execution of Plan Actions\<close>
+
+text \<open>We will perform two refinement steps, to summarize redundant operations\<close>
+
+text \<open>We first lift action schema lookup into the error monad. \<close>
+context ast_domain begin
+ definition "resolve_action_schemaE n \<equiv>
+ lift_opt
+ (resolve_action_schema n)
+ (ERR (shows ''No such action schema '' o shows n))"
+end \<comment> \<open>Context of \<open>ast_domain\<close>\<close>
+
+end \<comment> \<open>Theory\<close>
diff --git a/thys/AI_Planning_Languages_Semantics/PDDL_STRIPS_Semantics.thy b/thys/AI_Planning_Languages_Semantics/PDDL_STRIPS_Semantics.thy
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/PDDL_STRIPS_Semantics.thy
@@ -0,0 +1,969 @@
+section \<open>PDDL and STRIPS Semantics\<close>
+theory PDDL_STRIPS_Semantics
+imports
+ "Propositional_Proof_Systems.Formulas"
+ "Propositional_Proof_Systems.Sema"
+ "Propositional_Proof_Systems.Consistency"
+ "Automatic_Refinement.Misc"
+ "Automatic_Refinement.Refine_Util"
+begin
+no_notation insert ("_ \<triangleright> _" [56,55] 55)
+
+subsection \<open>Utility Functions\<close>
+definition "index_by f l \<equiv> map_of (map (\<lambda>x. (f x,x)) l)"
+
+lemma index_by_eq_Some_eq[simp]:
+ assumes "distinct (map f l)"
+ shows "index_by f l n = Some x \<longleftrightarrow> (x\<in>set l \<and> f x = n)"
+ unfolding index_by_def
+ using assms
+ by (auto simp: o_def)
+
+lemma index_by_eq_SomeD:
+ shows "index_by f l n = Some x \<Longrightarrow> (x\<in>set l \<and> f x = n)"
+ unfolding index_by_def
+ by (auto dest: map_of_SomeD)
+
+
+lemma lookup_zip_idx_eq:
+ assumes "length params = length args"
+ assumes "i<length args"
+ assumes "distinct params"
+ assumes "k = params ! i"
+ shows "map_of (zip params args) k = Some (args ! i)"
+ using assms
+ by (auto simp: in_set_conv_nth)
+
+lemma rtrancl_image_idem[simp]: "R\<^sup>* `` R\<^sup>* `` s = R\<^sup>* `` s"
+ by (metis relcomp_Image rtrancl_idemp_self_comp)
+
+
+subsection \<open>Abstract Syntax\<close>
+
+subsubsection \<open>Generic Entities\<close>
+type_synonym name = string
+
+datatype predicate = Pred (name: name)
+
+text \<open>Some of the AST entities are defined over a polymorphic \<open>'val\<close> type,
+ which gets either instantiated by variables (for domains)
+ or objects (for problems).
+\<close>
+
+text \<open>An atom is either a predicate with arguments, or an equality statement.\<close>
+datatype 'ent atom = predAtm (predicate: predicate) (arguments: "'ent list")
+ | Eq (lhs: 'ent) (rhs: 'ent)
+
+text \<open>A type is a list of primitive type names.
+ To model a primitive type, we use a singleton list.\<close>
+datatype type = Either (primitives: "name list")
+
+text \<open>An effect contains a list of values to be added, and a list of values
+ to be removed.\<close>
+datatype 'ent ast_effect = Effect (adds: "('ent atom formula) list") (dels: "('ent atom formula) list")
+
+text \<open>Variables are identified by their names.\<close>
+datatype variable = varname: Var name
+text \<open>Objects and constants are identified by their names\<close>
+datatype object = name: Obj name
+
+datatype "term" = VAR variable | CONST object
+hide_const (open) VAR CONST \<comment> \<open>Refer to constructors by qualified names only\<close>
+
+
+
+
+subsubsection \<open>Domains\<close>
+
+text \<open>An action schema has a name, a typed parameter list, a precondition,
+ and an effect.\<close>
+datatype ast_action_schema = Action_Schema
+ (name: name)
+ (parameters: "(variable \<times> type) list")
+ (precondition: "term atom formula")
+ (effect: "term ast_effect")
+
+text \<open>A predicate declaration contains the predicate's name and its
+ argument types.\<close>
+datatype predicate_decl = PredDecl
+ (pred: predicate)
+ (argTs: "type list")
+
+text \<open>A domain contains the declarations of primitive types, predicates,
+ and action schemas.\<close>
+datatype ast_domain = Domain
+ (types: "(name \<times> name) list") \<comment> \<open> \<open>(type, supertype)\<close> declarations. \<close>
+ (predicates: "predicate_decl list")
+ ("consts": "(object \<times> type) list")
+ (actions: "ast_action_schema list")
+
+subsubsection \<open>Problems\<close>
+
+
+text \<open>A fact is a predicate applied to objects.\<close>
+type_synonym fact = "predicate \<times> object list"
+
+text \<open>A problem consists of a domain, a list of objects,
+ a description of the initial state, and a description of the goal state. \<close>
+datatype ast_problem = Problem
+ (domain: ast_domain)
+ (objects: "(object \<times> type) list")
+ (init: "object atom formula list")
+ (goal: "object atom formula")
+
+
+subsubsection \<open>Plans\<close>
+datatype plan_action = PAction
+ (name: name)
+ (arguments: "object list")
+
+type_synonym plan = "plan_action list"
+
+subsubsection \<open>Ground Actions\<close>
+text \<open>The following datatype represents an action scheme that has been
+ instantiated by replacing the arguments with concrete objects,
+ also called ground action.
+\<close>
+datatype ground_action = Ground_Action
+ (precondition: "(object atom) formula")
+ (effect: "object ast_effect")
+
+
+
+subsection \<open>Closed-World Assumption, Equality, and Negation\<close>
+ text \<open>Discriminator for atomic predicate formulas.\<close>
+ fun is_predAtom where
+ "is_predAtom (Atom (predAtm _ _)) = True" | "is_predAtom _ = False"
+
+
+ text \<open>The world model is a set of (atomic) formulas\<close>
+ type_synonym world_model = "object atom formula set"
+
+ text \<open>It is basic, if it only contains atoms\<close>
+ definition "wm_basic M \<equiv> \<forall>a\<in>M. is_predAtom a"
+
+ text \<open>A valuation extracted from the atoms of the world model\<close>
+ definition valuation :: "world_model \<Rightarrow> object atom valuation"
+ where "valuation M \<equiv> \<lambda>predAtm p xs \<Rightarrow> Atom (predAtm p xs) \<in> M | Eq a b \<Rightarrow> a=b"
+
+ text \<open>Augment a world model by adding negated versions of all atoms
+ not contained in it, as well as interpretations of equality.\<close>
+ definition close_world :: "world_model \<Rightarrow> world_model" where "close_world M =
+ M \<union> {\<^bold>\<not>(Atom (predAtm p as)) | p as. Atom (predAtm p as) \<notin> M}
+ \<union> {Atom (Eq a a) | a. True} \<union> {\<^bold>\<not>(Atom (Eq a b)) | a b. a\<noteq>b}"
+
+ definition "close_neg M \<equiv> M \<union> {\<^bold>\<not>(Atom a) | a. Atom a \<notin> M}"
+ lemma "wm_basic M \<Longrightarrow> close_world M = close_neg (M \<union> {Atom (Eq a a) | a. True})"
+ unfolding close_world_def close_neg_def wm_basic_def
+ apply clarsimp
+ apply (auto 0 3)
+ by (metis atom.exhaust)
+
+
+ abbreviation cw_entailment (infix "\<^sup>c\<TTurnstile>\<^sub>=" 53) where
+ "M \<^sup>c\<TTurnstile>\<^sub>= \<phi> \<equiv> close_world M \<TTurnstile> \<phi>"
+
+
+ lemma
+ close_world_extensive: "M \<subseteq> close_world M" and
+ close_world_idem[simp]: "close_world (close_world M) = close_world M"
+ by (auto simp: close_world_def)
+
+ lemma in_close_world_conv:
+ "\<phi> \<in> close_world M \<longleftrightarrow> (
+ \<phi>\<in>M
+ \<or> (\<exists>p as. \<phi>=\<^bold>\<not>(Atom (predAtm p as)) \<and> Atom (predAtm p as)\<notin>M)
+ \<or> (\<exists>a. \<phi>=Atom (Eq a a))
+ \<or> (\<exists>a b. \<phi>=\<^bold>\<not>(Atom (Eq a b)) \<and> a\<noteq>b)
+ )"
+ by (auto simp: close_world_def)
+
+ lemma valuation_aux_1:
+ fixes M :: world_model and \<phi> :: "object atom formula"
+ defines "C \<equiv> close_world M"
+ assumes A: "\<forall>\<phi>\<in>C. \<A> \<Turnstile> \<phi>"
+ shows "\<A> = valuation M"
+ using A unfolding C_def
+ apply -
+ apply (auto simp: in_close_world_conv valuation_def Ball_def intro!: ext split: atom.split)
+ apply (metis formula_semantics.simps(1) formula_semantics.simps(3))
+ apply (metis formula_semantics.simps(1) formula_semantics.simps(3))
+ by (metis atom.collapse(2) formula_semantics.simps(1) is_predAtm_def)
+
+
+
+ lemma valuation_aux_2:
+ assumes "wm_basic M"
+ shows "(\<forall>G\<in>close_world M. valuation M \<Turnstile> G)"
+ using assms unfolding wm_basic_def
+ by (force simp: in_close_world_conv valuation_def elim: is_predAtom.elims)
+
+ lemma val_imp_close_world: "valuation M \<Turnstile> \<phi> \<Longrightarrow> M \<^sup>c\<TTurnstile>\<^sub>= \<phi>"
+ unfolding entailment_def
+ using valuation_aux_1
+ by blast
+
+ lemma close_world_imp_val:
+ "wm_basic M \<Longrightarrow> M \<^sup>c\<TTurnstile>\<^sub>= \<phi> \<Longrightarrow> valuation M \<Turnstile> \<phi>"
+ unfolding entailment_def using valuation_aux_2 by blast
+
+ text \<open>Main theorem of this section:
+ If a world model \<open>M\<close> contains only atoms, its induced valuation
+ satisfies a formula \<open>\<phi>\<close> if and only if the closure of \<open>M\<close> entails \<open>\<phi>\<close>.
+
+ Note that there are no syntactic restrictions on \<open>\<phi>\<close>,
+ in particular, \<open>\<phi>\<close> may contain negation.
+ \<close>
+ theorem valuation_iff_close_world:
+ assumes "wm_basic M"
+ shows "valuation M \<Turnstile> \<phi> \<longleftrightarrow> M \<^sup>c\<TTurnstile>\<^sub>= \<phi>"
+ using assms val_imp_close_world close_world_imp_val by blast
+
+
+subsubsection \<open>Proper Generalization\<close>
+text \<open>Adding negation and equality is a proper generalization of the
+ case without negation and equality\<close>
+
+fun is_STRIPS_fmla :: "'ent atom formula \<Rightarrow> bool" where
+ "is_STRIPS_fmla (Atom (predAtm _ _)) \<longleftrightarrow> True"
+| "is_STRIPS_fmla (\<bottom>) \<longleftrightarrow> True"
+| "is_STRIPS_fmla (\<phi>\<^sub>1 \<^bold>\<and> \<phi>\<^sub>2) \<longleftrightarrow> is_STRIPS_fmla \<phi>\<^sub>1 \<and> is_STRIPS_fmla \<phi>\<^sub>2"
+| "is_STRIPS_fmla (\<phi>\<^sub>1 \<^bold>\<or> \<phi>\<^sub>2) \<longleftrightarrow> is_STRIPS_fmla \<phi>\<^sub>1 \<and> is_STRIPS_fmla \<phi>\<^sub>2"
+| "is_STRIPS_fmla (\<^bold>\<not>\<bottom>) \<longleftrightarrow> True"
+| "is_STRIPS_fmla _ \<longleftrightarrow> False"
+
+lemma aux1: "\<lbrakk>wm_basic M; is_STRIPS_fmla \<phi>; valuation M \<Turnstile> \<phi>; \<forall>G\<in>M. \<A> \<Turnstile> G\<rbrakk> \<Longrightarrow> \<A> \<Turnstile> \<phi>"
+ apply(induction \<phi> rule: is_STRIPS_fmla.induct)
+ by (auto simp: valuation_def)
+
+lemma aux2: "\<lbrakk>wm_basic M; is_STRIPS_fmla \<phi>; \<forall>\<A>. (\<forall>G\<in>M. \<A> \<Turnstile> G) \<longrightarrow> \<A> \<Turnstile> \<phi>\<rbrakk> \<Longrightarrow> valuation M \<Turnstile> \<phi>"
+ apply(induction \<phi> rule: is_STRIPS_fmla.induct)
+ apply simp_all
+ apply (metis in_close_world_conv valuation_aux_2)
+ using in_close_world_conv valuation_aux_2 apply blast
+ using in_close_world_conv valuation_aux_2 by auto
+
+
+lemma valuation_iff_STRIPS:
+ assumes "wm_basic M"
+ assumes "is_STRIPS_fmla \<phi>"
+ shows "valuation M \<Turnstile> \<phi> \<longleftrightarrow> M \<TTurnstile> \<phi>"
+proof -
+ have aux1: "\<And>\<A>. \<lbrakk>valuation M \<Turnstile> \<phi>; \<forall>G\<in>M. \<A> \<Turnstile> G\<rbrakk> \<Longrightarrow> \<A> \<Turnstile> \<phi>"
+ using assms apply(induction \<phi> rule: is_STRIPS_fmla.induct)
+ by (auto simp: valuation_def)
+ have aux2: "\<lbrakk>\<forall>\<A>. (\<forall>G\<in>M. \<A> \<Turnstile> G) \<longrightarrow> \<A> \<Turnstile> \<phi>\<rbrakk> \<Longrightarrow> valuation M \<Turnstile> \<phi>"
+ using assms
+ apply(induction \<phi> rule: is_STRIPS_fmla.induct)
+ apply simp_all
+ apply (metis in_close_world_conv valuation_aux_2)
+ using in_close_world_conv valuation_aux_2 apply blast
+ using in_close_world_conv valuation_aux_2 by auto
+ show ?thesis
+ by (auto simp: entailment_def intro: aux1 aux2)
+qed
+
+text \<open>Our extension to negation and equality is a proper generalization of the
+ standard STRIPS semantics for formula without negation and equality\<close>
+theorem proper_STRIPS_generalization:
+ "\<lbrakk>wm_basic M; is_STRIPS_fmla \<phi>\<rbrakk> \<Longrightarrow> M \<^sup>c\<TTurnstile>\<^sub>= \<phi> \<longleftrightarrow> M \<TTurnstile> \<phi>"
+ by (simp add: valuation_iff_close_world[symmetric] valuation_iff_STRIPS)
+
+subsection \<open>STRIPS Semantics\<close>
+
+text \<open>For this section, we fix a domain \<open>D\<close>, using Isabelle's
+ locale mechanism.\<close>
+locale ast_domain =
+ fixes D :: ast_domain
+begin
+ text \<open>It seems to be agreed upon that, in case of a contradictory effect,
+ addition overrides deletion. We model this behaviour by first executing
+ the deletions, and then the additions.\<close>
+ fun apply_effect :: "object ast_effect \<Rightarrow> world_model \<Rightarrow> world_model"
+ where
+ "apply_effect (Effect a d) s = (s - set d) \<union> (set a)"
+
+ text \<open>Execute a ground action\<close>
+ definition execute_ground_action :: "ground_action \<Rightarrow> world_model \<Rightarrow> world_model"
+ where
+ "execute_ground_action a M = apply_effect (effect a) M"
+
+ text \<open>Predicate to model that the given list of action instances is
+ executable, and transforms an initial world model \<open>M\<close> into a final
+ model \<open>M'\<close>.
+
+ Note that this definition over the list structure is more convenient in HOL
+ than to explicitly define an indexed sequence \<open>M\<^sub>0\<dots>M\<^sub>N\<close> of intermediate world
+ models, as done in [Lif87].
+ \<close>
+ fun ground_action_path
+ :: "world_model \<Rightarrow> ground_action list \<Rightarrow> world_model \<Rightarrow> bool"
+ where
+ "ground_action_path M [] M' \<longleftrightarrow> (M = M')"
+ | "ground_action_path M (\<alpha>#\<alpha>s) M' \<longleftrightarrow> M \<^sup>c\<TTurnstile>\<^sub>= precondition \<alpha>
+ \<and> ground_action_path (execute_ground_action \<alpha> M) \<alpha>s M'"
+
+ text \<open>Function equations as presented in paper,
+ with inlined @{const execute_ground_action}.\<close>
+ lemma ground_action_path_in_paper:
+ "ground_action_path M [] M' \<longleftrightarrow> (M = M')"
+ "ground_action_path M (\<alpha>#\<alpha>s) M' \<longleftrightarrow> M \<^sup>c\<TTurnstile>\<^sub>= precondition \<alpha>
+ \<and> (ground_action_path (apply_effect (effect \<alpha>) M) \<alpha>s M')"
+ by (auto simp: execute_ground_action_def)
+
+end \<comment> \<open>Context of \<open>ast_domain\<close>\<close>
+
+
+
+subsection \<open>Well-Formedness of PDDL\<close>
+
+(* Well-formedness *)
+
+(*
+ Compute signature: predicate/arity
+ Check that all atoms (schemas and facts) satisfy signature
+
+ for action:
+ Check that used parameters \<subseteq> declared parameters
+
+ for init/goal: Check that facts only use declared objects
+*)
+
+
+fun ty_term where
+ "ty_term varT objT (term.VAR v) = varT v"
+| "ty_term varT objT (term.CONST c) = objT c"
+
+
+lemma ty_term_mono: "varT \<subseteq>\<^sub>m varT' \<Longrightarrow> objT \<subseteq>\<^sub>m objT' \<Longrightarrow>
+ ty_term varT objT \<subseteq>\<^sub>m ty_term varT' objT'"
+ apply (rule map_leI)
+ subgoal for x v
+ apply (cases x)
+ apply (auto dest: map_leD)
+ done
+ done
+
+
+context ast_domain begin
+
+ text \<open>The signature is a partial function that maps the predicates
+ of the domain to lists of argument types.\<close>
+ definition sig :: "predicate \<rightharpoonup> type list" where
+ "sig \<equiv> map_of (map (\<lambda>PredDecl p n \<Rightarrow> (p,n)) (predicates D))"
+
+ text \<open>We use a flat subtype hierarchy, where every type is a subtype
+ of object, and there are no other subtype relations.
+
+ Note that we do not need to restrict this relation to declared types,
+ as we will explicitly ensure that all types used in the problem are
+ declared.
+ \<close>
+
+ fun subtype_edge where
+ "subtype_edge (ty,superty) = (superty,ty)"
+
+ definition "subtype_rel \<equiv> set (map subtype_edge (types D))"
+
+ (*
+ definition "subtype_rel \<equiv> {''object''}\<times>UNIV"
+ *)
+
+ definition of_type :: "type \<Rightarrow> type \<Rightarrow> bool" where
+ "of_type oT T \<equiv> set (primitives oT) \<subseteq> subtype_rel\<^sup>* `` set (primitives T)"
+ text \<open>This checks that every primitive on the LHS is contained in or a
+ subtype of a primitive on the RHS\<close>
+
+
+ text \<open>For the next few definitions, we fix a partial function that maps
+ a polymorphic entity type @{typ "'e"} to types. An entity can be
+ instantiated by variables or objects later.\<close>
+ context
+ fixes ty_ent :: "'ent \<rightharpoonup> type" \<comment> \<open>Entity's type, None if invalid\<close>
+ begin
+
+ text \<open>Checks whether an entity has a given type\<close>
+ definition is_of_type :: "'ent \<Rightarrow> type \<Rightarrow> bool" where
+ "is_of_type v T \<longleftrightarrow> (
+ case ty_ent v of
+ Some vT \<Rightarrow> of_type vT T
+ | None \<Rightarrow> False)"
+
+ fun wf_pred_atom :: "predicate \<times> 'ent list \<Rightarrow> bool" where
+ "wf_pred_atom (p,vs) \<longleftrightarrow> (
+ case sig p of
+ None \<Rightarrow> False
+ | Some Ts \<Rightarrow> list_all2 is_of_type vs Ts)"
+
+ text \<open>Predicate-atoms are well-formed if their arguments match the
+ signature, equalities are well-formed if the arguments are valid
+ objects (have a type).
+
+ TODO: We could check that types may actually overlap
+ \<close>
+ fun wf_atom :: "'ent atom \<Rightarrow> bool" where
+ "wf_atom (predAtm p vs) \<longleftrightarrow> wf_pred_atom (p,vs)"
+ | "wf_atom (Eq a b) \<longleftrightarrow> ty_ent a \<noteq> None \<and> ty_ent b \<noteq> None"
+
+ text \<open>A formula is well-formed if it consists of valid atoms,
+ and does not contain negations, except for the encoding \<open>\<^bold>\<not>\<bottom>\<close> of true.
+ \<close>
+ fun wf_fmla :: "('ent atom) formula \<Rightarrow> bool" where
+ "wf_fmla (Atom a) \<longleftrightarrow> wf_atom a"
+ | "wf_fmla (\<bottom>) \<longleftrightarrow> True"
+ | "wf_fmla (\<phi>1 \<^bold>\<and> \<phi>2) \<longleftrightarrow> (wf_fmla \<phi>1 \<and> wf_fmla \<phi>2)"
+ | "wf_fmla (\<phi>1 \<^bold>\<or> \<phi>2) \<longleftrightarrow> (wf_fmla \<phi>1 \<and> wf_fmla \<phi>2)"
+ | "wf_fmla (\<^bold>\<not>\<phi>) \<longleftrightarrow> wf_fmla \<phi>"
+ | "wf_fmla (\<phi>1 \<^bold>\<rightarrow> \<phi>2) \<longleftrightarrow> (wf_fmla \<phi>1 \<and> wf_fmla \<phi>2)"
+
+ lemma "wf_fmla \<phi> = (\<forall>a\<in>atoms \<phi>. wf_atom a)"
+ by (induction \<phi>) auto
+
+ (*lemma wf_fmla_add_simps[simp]: "wf_fmla (\<^bold>\<not>\<phi>) \<longleftrightarrow> \<phi>=\<bottom>"
+ by (cases \<phi>) auto*)
+
+ text \<open>Special case for a well-formed atomic predicate formula\<close>
+ fun wf_fmla_atom where
+ "wf_fmla_atom (Atom (predAtm a vs)) \<longleftrightarrow> wf_pred_atom (a,vs)"
+ | "wf_fmla_atom _ \<longleftrightarrow> False"
+
+ lemma wf_fmla_atom_alt: "wf_fmla_atom \<phi> \<longleftrightarrow> is_predAtom \<phi> \<and> wf_fmla \<phi>"
+ by (cases \<phi> rule: wf_fmla_atom.cases) auto
+
+ text \<open>An effect is well-formed if the added and removed formulas
+ are atomic\<close>
+ fun wf_effect where
+ "wf_effect (Effect a d) \<longleftrightarrow>
+ (\<forall>ae\<in>set a. wf_fmla_atom ae)
+ \<and> (\<forall>de\<in>set d. wf_fmla_atom de)"
+
+ end \<comment> \<open>Context fixing \<open>ty_ent\<close>\<close>
+
+
+ definition constT :: "object \<rightharpoonup> type" where
+ "constT \<equiv> map_of (consts D)"
+
+ text \<open>An action schema is well-formed if the parameter names are distinct,
+ and the precondition and effect is well-formed wrt.\ the parameters.
+ \<close>
+ fun wf_action_schema :: "ast_action_schema \<Rightarrow> bool" where
+ "wf_action_schema (Action_Schema n params pre eff) \<longleftrightarrow> (
+ let
+ tyt = ty_term (map_of params) constT
+ in
+ distinct (map fst params)
+ \<and> wf_fmla tyt pre
+ \<and> wf_effect tyt eff)"
+
+ text \<open>A type is well-formed if it consists only of declared primitive types,
+ and the type object.\<close>
+ fun wf_type where
+ "wf_type (Either Ts) \<longleftrightarrow> set Ts \<subseteq> insert ''object'' (fst`set (types D))"
+
+ text \<open>A predicate is well-formed if its argument types are well-formed.\<close>
+ fun wf_predicate_decl where
+ "wf_predicate_decl (PredDecl p Ts) \<longleftrightarrow> (\<forall>T\<in>set Ts. wf_type T)"
+
+ text \<open>The types declaration is well-formed, if all supertypes are declared types (or object)\<close>
+ definition "wf_types \<equiv> snd`set (types D) \<subseteq> insert ''object'' (fst`set (types D))"
+
+ text \<open>A domain is well-formed if
+ \<^item> there are no duplicate declared predicate names,
+ \<^item> all declared predicates are well-formed,
+ \<^item> there are no duplicate action names,
+ \<^item> and all declared actions are well-formed
+ \<close>
+ definition wf_domain :: "bool" where
+ "wf_domain \<equiv>
+ wf_types
+ \<and> distinct (map (predicate_decl.pred) (predicates D))
+ \<and> (\<forall>p\<in>set (predicates D). wf_predicate_decl p)
+ \<and> distinct (map fst (consts D))
+ \<and> (\<forall>(n,T)\<in>set (consts D). wf_type T)
+ \<and> distinct (map ast_action_schema.name (actions D))
+ \<and> (\<forall>a\<in>set (actions D). wf_action_schema a)
+ "
+
+end \<comment> \<open>locale \<open>ast_domain\<close>\<close>
+
+text \<open>We fix a problem, and also include the definitions for the domain
+ of this problem.\<close>
+locale ast_problem = ast_domain "domain P"
+ for P :: ast_problem
+begin
+ text \<open>We refer to the problem domain as \<open>D\<close>\<close>
+ abbreviation "D \<equiv> ast_problem.domain P"
+
+ definition objT :: "object \<rightharpoonup> type" where
+ "objT \<equiv> map_of (objects P) ++ constT"
+
+ lemma objT_alt: "objT = map_of (consts D @ objects P)"
+ unfolding objT_def constT_def
+ apply (clarsimp)
+ done
+
+ definition wf_fact :: "fact \<Rightarrow> bool" where
+ "wf_fact = wf_pred_atom objT"
+
+ text \<open>This definition is needed for well-formedness of the initial model,
+ and forward-references to the concept of world model.
+ \<close>
+ definition wf_world_model where
+ "wf_world_model M = (\<forall>f\<in>M. wf_fmla_atom objT f)"
+
+ (*Note: current semantics assigns each object a unique type *)
+ definition wf_problem where
+ "wf_problem \<equiv>
+ wf_domain
+ \<and> distinct (map fst (objects P) @ map fst (consts D))
+ \<and> (\<forall>(n,T)\<in>set (objects P). wf_type T)
+ \<and> distinct (init P)
+ \<and> wf_world_model (set (init P))
+ \<and> wf_fmla objT (goal P)
+ "
+
+ fun wf_effect_inst :: "object ast_effect \<Rightarrow> bool" where
+ "wf_effect_inst (Effect (a) (d))
+ \<longleftrightarrow> (\<forall>a\<in>set a \<union> set d. wf_fmla_atom objT a)"
+
+ lemma wf_effect_inst_alt: "wf_effect_inst eff = wf_effect objT eff"
+ by (cases eff) auto
+
+end \<comment> \<open>locale \<open>ast_problem\<close>\<close>
+
+text \<open>Locale to express a well-formed domain\<close>
+locale wf_ast_domain = ast_domain +
+ assumes wf_domain: wf_domain
+
+text \<open>Locale to express a well-formed problem\<close>
+locale wf_ast_problem = ast_problem P for P +
+ assumes wf_problem: wf_problem
+begin
+ sublocale wf_ast_domain "domain P"
+ apply unfold_locales
+ using wf_problem
+ unfolding wf_problem_def by simp
+
+end \<comment> \<open>locale \<open>wf_ast_problem\<close>\<close>
+
+subsection \<open>PDDL Semantics\<close>
+
+(* Semantics *)
+
+(* To apply plan_action:
+ find action schema, instantiate, check precond, apply effect
+*)
+
+
+
+context ast_domain begin
+
+ definition resolve_action_schema :: "name \<rightharpoonup> ast_action_schema" where
+ "resolve_action_schema n = index_by ast_action_schema.name (actions D) n"
+
+ fun subst_term where
+ "subst_term psubst (term.VAR x) = psubst x"
+ | "subst_term psubst (term.CONST c) = c"
+
+ text \<open>To instantiate an action schema, we first compute a substitution from
+ parameters to objects, and then apply this substitution to the
+ precondition and effect. The substitution is applied via the \<open>map_xxx\<close>
+ functions generated by the datatype package.
+ \<close>
+ fun instantiate_action_schema
+ :: "ast_action_schema \<Rightarrow> object list \<Rightarrow> ground_action"
+ where
+ "instantiate_action_schema (Action_Schema n params pre eff) args = (let
+ tsubst = subst_term (the o (map_of (zip (map fst params) args)));
+ pre_inst = (map_formula o map_atom) tsubst pre;
+ eff_inst = (map_ast_effect) tsubst eff
+ in
+ Ground_Action pre_inst eff_inst
+ )"
+
+end \<comment> \<open>Context of \<open>ast_domain\<close>\<close>
+
+
+context ast_problem begin
+
+ text \<open>Initial model\<close>
+ definition I :: "world_model" where
+ "I \<equiv> set (init P)"
+
+
+ text \<open>Resolve a plan action and instantiate the referenced action schema.\<close>
+ fun resolve_instantiate :: "plan_action \<Rightarrow> ground_action" where
+ "resolve_instantiate (PAction n args) =
+ instantiate_action_schema
+ (the (resolve_action_schema n))
+ args"
+
+ text \<open>Check whether object has specified type\<close>
+ definition "is_obj_of_type n T \<equiv> case objT n of
+ None \<Rightarrow> False
+ | Some oT \<Rightarrow> of_type oT T"
+
+ text \<open>We can also use the generic \<open>is_of_type\<close> function.\<close>
+ lemma is_obj_of_type_alt: "is_obj_of_type = is_of_type objT"
+ apply (intro ext)
+ unfolding is_obj_of_type_def is_of_type_def by auto
+
+
+ text \<open>HOL encoding of matching an action's formal parameters against an
+ argument list.
+ The parameters of the action are encoded as a list of \<open>name\<times>type\<close> pairs,
+ such that we map it to a list of types first. Then, the list
+ relator @{const list_all2} checks that arguments and types have the same
+ length, and each matching pair of argument and type
+ satisfies the predicate @{const is_obj_of_type}.
+ \<close>
+ definition "action_params_match a args
+ \<equiv> list_all2 is_obj_of_type args (map snd (parameters a))"
+
+ text \<open>At this point, we can define well-formedness of a plan action:
+ The action must refer to a declared action schema, the arguments must
+ be compatible with the formal parameters' types.
+ \<close>
+ (* Objects are valid and match parameter types *)
+ fun wf_plan_action :: "plan_action \<Rightarrow> bool" where
+ "wf_plan_action (PAction n args) = (
+ case resolve_action_schema n of
+ None \<Rightarrow> False
+ | Some a \<Rightarrow>
+ action_params_match a args
+ \<and> wf_effect_inst (effect (instantiate_action_schema a args))
+ )"
+ text \<open>
+ TODO: The second conjunct is redundant, as instantiating a well formed
+ action with valid objects yield a valid effect.
+ \<close>
+
+
+
+ text \<open>A sequence of plan actions form a path, if they are well-formed and
+ their instantiations form a path.\<close>
+ definition plan_action_path
+ :: "world_model \<Rightarrow> plan_action list \<Rightarrow> world_model \<Rightarrow> bool"
+ where
+ "plan_action_path M \<pi>s M' =
+ ((\<forall>\<pi> \<in> set \<pi>s. wf_plan_action \<pi>)
+ \<and> ground_action_path M (map resolve_instantiate \<pi>s) M')"
+
+ text \<open>A plan is valid wrt.\ a given initial model, if it forms a path to a
+ goal model \<close>
+ definition valid_plan_from :: "world_model \<Rightarrow> plan \<Rightarrow> bool" where
+ "valid_plan_from M \<pi>s = (\<exists>M'. plan_action_path M \<pi>s M' \<and> M' \<^sup>c\<TTurnstile>\<^sub>= (goal P))"
+
+ (* Implementation note: resolve and instantiate already done inside
+ enabledness check, redundancy! *)
+
+ text \<open>Finally, a plan is valid if it is valid wrt.\ the initial world
+ model @{const I}\<close>
+ definition valid_plan :: "plan \<Rightarrow> bool"
+ where "valid_plan \<equiv> valid_plan_from I"
+
+ text \<open>Concise definition used in paper:\<close>
+ lemma "valid_plan \<pi>s \<equiv> \<exists>M'. plan_action_path I \<pi>s M' \<and> M' \<^sup>c\<TTurnstile>\<^sub>= (goal P)"
+ unfolding valid_plan_def valid_plan_from_def by auto
+
+
+end \<comment> \<open>Context of \<open>ast_problem\<close>\<close>
+
+
+
+subsection \<open>Preservation of Well-Formedness\<close>
+
+subsubsection \<open>Well-Formed Action Instances\<close>
+text \<open>The goal of this section is to establish that well-formedness of
+ world models is preserved by execution of well-formed plan actions.
+\<close>
+
+context ast_problem begin
+
+ text \<open>As plan actions are executed by first instantiating them, and then
+ executing the action instance, it is natural to define a well-formedness
+ concept for action instances.\<close>
+
+ fun wf_ground_action :: "ground_action \<Rightarrow> bool" where
+ "wf_ground_action (Ground_Action pre eff) \<longleftrightarrow> (
+ wf_fmla objT pre
+ \<and> wf_effect objT eff
+ )
+ "
+
+ text \<open>We first prove that instantiating a well-formed action schema will yield
+ a well-formed action instance.
+
+ We begin with some auxiliary lemmas before the actual theorem.
+ \<close>
+
+ lemma (in ast_domain) of_type_refl[simp, intro!]: "of_type T T"
+ unfolding of_type_def by auto
+
+ lemma (in ast_domain) of_type_trans[trans]:
+ "of_type T1 T2 \<Longrightarrow> of_type T2 T3 \<Longrightarrow> of_type T1 T3"
+ unfolding of_type_def
+ by clarsimp (metis (no_types, hide_lams)
+ Image_mono contra_subsetD order_refl rtrancl_image_idem)
+
+ lemma is_of_type_map_ofE:
+ assumes "is_of_type (map_of params) x T"
+ obtains i xT where "i<length params" "params!i = (x,xT)" "of_type xT T"
+ using assms
+ unfolding is_of_type_def
+ by (auto split: option.splits dest!: map_of_SomeD simp: in_set_conv_nth)
+
+ lemma wf_atom_mono:
+ assumes SS: "tys \<subseteq>\<^sub>m tys'"
+ assumes WF: "wf_atom tys a"
+ shows "wf_atom tys' a"
+ proof -
+ have "list_all2 (is_of_type tys') xs Ts" if "list_all2 (is_of_type tys) xs Ts" for xs Ts
+ using that
+ apply induction
+ by (auto simp: is_of_type_def split: option.splits dest: map_leD[OF SS])
+ with WF show ?thesis
+ by (cases a) (auto split: option.splits dest: map_leD[OF SS])
+ qed
+
+ lemma wf_fmla_atom_mono:
+ assumes SS: "tys \<subseteq>\<^sub>m tys'"
+ assumes WF: "wf_fmla_atom tys a"
+ shows "wf_fmla_atom tys' a"
+ proof -
+ have "list_all2 (is_of_type tys') xs Ts" if "list_all2 (is_of_type tys) xs Ts" for xs Ts
+ using that
+ apply induction
+ by (auto simp: is_of_type_def split: option.splits dest: map_leD[OF SS])
+ with WF show ?thesis
+ by (cases a rule: wf_fmla_atom.cases) (auto split: option.splits dest: map_leD[OF SS])
+ qed
+
+
+ lemma constT_ss_objT: "constT \<subseteq>\<^sub>m objT"
+ unfolding constT_def objT_def
+ apply rule
+ by (auto simp: map_add_def split: option.split)
+
+ lemma wf_atom_constT_imp_objT: "wf_atom (ty_term Q constT) a \<Longrightarrow> wf_atom (ty_term Q objT) a"
+ apply (erule wf_atom_mono[rotated])
+ apply (rule ty_term_mono)
+ by (simp_all add: constT_ss_objT)
+
+ lemma wf_fmla_atom_constT_imp_objT: "wf_fmla_atom (ty_term Q constT) a \<Longrightarrow> wf_fmla_atom (ty_term Q objT) a"
+ apply (erule wf_fmla_atom_mono[rotated])
+ apply (rule ty_term_mono)
+ by (simp_all add: constT_ss_objT)
+
+ context
+ fixes Q and f :: "variable \<Rightarrow> object"
+ assumes INST: "is_of_type Q x T \<Longrightarrow> is_of_type objT (f x) T"
+ begin
+
+ lemma is_of_type_var_conv: "is_of_type (ty_term Q objT) (term.VAR x) T \<longleftrightarrow> is_of_type Q x T"
+ unfolding is_of_type_def by (auto)
+
+ lemma is_of_type_const_conv: "is_of_type (ty_term Q objT) (term.CONST x) T \<longleftrightarrow> is_of_type objT x T"
+ unfolding is_of_type_def
+ by (auto split: option.split)
+
+ lemma INST': "is_of_type (ty_term Q objT) x T \<Longrightarrow> is_of_type objT (subst_term f x) T"
+ apply (cases x) using INST apply (auto simp: is_of_type_var_conv is_of_type_const_conv)
+ done
+
+
+ lemma wf_inst_eq_aux: "Q x = Some T \<Longrightarrow> objT (f x) \<noteq> None"
+ using INST[of x T] unfolding is_of_type_def
+ by (auto split: option.splits)
+
+ lemma wf_inst_eq_aux': "ty_term Q objT x = Some T \<Longrightarrow> objT (subst_term f x) \<noteq> None"
+ by (cases x) (auto simp: wf_inst_eq_aux)
+
+
+ lemma wf_inst_atom:
+ assumes "wf_atom (ty_term Q constT) a"
+ shows "wf_atom objT (map_atom (subst_term f) a)"
+ proof -
+ have X1: "list_all2 (is_of_type objT) (map (subst_term f) xs) Ts" if
+ "list_all2 (is_of_type (ty_term Q objT)) xs Ts" for xs Ts
+ using that
+ apply induction
+ using INST'
+ by auto
+ then show ?thesis
+ using assms[THEN wf_atom_constT_imp_objT] wf_inst_eq_aux'
+ by (cases a; auto split: option.splits)
+
+ qed
+
+ lemma wf_inst_formula_atom:
+ assumes "wf_fmla_atom (ty_term Q constT) a"
+ shows "wf_fmla_atom objT ((map_formula o map_atom o subst_term) f a)"
+ using assms[THEN wf_fmla_atom_constT_imp_objT] wf_inst_atom
+ apply (cases a rule: wf_fmla_atom.cases; auto split: option.splits)
+ by (simp add: INST' list.rel_map(1) list_all2_mono)
+
+ lemma wf_inst_effect:
+ assumes "wf_effect (ty_term Q constT) \<phi>"
+ shows "wf_effect objT ((map_ast_effect o subst_term) f \<phi>)"
+ using assms
+ proof (induction \<phi>)
+ case (Effect x1a x2a)
+ then show ?case using wf_inst_formula_atom by auto
+ qed
+
+ lemma wf_inst_formula:
+ assumes "wf_fmla (ty_term Q constT) \<phi>"
+ shows "wf_fmla objT ((map_formula o map_atom o subst_term) f \<phi>)"
+ using assms
+ by (induction \<phi>) (auto simp: wf_inst_atom dest: wf_inst_eq_aux)
+
+ end
+
+
+
+ text \<open>Instantiating a well-formed action schema with compatible arguments
+ will yield a well-formed action instance.
+ \<close>
+ theorem wf_instantiate_action_schema:
+ assumes "action_params_match a args"
+ assumes "wf_action_schema a"
+ shows "wf_ground_action (instantiate_action_schema a args)"
+ proof (cases a)
+ case [simp]: (Action_Schema name params pre eff)
+ have INST:
+ "is_of_type objT ((the \<circ> map_of (zip (map fst params) args)) x) T"
+ if "is_of_type (map_of params) x T" for x T
+ using that
+ apply (rule is_of_type_map_ofE)
+ using assms
+ apply (clarsimp simp: Let_def)
+ subgoal for i xT
+ unfolding action_params_match_def
+ apply (subst lookup_zip_idx_eq[where i=i];
+ (clarsimp simp: list_all2_lengthD)?)
+ apply (frule list_all2_nthD2[where p=i]; simp?)
+ apply (auto
+ simp: is_obj_of_type_alt is_of_type_def
+ intro: of_type_trans
+ split: option.splits)
+ done
+ done
+ then show ?thesis
+ using assms(2) wf_inst_formula wf_inst_effect
+ by (fastforce split: term.splits simp: Let_def comp_apply[abs_def])
+ qed
+end \<comment> \<open>Context of \<open>ast_problem\<close>\<close>
+
+
+
+subsubsection \<open>Preservation\<close>
+
+context ast_problem begin
+
+ text \<open>We start by defining two shorthands for enabledness and execution of
+ a plan action.\<close>
+
+ text \<open>Shorthand for enabled plan action: It is well-formed, and the
+ precondition holds for its instance.\<close>
+ definition plan_action_enabled :: "plan_action \<Rightarrow> world_model \<Rightarrow> bool" where
+ "plan_action_enabled \<pi> M
+ \<longleftrightarrow> wf_plan_action \<pi> \<and> M \<^sup>c\<TTurnstile>\<^sub>= precondition (resolve_instantiate \<pi>)"
+
+ text \<open>Shorthand for executing a plan action: Resolve, instantiate, and
+ apply effect\<close>
+ definition execute_plan_action :: "plan_action \<Rightarrow> world_model \<Rightarrow> world_model"
+ where "execute_plan_action \<pi> M
+ = (apply_effect (effect (resolve_instantiate \<pi>)) M)"
+
+ text \<open>The @{const plan_action_path} predicate can be decomposed naturally
+ using these shorthands: \<close>
+ lemma plan_action_path_Nil[simp]: "plan_action_path M [] M' \<longleftrightarrow> M'=M"
+ by (auto simp: plan_action_path_def)
+
+ lemma plan_action_path_Cons[simp]:
+ "plan_action_path M (\<pi>#\<pi>s) M' \<longleftrightarrow>
+ plan_action_enabled \<pi> M
+ \<and> plan_action_path (execute_plan_action \<pi> M) \<pi>s M'"
+ by (auto
+ simp: plan_action_path_def execute_plan_action_def
+ execute_ground_action_def plan_action_enabled_def)
+
+
+
+end \<comment> \<open>Context of \<open>ast_problem\<close>\<close>
+
+context wf_ast_problem begin
+ text \<open>The initial world model is well-formed\<close>
+ lemma wf_I: "wf_world_model I"
+ using wf_problem
+ unfolding I_def wf_world_model_def wf_problem_def
+ apply(safe) subgoal for f by (induction f) auto
+ done
+
+ text \<open>Application of a well-formed effect preserves well-formedness
+ of the model\<close>
+ lemma wf_apply_effect:
+ assumes "wf_effect objT e"
+ assumes "wf_world_model s"
+ shows "wf_world_model (apply_effect e s)"
+ using assms wf_problem
+ unfolding wf_world_model_def wf_problem_def wf_domain_def
+ by (cases e) (auto split: formula.splits prod.splits)
+
+ text \<open>Execution of plan actions preserves well-formedness\<close>
+ theorem wf_execute:
+ assumes "plan_action_enabled \<pi> s"
+ assumes "wf_world_model s"
+ shows "wf_world_model (execute_plan_action \<pi> s)"
+ using assms
+ proof (cases \<pi>)
+ case [simp]: (PAction name args)
+
+ from \<open>plan_action_enabled \<pi> s\<close> have "wf_plan_action \<pi>"
+ unfolding plan_action_enabled_def by auto
+ then obtain a where
+ "resolve_action_schema name = Some a" and
+ T: "action_params_match a args"
+ by (auto split: option.splits)
+
+ from wf_domain have
+ [simp]: "distinct (map ast_action_schema.name (actions D))"
+ unfolding wf_domain_def by auto
+
+ from \<open>resolve_action_schema name = Some a\<close> have
+ "a \<in> set (actions D)"
+ unfolding resolve_action_schema_def by auto
+ with wf_domain have "wf_action_schema a"
+ unfolding wf_domain_def by auto
+ hence "wf_ground_action (resolve_instantiate \<pi>)"
+ using \<open>resolve_action_schema name = Some a\<close> T
+ wf_instantiate_action_schema
+ by auto
+ thus ?thesis
+ apply (simp add: execute_plan_action_def execute_ground_action_def)
+ apply (rule wf_apply_effect)
+ apply (cases "resolve_instantiate \<pi>"; simp)
+ by (rule \<open>wf_world_model s\<close>)
+ qed
+
+ theorem wf_execute_compact_notation:
+ "plan_action_enabled \<pi> s \<Longrightarrow> wf_world_model s
+ \<Longrightarrow> wf_world_model (execute_plan_action \<pi> s)"
+ by (rule wf_execute)
+
+
+ text \<open>Execution of a plan preserves well-formedness\<close>
+ corollary wf_plan_action_path:
+ assumes "wf_world_model M" and " plan_action_path M \<pi>s M'"
+ shows "wf_world_model M'"
+ using assms
+ by (induction \<pi>s arbitrary: M) (auto intro: wf_execute)
+
+
+end \<comment> \<open>Context of \<open>wf_ast_problem\<close>\<close>
+
+
+
+
+end \<comment> \<open>Theory\<close>
diff --git a/thys/AI_Planning_Languages_Semantics/ROOT b/thys/AI_Planning_Languages_Semantics/ROOT
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/ROOT
@@ -0,0 +1,33 @@
+chapter AFP
+
+session AI_Planning_Languages_Semantics (AFP) = HOL +
+ description \<open>AI Planning Languages Semantics and Validation\<close>
+ options [timeout = 600]
+ sessions
+ "HOL-Library"
+ "Certification_Monads"
+ "Show"
+ "Containers"
+ "Propositional_Proof_Systems"
+ theories [document = false]
+ "HOL-Library.Code_Target_Nat"
+ "HOL-Library.Monad_Syntax"
+ "HOL-Library.Char_ord"
+ "HOL-Library.Code_Target_Nat"
+ "HOL-Library.Rewrite"
+ "Certification_Monads.Error_Monad"
+ "Show.Show"
+ "HOL-Library.Rewrite"
+ "Containers.Containers"
+ theories [document = false]
+ Error_Monad_Add
+ Option_Monad_Add
+ theories
+ SASP_Semantics
+ SASP_Checker
+ PDDL_STRIPS_Semantics
+ PDDL_STRIPS_Checker
+ Lifschitz_Consistency
+ document_files
+ "root.tex"
+ "root.bib"
diff --git a/thys/AI_Planning_Languages_Semantics/SASP_Checker.thy b/thys/AI_Planning_Languages_Semantics/SASP_Checker.thy
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/SASP_Checker.thy
@@ -0,0 +1,348 @@
+theory SASP_Checker
+imports SASP_Semantics
+ "HOL-Library.Code_Target_Nat"
+begin
+
+section \<open>An Executable Checker for Multi-Valued Planning Problem Solutions\<close>
+
+
+ subsection \<open>Auxiliary Lemmas\<close>
+ lemma map_of_leI:
+ assumes "distinct (map fst l)"
+ assumes "\<And>k v. (k,v)\<in>set l \<Longrightarrow> m k = Some v"
+ shows "map_of l \<subseteq>\<^sub>m m"
+ using assms
+ by (metis (no_types, hide_lams) domIff map_le_def map_of_SomeD not_Some_eq)
+
+ lemma [simp]: "fst \<circ> (\<lambda>(a, b, c, d). (f a b c d, g a b c d)) = (\<lambda>(a,b,c,d). f a b c d)"
+ by auto
+
+ lemma map_mp: "m\<subseteq>\<^sub>mm' \<Longrightarrow> m k = Some v \<Longrightarrow> m' k = Some v"
+ by (auto simp: map_le_def dom_def)
+
+
+ lemma map_add_map_of_fold:
+ fixes ps and m :: "'a \<rightharpoonup> 'b"
+ assumes "distinct (map fst ps)"
+ shows "m ++ map_of ps = fold (\<lambda>(k, v) m. m(k \<mapsto> v)) ps m"
+ proof -
+ have X1: "fold (\<lambda>(k, v) m. m(k \<mapsto> v)) ps m(a \<mapsto> b)
+ = fold (\<lambda>(k, v) m. m(k \<mapsto> v)) ps (m(a \<mapsto> b))"
+ if "a \<notin> fst ` set ps"
+ for a b ps and m :: "'a \<rightharpoonup> 'b"
+ using that
+ by (induction ps arbitrary: m) (auto simp: fun_upd_twist)
+
+ show ?thesis
+ using assms
+ by (induction ps arbitrary: m) (auto simp: X1)
+ qed
+
+
+
+ subsection \<open>Well-formedness Check\<close>
+ lemmas wf_code_thms =
+ ast_problem.astDom_def ast_problem.astI_def ast_problem.astG_def ast_problem.ast\<delta>_def
+ ast_problem.numVars_def ast_problem.numVals_def
+ ast_problem.wf_partial_state_def ast_problem.wf_operator_def ast_problem.well_formed_def
+
+
+ declare wf_code_thms[code]
+
+ export_code ast_problem.well_formed in SML
+
+
+ subsection \<open>Execution\<close>
+
+ definition match_pre :: "ast_precond \<Rightarrow> state \<Rightarrow> bool" where
+ "match_pre \<equiv> \<lambda>(x,v) s. s x = Some v"
+
+ definition match_pres :: "ast_precond list \<Rightarrow> state \<Rightarrow> bool" where
+ "match_pres pres s \<equiv> \<forall>pre\<in>set pres. match_pre pre s"
+
+ definition match_implicit_pres :: "ast_effect list \<Rightarrow> state \<Rightarrow> bool" where
+ "match_implicit_pres effs s \<equiv> \<forall>(_,x,vp,_)\<in>set effs.
+ (case vp of None \<Rightarrow> True | Some v \<Rightarrow> s x = Some v)"
+
+ definition enabled_opr' :: "ast_operator \<Rightarrow> state \<Rightarrow> bool" where
+ "enabled_opr' \<equiv> \<lambda>(name,pres,effs,cost) s. match_pres pres s \<and> match_implicit_pres effs s"
+
+ definition eff_enabled' :: "state \<Rightarrow> ast_effect \<Rightarrow> bool" where
+ "eff_enabled' s \<equiv> \<lambda>(pres,_,_,_). match_pres pres s"
+
+ definition "execute_opr' \<equiv> \<lambda>(name,_,effs,_) s.
+ let effs = filter (eff_enabled' s) effs
+ in fold (\<lambda>(_,x,_,v) s. s(x\<mapsto>v)) effs s
+ "
+
+ definition lookup_operator' :: "ast_problem \<Rightarrow> name \<rightharpoonup> ast_operator"
+ where "lookup_operator' \<equiv> \<lambda>(D,I,G,\<delta>) name. find (\<lambda>(n,_,_,_). n=name) \<delta>"
+
+ definition enabled' :: "ast_problem \<Rightarrow> name \<Rightarrow> state \<Rightarrow> bool" where
+ "enabled' problem name s \<equiv>
+ case lookup_operator' problem name of
+ Some \<pi> \<Rightarrow> enabled_opr' \<pi> s
+ | None \<Rightarrow> False"
+
+ definition execute' :: "ast_problem \<Rightarrow> name \<Rightarrow> state \<Rightarrow> state" where
+ "execute' problem name s \<equiv>
+ case lookup_operator' problem name of
+ Some \<pi> \<Rightarrow> execute_opr' \<pi> s
+ | None \<Rightarrow> undefined"
+
+
+ context wf_ast_problem begin
+
+ lemma match_pres_correct:
+ assumes D: "distinct (map fst pres)"
+ assumes "s\<in>valid_states"
+ shows "match_pres pres s \<longleftrightarrow> s\<in>subsuming_states (map_of pres)"
+ proof -
+ have "match_pres pres s \<longleftrightarrow> map_of pres \<subseteq>\<^sub>m s"
+ unfolding match_pres_def match_pre_def
+ apply (auto split: prod.splits)
+ using map_le_def map_of_SomeD apply fastforce
+ by (metis (full_types) D domIff map_le_def map_of_eq_Some_iff option.simps(3))
+
+ with assms show ?thesis
+ unfolding subsuming_states_def
+ by auto
+ qed
+
+ lemma match_implicit_pres_correct:
+ assumes D: "distinct (map (\<lambda>(_, v, _, _). v) effs)"
+ assumes "s\<in>valid_states"
+ shows "match_implicit_pres effs s \<longleftrightarrow> s\<in>subsuming_states (map_of (implicit_pres effs))"
+ proof -
+ from assms show ?thesis
+ unfolding subsuming_states_def
+ unfolding match_implicit_pres_def implicit_pres_def
+ apply (auto
+ split: prod.splits option.splits
+ simp: distinct_map_filter
+ intro!: map_of_leI)
+ apply (force simp: distinct_map_filter split: prod.split elim: map_mp)
+ done
+ qed
+
+ lemma enabled_opr'_correct:
+ assumes V: "s\<in>valid_states"
+ assumes "lookup_operator name = Some \<pi>"
+ shows "enabled_opr' \<pi> s \<longleftrightarrow> enabled name s"
+ using lookup_operator_wf[OF assms(2)] assms
+ unfolding enabled_opr'_def enabled_def wf_operator_def
+ by (auto
+ simp: match_pres_correct[OF _ V] match_implicit_pres_correct[OF _ V]
+ simp: wf_partial_state_def
+ split: option.split
+ )
+
+ lemma eff_enabled'_correct:
+ assumes V: "s\<in>valid_states"
+ assumes "case eff of (pres,_,_,_) \<Rightarrow> wf_partial_state pres"
+ shows "eff_enabled' s eff \<longleftrightarrow> eff_enabled s eff"
+ using assms
+ unfolding eff_enabled'_def eff_enabled_def wf_partial_state_def
+ by (auto simp: match_pres_correct)
+
+
+ lemma execute_opr'_correct:
+ assumes V: "s\<in>valid_states"
+ assumes LO: "lookup_operator name = Some \<pi>"
+ shows "execute_opr' \<pi> s = execute name s"
+ proof (cases \<pi>)
+ case [simp]: (fields name pres effs)
+
+ have [simp]: "filter (eff_enabled' s) effs = filter (eff_enabled s) effs"
+ apply (rule filter_cong[OF refl])
+ apply (rule eff_enabled'_correct[OF V])
+ using lookup_operator_wf[OF LO]
+ unfolding wf_operator_def by auto
+
+ have X1: "distinct (map fst (map (\<lambda>(_, x, _, y). (x, y)) (filter (eff_enabled s) effs)))"
+ using lookup_operator_wf[OF LO]
+ unfolding wf_operator_def
+ by (auto simp: distinct_map_filter)
+
+ term "filter (eff_enabled s) effs"
+
+ have [simp]:
+ "fold (\<lambda>(_, x, _, v) s. s(x \<mapsto> v)) l s =
+ fold (\<lambda>(k, v) m. m(k \<mapsto> v)) (map (\<lambda>(_, x, _, y). (x, y)) l) s"
+ for l :: "ast_effect list"
+ by (induction l arbitrary: s) auto
+
+ show ?thesis
+ unfolding execute_opr'_def execute_def using LO
+ by (auto simp: map_add_map_of_fold[OF X1])
+ qed
+
+
+ lemma lookup_operator'_correct:
+ "lookup_operator' problem name = lookup_operator name"
+ unfolding lookup_operator'_def lookup_operator_def
+ unfolding ast\<delta>_def
+ by (auto split: prod.split)
+
+ lemma enabled'_correct:
+ assumes V: "s\<in>valid_states"
+ shows "enabled' problem name s = enabled name s"
+ unfolding enabled'_def
+ using enabled_opr'_correct[OF V]
+ by (auto split: option.splits simp: enabled_def lookup_operator'_correct)
+
+ lemma execute'_correct:
+ assumes V: "s\<in>valid_states"
+ assumes "enabled name s" (* Intentionally put this here, also we could resolve non-enabled case by reflexivity (undefined=undefined) *)
+ shows "execute' problem name s = execute name s"
+ unfolding execute'_def
+ using execute_opr'_correct[OF V] \<open>enabled name s\<close>
+ by (auto split: option.splits simp: enabled_def lookup_operator'_correct)
+
+
+
+ end
+
+ context ast_problem
+ begin
+
+ fun simulate_plan :: "plan \<Rightarrow> state \<rightharpoonup> state" where
+ "simulate_plan [] s = Some s"
+ | "simulate_plan (\<pi>#\<pi>s) s = (
+ if enabled \<pi> s then
+ let s' = execute \<pi> s in
+ simulate_plan \<pi>s s'
+ else
+ None
+ )"
+
+ lemma simulate_plan_correct: "simulate_plan \<pi>s s = Some s' \<longleftrightarrow> path_to s \<pi>s s'"
+ by (induction s \<pi>s s' rule: path_to.induct) auto
+
+ definition check_plan :: "plan \<Rightarrow> bool" where
+ "check_plan \<pi>s = (
+ case simulate_plan \<pi>s I of
+ None \<Rightarrow> False
+ | Some s' \<Rightarrow> s' \<in> G)"
+
+ lemma check_plan_correct: "check_plan \<pi>s \<longleftrightarrow> valid_plan \<pi>s"
+ unfolding check_plan_def valid_plan_def
+ by (auto split: option.split simp: simulate_plan_correct[symmetric])
+
+ end
+
+ fun simulate_plan' :: "ast_problem \<Rightarrow> plan \<Rightarrow> state \<rightharpoonup> state" where
+ "simulate_plan' problem [] s = Some s"
+ | "simulate_plan' problem (\<pi>#\<pi>s) s = (
+ if enabled' problem \<pi> s then
+ let s = execute' problem \<pi> s in
+ simulate_plan' problem \<pi>s s
+ else
+ None
+ )"
+
+ text \<open>Avoiding duplicate lookup.\<close>
+ (*[code] *)
+ lemma simulate_plan'_code[code]:
+ "simulate_plan' problem [] s = Some s"
+ "simulate_plan' problem (\<pi>#\<pi>s) s = (
+ case lookup_operator' problem \<pi> of
+ None \<Rightarrow> None
+ | Some \<pi> \<Rightarrow>
+ if enabled_opr' \<pi> s then
+ simulate_plan' problem \<pi>s (execute_opr' \<pi> s)
+ else None
+ )"
+ by (auto simp: enabled'_def execute'_def split: option.split)
+
+
+ definition initial_state' :: "ast_problem \<Rightarrow> state" where
+ "initial_state' problem \<equiv> let astI = ast_problem.astI problem in (
+ \<lambda>v. if v<length astI then Some (astI!v) else None
+ )"
+
+ definition check_plan' :: "ast_problem \<Rightarrow> plan \<Rightarrow> bool" where
+ "check_plan' problem \<pi>s = (
+ case simulate_plan' problem \<pi>s (initial_state' problem) of
+ None \<Rightarrow> False
+ | Some s' \<Rightarrow> match_pres (ast_problem.astG problem) s')"
+
+
+ context wf_ast_problem
+ begin
+
+ lemma simulate_plan'_correct:
+ assumes "s\<in>valid_states"
+ shows "simulate_plan' problem \<pi>s s = simulate_plan \<pi>s s"
+ using assms
+ apply (induction \<pi>s s rule: simulate_plan.induct)
+ apply (auto simp: enabled'_correct execute'_correct execute_preserves_valid)
+ done
+
+ lemma simulate_plan'_correct_paper: (* For presentation in paper.
+ Summarizing intermediate refinement step. *)
+ assumes "s\<in>valid_states"
+ shows "simulate_plan' problem \<pi>s s = Some s'
+ \<longleftrightarrow> path_to s \<pi>s s'"
+ using simulate_plan'_correct[OF assms] simulate_plan_correct by simp
+
+
+ lemma initial_state'_correct:
+ "initial_state' problem = I"
+ unfolding initial_state'_def I_def by (auto simp: Let_def)
+
+ lemma check_plan'_correct:
+ "check_plan' problem \<pi>s = check_plan \<pi>s"
+ proof -
+ have D: "distinct (map fst astG)" using wf_goal unfolding wf_partial_state_def by auto
+
+ have S'V: "s'\<in>valid_states" if "simulate_plan \<pi>s I = Some s'" for s'
+ using that by (auto simp: simulate_plan_correct path_to_pres_valid[OF I_valid])
+
+ show ?thesis
+ unfolding check_plan'_def check_plan_def
+ by (auto
+ split: option.splits
+ simp: initial_state'_correct simulate_plan'_correct[OF I_valid]
+ simp: match_pres_correct[OF D S'V] G_def
+ )
+ qed
+
+ end
+
+
+ (* Overall checker *)
+
+ definition verify_plan :: "ast_problem \<Rightarrow> plan \<Rightarrow> String.literal + unit" where
+ "verify_plan problem \<pi>s = (
+ if ast_problem.well_formed problem then
+ if check_plan' problem \<pi>s then Inr () else Inl (STR ''Invalid plan'')
+ else Inl (STR ''Problem not well formed'')
+ )"
+
+ lemma verify_plan_correct:
+ "verify_plan problem \<pi>s = Inr ()
+ \<longleftrightarrow> ast_problem.well_formed problem \<and> ast_problem.valid_plan problem \<pi>s"
+ proof -
+ {
+ assume "ast_problem.well_formed problem"
+ then interpret wf_ast_problem by unfold_locales
+
+ from check_plan'_correct check_plan_correct
+ have "check_plan' problem \<pi>s = valid_plan \<pi>s" by simp
+ }
+ then show ?thesis
+ unfolding verify_plan_def
+ by auto
+ qed
+
+ definition nat_opt_of_integer :: "integer \<Rightarrow> nat option" where
+ "nat_opt_of_integer i = (if (i \<ge> 0) then Some (nat_of_integer i) else None)"
+
+ (*Export functions, which includes constructors*)
+ export_code verify_plan nat_of_integer integer_of_nat nat_opt_of_integer Inl Inr String.explode String.implode
+ in SML
+ module_name SASP_Checker_Exported
+ file "code/SASP_Checker_Exported.sml"
+
+end
diff --git a/thys/AI_Planning_Languages_Semantics/SASP_Semantics.thy b/thys/AI_Planning_Languages_Semantics/SASP_Semantics.thy
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/SASP_Semantics.thy
@@ -0,0 +1,228 @@
+theory SASP_Semantics
+imports Main
+begin
+
+section \<open>Semantics of Fast-Downward's Multi-Valued Planning Tasks Language\<close>
+
+subsection \<open>Syntax\<close>
+ type_synonym name = string
+ type_synonym ast_variable = "name \<times> nat option \<times> name list" (* var name, axiom layer, atom names *)
+ type_synonym ast_variable_section = "ast_variable list"
+ type_synonym ast_initial_state = "nat list"
+ type_synonym ast_goal = "(nat \<times> nat) list"
+ type_synonym ast_precond = "(nat \<times> nat)"
+ type_synonym ast_effect = "ast_precond list \<times> nat \<times> nat option \<times> nat"
+ type_synonym ast_operator = "name \<times> ast_precond list \<times> ast_effect list \<times> nat"
+ type_synonym ast_operator_section = "ast_operator list"
+
+ type_synonym ast_problem =
+ "ast_variable_section \<times> ast_initial_state \<times> ast_goal \<times> ast_operator_section"
+
+ type_synonym plan = "name list"
+
+ subsubsection \<open>Well-Formedness\<close>
+
+ locale ast_problem =
+ fixes problem :: ast_problem
+ begin
+ definition astDom :: ast_variable_section (* TODO: Dom \<rightarrow> Vars, D \<rightarrow> X*)
+ where "astDom \<equiv> case problem of (D,I,G,\<delta>) \<Rightarrow> D"
+ definition astI :: ast_initial_state
+ where "astI \<equiv> case problem of (D,I,G,\<delta>) \<Rightarrow> I"
+ definition astG :: ast_goal
+ where "astG \<equiv> case problem of (D,I,G,\<delta>) \<Rightarrow> G"
+ definition ast\<delta> :: ast_operator_section
+ where "ast\<delta> \<equiv> case problem of (D,I,G,\<delta>) \<Rightarrow> \<delta>"
+
+ definition "numVars \<equiv> length astDom"
+ definition "numVals x \<equiv> length (snd (snd (astDom!x)))"
+
+ definition "wf_partial_state ps \<equiv>
+ distinct (map fst ps)
+ \<and> (\<forall>(x,v) \<in> set ps. x < numVars \<and> v < numVals x)"
+
+ definition wf_operator :: "ast_operator \<Rightarrow> bool"
+ where "wf_operator \<equiv> \<lambda>(name, pres, effs, cost).
+ wf_partial_state pres
+ \<and> distinct (map (\<lambda>(_, v, _, _). v) effs) \<comment> \<open>This may be too restrictive\<close>
+ \<and> (\<forall>(epres,x,vp,v)\<in>set effs.
+ wf_partial_state epres
+ \<and> x < numVars \<and> v < numVals x
+ \<and> (case vp of None \<Rightarrow> True | Some v \<Rightarrow> v<numVals x)
+ )
+ "
+
+ definition "well_formed \<equiv>
+ \<comment> \<open>Initial state\<close>
+ length astI = numVars
+ \<and> (\<forall>x<numVars. astI!x < numVals x)
+
+ \<comment> \<open>Goal\<close>
+ \<and> wf_partial_state astG
+
+ \<comment> \<open>Operators\<close>
+ \<and> (distinct (map fst ast\<delta>))
+ \<and> (\<forall>\<pi>\<in>set ast\<delta>. wf_operator \<pi>)
+ "
+
+ end
+
+ locale wf_ast_problem = ast_problem +
+ assumes wf: well_formed
+ begin
+ lemma wf_initial:
+ "length astI = numVars"
+ "\<forall>x<numVars. astI!x < numVals x"
+ using wf unfolding well_formed_def by auto
+
+ lemma wf_goal: "wf_partial_state astG"
+ using wf unfolding well_formed_def by auto
+
+ lemma wf_operators:
+ "distinct (map fst ast\<delta>)"
+ "\<forall>\<pi>\<in>set ast\<delta>. wf_operator \<pi>"
+ using wf unfolding well_formed_def by auto
+ end
+
+
+ subsection \<open>Semantics as Transition System\<close>
+
+ type_synonym state = "nat \<rightharpoonup> nat"
+ type_synonym pstate = "nat \<rightharpoonup> nat"
+
+
+ context ast_problem
+ begin
+
+ definition Dom :: "nat set" where "Dom = {0..<numVars}"
+
+ definition range_of_var where "range_of_var x \<equiv> {0..<numVals x}"
+
+ definition valid_states :: "state set" where "valid_states \<equiv> {
+ s. dom s = Dom \<and> (\<forall>x\<in>Dom. the (s x) \<in> range_of_var x)
+ }"
+
+ definition I :: state
+ where "I v \<equiv> if v<length astI then Some (astI!v) else None"
+
+ definition subsuming_states :: "pstate \<Rightarrow> state set"
+ where "subsuming_states partial \<equiv> { s\<in>valid_states. partial \<subseteq>\<^sub>m s }"
+
+ definition G :: "state set"
+ where "G \<equiv> subsuming_states (map_of astG)"
+end
+
+ definition implicit_pres :: "ast_effect list \<Rightarrow> ast_precond list" where
+ "implicit_pres effs \<equiv>
+ map (\<lambda>(_,v,vpre,_). (v,the vpre))
+ (filter (\<lambda>(_,_,vpre,_). vpre\<noteq>None) effs)"
+
+context ast_problem
+begin
+
+ definition lookup_operator :: "name \<Rightarrow> ast_operator option" where
+ "lookup_operator name \<equiv> find (\<lambda>(n,_,_,_). n=name) ast\<delta>"
+
+ definition enabled :: "name \<Rightarrow> state \<Rightarrow> bool"
+ where "enabled name s \<equiv>
+ case lookup_operator name of
+ Some (_,pres,effs,_) \<Rightarrow>
+ s\<in>subsuming_states (map_of pres)
+ \<and> s\<in>subsuming_states (map_of (implicit_pres effs))
+ | None \<Rightarrow> False"
+
+ definition eff_enabled :: "state \<Rightarrow> ast_effect \<Rightarrow> bool" where
+ "eff_enabled s \<equiv> \<lambda>(pres,_,_,_). s\<in>subsuming_states (map_of pres)"
+
+ definition execute :: "name \<Rightarrow> state \<Rightarrow> state" where
+ "execute name s \<equiv>
+ case lookup_operator name of
+ Some (_,_,effs,_) \<Rightarrow>
+ s ++ map_of (map (\<lambda>(_,x,_,v). (x,v)) (filter (eff_enabled s) effs))
+ | None \<Rightarrow> undefined
+ "
+
+ fun path_to where
+ "path_to s [] s' \<longleftrightarrow> s'=s"
+ | "path_to s (\<pi>#\<pi>s) s' \<longleftrightarrow> enabled \<pi> s \<and> path_to (execute \<pi> s) \<pi>s s'"
+
+ definition valid_plan :: "plan \<Rightarrow> bool"
+ where "valid_plan \<pi>s \<equiv> \<exists>s'\<in>G. path_to I \<pi>s s'"
+
+
+ end
+
+ (*
+ Next steps:
+ * well-formed stuff
+ * Executable SAS+ validator (well_formed and execute function)
+
+ *)
+
+ subsubsection \<open>Preservation of well-formedness\<close>
+ context wf_ast_problem
+ begin
+ lemma I_valid: "I \<in> valid_states"
+ using wf_initial
+ unfolding valid_states_def Dom_def I_def range_of_var_def
+ by (auto split:if_splits)
+
+ lemma lookup_operator_wf:
+ assumes "lookup_operator name = Some \<pi>"
+ shows "wf_operator \<pi>" "fst \<pi> = name"
+ proof -
+ obtain name' pres effs cost where [simp]: "\<pi>=(name',pres,effs,cost)" by (cases \<pi>)
+ hence [simp]: "name'=name" and IN_AST: "(name,pres,effs,cost) \<in> set ast\<delta>"
+ using assms
+ unfolding lookup_operator_def
+ apply -
+ apply (metis (mono_tags, lifting) case_prodD find_Some_iff)
+ by (metis (mono_tags, lifting) case_prodD find_Some_iff nth_mem)
+
+ from IN_AST show WF: "wf_operator \<pi>" "fst \<pi> = name"
+ unfolding enabled_def using wf_operators by auto
+ qed
+
+
+ lemma execute_preserves_valid:
+ assumes "s\<in>valid_states"
+ assumes "enabled name s"
+ shows "execute name s \<in> valid_states"
+ proof -
+ from \<open>enabled name s\<close> obtain name' pres effs cost where
+ [simp]: "lookup_operator name = Some (name',pres,effs,cost)"
+ unfolding enabled_def by (auto split: option.splits)
+ from lookup_operator_wf[OF this] have WF: "wf_operator (name,pres,effs,cost)" by simp
+
+ have X1: "s ++ m \<in> valid_states" if "\<forall>x v. m x = Some v \<longrightarrow> x<numVars \<and> v<numVals x" for m
+ using that \<open>s\<in>valid_states\<close>
+ by (auto
+ simp: valid_states_def Dom_def range_of_var_def map_add_def dom_def
+ split: option.splits)
+
+ have X2: "x<numVars" "v<numVals x"
+ if "map_of (map (\<lambda>(_, x, _, y). (x, y)) (filter (eff_enabled s) effs)) x = Some v"
+ for x v
+ proof -
+ from that obtain epres vp where "(epres,x,vp,v) \<in> set effs"
+ by (auto dest!: map_of_SomeD)
+ with WF show "x<numVars" "v<numVals x"
+ unfolding wf_operator_def by auto
+ qed
+
+ show ?thesis
+ using assms
+ unfolding enabled_def execute_def
+ by (auto intro!: X1 X2)
+ qed
+
+ lemma path_to_pres_valid:
+ assumes "s\<in>valid_states"
+ assumes "path_to s \<pi>s s'"
+ shows "s'\<in>valid_states"
+ using assms
+ by (induction s \<pi>s s' rule: path_to.induct) (auto simp: execute_preserves_valid)
+
+ end
+
+end
diff --git a/thys/AI_Planning_Languages_Semantics/code/Makefile b/thys/AI_Planning_Languages_Semantics/code/Makefile
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/code/Makefile
@@ -0,0 +1,11 @@
+all: PDDL_Checker
+
+PDDL_Checker: PDDL_Checker.mlb PDDL_Checker.sml PDDL_Checker_Exported.sml Unsynchronized.sml
+ mlton -verbose 1 -default-type intinf -output PDDL_Checker PDDL_Checker.mlb
+
+PDDL_Checker_prof: PDDL_Checker.mlb PDDL_Checker.sml PDDL_Checker_Exported.sml Unsynchronized.sml
+ mlton -verbose 1 -default-type intinf -profile time -output PDDL_Checker_prof PDDL_Checker.mlb
+# mlton -verbose 1 -default-type intinf -profile time -const 'Exn.keepHistory true' -output PDDL_Checker_prof PDDL_Checker.mlb
+
+install: PDDL_Checker
+ cp PDDL_Checker "$(HOME)/bin/"
diff --git a/thys/AI_Planning_Languages_Semantics/code/PDDL_Checker.mlb b/thys/AI_Planning_Languages_Semantics/code/PDDL_Checker.mlb
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/code/PDDL_Checker.mlb
@@ -0,0 +1,14 @@
+$(SML_LIB)/basis/basis.mlb
+$(SML_LIB)/basis/mlton.mlb
+$(SML_LIB)/smlnj-lib/Util/smlnj-lib.mlb
+
+local
+ Unsynchronized.sml
+ ann "nonexhaustiveMatch ignore" in
+ PDDL_Checker_Exported.sml
+ end
+in
+ structure PDDL_Checker_Exported
+end
+
+PDDL_Checker.sml
diff --git a/thys/AI_Planning_Languages_Semantics/code/PDDL_Checker.sml b/thys/AI_Planning_Languages_Semantics/code/PDDL_Checker.sml
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/code/PDDL_Checker.sml
@@ -0,0 +1,72 @@
+fun println x = print (x ^ "\n")
+
+fun file_to_string name = let
+ val f = TextIO.openIn name
+ val s = TextIO.inputAll f
+ val _ = TextIO.closeIn f
+in s end
+
+
+fun print_help () = (
+ println("c Usage: " ^ CommandLine.name() ^ "[<options>] <domain> <problem> [<plan>]");
+ println("c Options:");
+ println("c --no-wf-checking Do not check well-formedness.");
+ println("c No guarantees if input not well-formed")
+)
+
+fun verify_plan dom prob plan = let
+ val dom = file_to_string dom
+ val prob = file_to_string prob
+ val plan = file_to_string plan
+ open PDDL_Checker_Exported
+ val chkres = parse_check_dpp_impl dom prob plan
+in
+ case chkres of
+ Inl msg => println ("s ERROR: " ^ msg)
+ | Inr _ => println ("s VERIFIED")
+end
+
+fun verify_plan_assum_wf dom prob plan = let
+ val dom = file_to_string dom
+ val prob = file_to_string prob
+ val plan = file_to_string plan
+ open PDDL_Checker_Exported
+ val chkres = parse_check_p_impl dom prob plan
+in
+ case chkres of
+ Inl msg => println ("s ERROR: " ^ msg)
+ | Inr _ => println ("s (WELLFORMED ==> VERIFIED)")
+end
+
+
+fun check_dom_prob_wf dom prob = let
+ val dom = file_to_string dom
+ val prob = file_to_string prob
+ open PDDL_Checker_Exported
+ val chkres = parse_check_dp_impl dom prob
+in
+ case chkres of
+ Inl msg => println ("s ERROR: " ^ msg)
+ | Inr _ => println ("s WELLFORMED")
+end
+
+
+fun
+ process_args [dom,prob] = check_dom_prob_wf dom prob
+ | process_args [dom,prob,plan] = verify_plan dom prob plan
+ | process_args ["--no-wf-checking",dom,prob,plan] = verify_plan_assum_wf dom prob plan
+ | process_args _ = (
+ println("s ERROR: Invalid command line arguments");
+ print_help()
+ )
+
+fun main () = let
+ val args = CommandLine.arguments ();
+in
+ process_args args
+end
+
+
+val _ = if MLton.isMLton then main() else ()
+
+
diff --git a/thys/AI_Planning_Languages_Semantics/code/PDDL_Checker_Fluents.mlb b/thys/AI_Planning_Languages_Semantics/code/PDDL_Checker_Fluents.mlb
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/code/PDDL_Checker_Fluents.mlb
@@ -0,0 +1,14 @@
+$(SML_LIB)/basis/basis.mlb
+$(SML_LIB)/basis/mlton.mlb
+$(SML_LIB)/smlnj-lib/Util/smlnj-lib.mlb
+
+local
+ Unsynchronized.sml
+ ann "nonexhaustiveMatch ignore" in
+ PDDL_Checker_Exported.sml
+ end
+in
+ structure PDDL_Checker_Exported
+end
+
+PDDL_Checker.sml
diff --git a/thys/AI_Planning_Languages_Semantics/code/SASP_Checker_Exported.sml b/thys/AI_Planning_Languages_Semantics/code/SASP_Checker_Exported.sml
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/code/SASP_Checker_Exported.sml
@@ -0,0 +1,327 @@
+structure SASP_Checker_Exported : sig
+ type nat
+ val integer_of_nat : nat -> IntInf.int
+ type char
+ datatype ('a, 'b) sum = Inl of 'a | Inr of 'b
+ val implode : char list -> string
+ val explode : string -> char list
+ val verify_plan :
+ (char list * (nat option * (char list) list)) list *
+ (nat list *
+ ((nat * nat) list *
+ (char list *
+ ((nat * nat) list *
+ (((nat * nat) list * (nat * (nat option * nat))) list *
+ nat))) list)) ->
+ (char list) list -> (string, unit) sum
+ val nat_of_integer : IntInf.int -> nat
+ val nat_opt_of_integer : IntInf.int -> nat option
+end = struct
+
+datatype nat = Nat of IntInf.int;
+
+fun integer_of_nat (Nat x) = x;
+
+fun equal_nata m n = (((integer_of_nat m) : IntInf.int) = (integer_of_nat n));
+
+type 'a equal = {equal : 'a -> 'a -> bool};
+val equal = #equal : 'a equal -> 'a -> 'a -> bool;
+
+val equal_nat = {equal = equal_nata} : nat equal;
+
+fun eq A_ a b = equal A_ a b;
+
+fun equal_lista A_ [] (x21 :: x22) = false
+ | equal_lista A_ (x21 :: x22) [] = false
+ | equal_lista A_ (x21 :: x22) (y21 :: y22) =
+ eq A_ x21 y21 andalso equal_lista A_ x22 y22
+ | equal_lista A_ [] [] = true;
+
+fun equal_list A_ = {equal = equal_lista A_} : ('a list) equal;
+
+fun equal_bool p true = p
+ | equal_bool p false = not p
+ | equal_bool true p = p
+ | equal_bool false p = not p;
+
+datatype char = Chara of bool * bool * bool * bool * bool * bool * bool * bool;
+
+fun equal_chara (Chara (x1, x2, x3, x4, x5, x6, x7, x8))
+ (Chara (y1, y2, y3, y4, y5, y6, y7, y8)) =
+ equal_bool x1 y1 andalso
+ (equal_bool x2 y2 andalso
+ (equal_bool x3 y3 andalso
+ (equal_bool x4 y4 andalso
+ (equal_bool x5 y5 andalso
+ (equal_bool x6 y6 andalso
+ (equal_bool x7 y7 andalso equal_bool x8 y8))))));
+
+val equal_char = {equal = equal_chara} : char equal;
+
+datatype num = One | Bit0 of num | Bit1 of num;
+
+val one_integera : IntInf.int = (1 : IntInf.int);
+
+type 'a one = {one : 'a};
+val one = #one : 'a one -> 'a;
+
+val one_integer = {one = one_integera} : IntInf.int one;
+
+type 'a zero = {zero : 'a};
+val zero = #zero : 'a zero -> 'a;
+
+val zero_integer = {zero = (0 : IntInf.int)} : IntInf.int zero;
+
+type 'a ord = {less_eq : 'a -> 'a -> bool, less : 'a -> 'a -> bool};
+val less_eq = #less_eq : 'a ord -> 'a -> 'a -> bool;
+val less = #less : 'a ord -> 'a -> 'a -> bool;
+
+val ord_integer =
+ {less_eq = (fn a => fn b => IntInf.<= (a, b)),
+ less = (fn a => fn b => IntInf.< (a, b))}
+ : IntInf.int ord;
+
+type 'a zero_neq_one = {one_zero_neq_one : 'a one, zero_zero_neq_one : 'a zero};
+val one_zero_neq_one = #one_zero_neq_one : 'a zero_neq_one -> 'a one;
+val zero_zero_neq_one = #zero_zero_neq_one : 'a zero_neq_one -> 'a zero;
+
+val zero_neq_one_integer =
+ {one_zero_neq_one = one_integer, zero_zero_neq_one = zero_integer} :
+ IntInf.int zero_neq_one;
+
+datatype ('a, 'b) sum = Inl of 'a | Inr of 'b;
+
+fun plus_nat m n = Nat (IntInf.+ (integer_of_nat m, integer_of_nat n));
+
+val one_nat : nat = Nat (1 : IntInf.int);
+
+fun suc n = plus_nat n one_nat;
+
+fun max A_ a b = (if less_eq A_ a b then b else a);
+
+fun minus_nat m n =
+ Nat (max ord_integer (0 : IntInf.int)
+ (IntInf.- (integer_of_nat m, integer_of_nat n)));
+
+val zero_nat : nat = Nat (0 : IntInf.int);
+
+fun nth (x :: xs) n =
+ (if equal_nata n zero_nat then x else nth xs (minus_nat n one_nat));
+
+fun find uu [] = NONE
+ | find p (x :: xs) = (if p x then SOME x else find p xs);
+
+fun fold f (x :: xs) s = fold f xs (f x s)
+ | fold f [] s = s;
+
+fun fun_upd A_ f a b = (fn x => (if eq A_ x a then b else f x));
+
+fun filter p [] = []
+ | filter p (x :: xs) = (if p x then x :: filter p xs else filter p xs);
+
+fun member A_ [] y = false
+ | member A_ (x :: xs) y = eq A_ x y orelse member A_ xs y;
+
+fun distinct A_ [] = true
+ | distinct A_ (x :: xs) = not (member A_ xs x) andalso distinct A_ xs;
+
+fun map f [] = []
+ | map f (x21 :: x22) = f x21 :: map f x22;
+
+fun of_bool A_ true = one (one_zero_neq_one A_)
+ | of_bool A_ false = zero (zero_zero_neq_one A_);
+
+fun integer_of_char (Chara (b0, b1, b2, b3, b4, b5, b6, b7)) =
+ IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (of_bool
+ zero_neq_one_integer
+ b7, (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b6), (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b5), (2 : IntInf.int)), of_bool
+ zero_neq_one_integer
+ b4), (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b3), (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b2), (2 : IntInf.int)), of_bool
+ zero_neq_one_integer
+ b1), (2 : IntInf.int)), of_bool zero_neq_one_integer b0);
+
+fun implode cs =
+ (String.implode
+ o List.map (fn k => if 0 <= k andalso k < 128 then (Char.chr o IntInf.toInt) k else raise Fail "Non-ASCII character in literal"))
+ (map integer_of_char cs);
+
+fun gen_length n (x :: xs) = gen_length (suc n) xs
+ | gen_length n [] = n;
+
+fun list_all p [] = true
+ | list_all p (x :: xs) = p x andalso list_all p xs;
+
+fun less_eq_nat m n = IntInf.<= (integer_of_nat m, integer_of_nat n);
+
+fun all_interval_nat p i j =
+ less_eq_nat j i orelse p i andalso all_interval_nat p (suc i) j;
+
+fun fst (x1, x2) = x1;
+
+fun snd (x1, x2) = x2;
+
+fun equal_option A_ NONE (SOME x2) = false
+ | equal_option A_ (SOME x2) NONE = false
+ | equal_option A_ (SOME x2) (SOME y2) = eq A_ x2 y2
+ | equal_option A_ NONE NONE = true;
+
+fun match_pre x =
+ (fn (xa, v) => fn s => equal_option equal_nat (s xa) (SOME v)) x;
+
+fun bit_cut_integer k =
+ (if ((k : IntInf.int) = (0 : IntInf.int)) then ((0 : IntInf.int), false)
+ else let
+ val (r, s) =
+ IntInf.divMod (IntInf.abs k, IntInf.abs (2 : IntInf.int));
+ in
+ ((if IntInf.< ((0 : IntInf.int), k) then r
+ else IntInf.- (IntInf.~ r, s)),
+ ((s : IntInf.int) = (1 : IntInf.int)))
+ end);
+
+fun char_of_integer k = let
+ val (q0, b0) = bit_cut_integer k;
+ val (q1, b1) = bit_cut_integer q0;
+ val (q2, b2) = bit_cut_integer q1;
+ val (q3, b3) = bit_cut_integer q2;
+ val (q4, b4) = bit_cut_integer q3;
+ val (q5, b5) = bit_cut_integer q4;
+ val (q6, b6) = bit_cut_integer q5;
+ val a = bit_cut_integer q6;
+ val (_, aa) = a;
+ in
+ Chara (b0, b1, b2, b3, b4, b5, b6, aa)
+ end;
+
+fun explode s =
+ map char_of_integer
+ ((List.map (fn c => let val k = Char.ord c in if k < 128 then IntInf.fromInt k else raise Fail "Non-ASCII character in literal" end)
+ o String.explode)
+ s);
+
+fun match_pres pres s = list_all (fn pre => match_pre pre s) pres;
+
+fun astG problem = let
+ val (_, (_, (g, _))) = problem;
+ in
+ g
+ end;
+
+fun lookup_operator x =
+ (fn (_, (_, (_, delta))) => fn name =>
+ find (fn (n, (_, (_, _))) => equal_lista equal_char n name) delta)
+ x;
+
+fun eff_enabled s = (fn (pres, (_, (_, _))) => match_pres pres s);
+
+fun execute_opr x =
+ (fn (_, (_, (effs, _))) => fn s =>
+ let
+ val effsa = filter (eff_enabled s) effs;
+ in
+ fold (fn (_, (xa, (_, v))) => fn sa => fun_upd equal_nat sa xa (SOME v))
+ effsa s
+ end)
+ x;
+
+fun match_implicit_pres effs s =
+ list_all
+ (fn a =>
+ (case a of (_, (_, (NONE, _))) => true
+ | (_, (x, (SOME v, _))) => equal_option equal_nat (s x) (SOME v)))
+ effs;
+
+fun enabled_opr x =
+ (fn (_, (pres, (effs, _))) => fn s =>
+ match_pres pres s andalso match_implicit_pres effs s)
+ x;
+
+fun simulate_plan problem (pi :: pi_s) s =
+ (case lookup_operator problem pi of NONE => NONE
+ | SOME pia =>
+ (if enabled_opr pia s then simulate_plan problem pi_s (execute_opr pia s)
+ else NONE))
+ | simulate_plan problem [] s = SOME s;
+
+fun astI problem = let
+ val (_, (i, (_, _))) = problem;
+ in
+ i
+ end;
+
+fun size_list x = gen_length zero_nat x;
+
+fun less_nat m n = IntInf.< (integer_of_nat m, integer_of_nat n);
+
+fun initial_state problem =
+ let
+ val astIa = astI problem;
+ in
+ (fn v =>
+ (if less_nat v (size_list astIa) then SOME (nth astIa v) else NONE))
+ end;
+
+fun check_plan problem pi_s =
+ (case simulate_plan problem pi_s (initial_state problem) of NONE => false
+ | SOME a => match_pres (astG problem) a);
+
+fun astDom problem = let
+ val (d, (_, (_, _))) = problem;
+ in
+ d
+ end;
+
+fun numVars problem = size_list (astDom problem);
+
+fun numVals problem x = size_list (snd (snd (nth (astDom problem) x)));
+
+fun wf_partial_state problem ps =
+ distinct equal_nat (map fst ps) andalso
+ list_all
+ (fn (x, v) =>
+ less_nat x (numVars problem) andalso less_nat v (numVals problem x))
+ ps;
+
+fun wf_operator problem =
+ (fn (_, (pres, (effs, _))) =>
+ wf_partial_state problem pres andalso
+ (distinct equal_nat (map (fn (_, (v, (_, _))) => v) effs) andalso
+ list_all
+ (fn (epres, (x, (vp, v))) =>
+ wf_partial_state problem epres andalso
+ (less_nat x (numVars problem) andalso
+ (less_nat v (numVals problem x) andalso
+ (case vp of NONE => true
+ | SOME va => less_nat va (numVals problem x)))))
+ effs));
+
+fun ast_delta problem = let
+ val (_, (_, (_, delta))) = problem;
+ in
+ delta
+ end;
+
+fun well_formed problem =
+ equal_nata (size_list (astI problem)) (numVars problem) andalso
+ (all_interval_nat
+ (fn x => less_nat (nth (astI problem) x) (numVals problem x)) zero_nat
+ (numVars problem) andalso
+ (wf_partial_state problem (astG problem) andalso
+ (distinct (equal_list equal_char) (map fst (ast_delta problem)) andalso
+ list_all (wf_operator problem) (ast_delta problem))));
+
+fun verify_plan problem pi_s =
+ (if well_formed problem
+ then (if check_plan problem pi_s then Inr () else Inl "Invalid plan")
+ else Inl "Problem not well formed");
+
+fun nat_of_integer k = Nat (max ord_integer (0 : IntInf.int) k);
+
+fun nat_opt_of_integer i =
+ (if IntInf.<= ((0 : IntInf.int), i) then SOME (nat_of_integer i) else NONE);
+
+end; (*struct SASP_Checker_Exported*)
diff --git a/thys/AI_Planning_Languages_Semantics/code/Unsynchronized.sml b/thys/AI_Planning_Languages_Semantics/code/Unsynchronized.sml
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/code/Unsynchronized.sml
@@ -0,0 +1,6 @@
+structure Unsynchronized =
+struct
+
+datatype ref = datatype ref;
+
+end;
diff --git a/thys/AI_Planning_Languages_Semantics/document/root.bib b/thys/AI_Planning_Languages_Semantics/document/root.bib
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/document/root.bib
@@ -0,0 +1,2105 @@
+@string{lncs = "Lecture Notes in Computer Science"}
+
+@techreport{PDDLref,
+ author = {Mc{D}ermott, Drew and Ghallab, Malik and Howe, Adele and Knoblock, Craig and Ram, Ashwin and Veloso, Manuela and Weld, Daniel and Wilkins, David},
+ institution = {CVC TR-98-003/DCS TR-1165, Yale Center for Computational Vision and Control},
+ priority = {2},
+ title = {{PDDL: The Planning Domain Definition Language}},
+ year = {1998}
+}
+
+@inproceedings{BiereCCZ99,
+ author = {Armin Biere and
+ Alessandro Cimatti and
+ Edmund M. Clarke and
+ Yunshan Zhu},
+ title = {Symbolic Model Checking without {BDDs}},
+ booktitle = {{TACAS}},
+ pages = {193--207},
+ year = {1999}
+}
+
+@inproceedings{KroeningS03,
+ author = {Daniel Kroening and
+ Ofer Strichman},
+ title = {Efficient Computation of Recurrence Diameters},
+ booktitle = {{VMCAI}},
+ pages = {298--309},
+ year = {2003}
+}
+
+
+@inproceedings{Rintanen:Gretton:2013,
+ author = {Jussi Rintanen and
+ Charles Orgill Gretton},
+ title = {Computing Upper Bounds on Lengths of Transition Sequences},
+ booktitle = {International Joint Conference on Artificial Intelligence},
+ year = {2013}
+}
+
+@inproceedings{sievers:etal:12,
+ author = {S. Sievers and
+ M. Ortlieb and
+ M. Helmert},
+ title = {Efficient Implementation of Pattern Database Heuristics
+ for Classical Planning},
+ booktitle = {Proc. 5th Annual Symposium on Combinatorial Search},
+ year = {2012},
+ ee = {http://www.aaai.org/ocs/index.php/SOCS/SOCS12/paper/view/5375},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{sang:etal:05,
+ author = {T. Sang and
+ P. Beame and
+ H. A. Kautz},
+ title = {Heuristics for Fast Exact Model Counting},
+ booktitle = {Proc. 8th International Conference on Theory and Applications of Satisfiability Testing},
+ publisher = {Springer-Verlag},
+ year = {2005},
+ pages = {226--240},
+ ee = {http://dx.doi.org/10.1007/11499107_17},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+
+
+@article{luna:etal:07,
+ author = {G. Luna and
+ P. Bello L{\'o}pez and
+ M. C. Gonz{\'a}lez},
+ title = {New Polynomial Classes for \#2{SAT} Established Via Graph-Topological
+ Structure},
+ journal = {Engineering Letters},
+ volume = {15},
+ number = {2},
+ year = {2007},
+ pages = {250--258},
+ ee = {http://www.engineeringletters.com/issues_v15/issue_2/EL_15_2_11.pdf},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{streeter:07,
+ author = {M. J. Streeter and
+ S. F. Smith},
+ title = {Using Decision Procedures Efficiently for Optimization},
+ booktitle = {Proc. 17th International Conference on Automated Planning and Scheduling},
+ publisher = {AAAI Press},
+ year = {2007},
+ pages = {312--319},
+ ee = {http://www.aaai.org/Library/ICAPS/2007/icaps07-040.php},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@article{gimenez:jonsson:12,
+ author = {O. Gim{\'e}nez and
+ A. Jonsson},
+ title = {The influence of k-dependence on the complexity of planning},
+ journal = {Artificial Intelligence},
+ volume = {177-179},
+ year = {2012},
+ pages = {25--45},
+ ee = {http://dx.doi.org/10.1016/j.artint.2011.12.002},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@article{JonssonB98,
+ author = {Peter Jonsson and
+ Christer B{\"a}ckstr{\"o}m},
+ title = {State-Variable Planning Under Structural Restrictions: Algorithms
+ and Complexity},
+ journal = {Artificial Intelligence},
+ volume = {100},
+ number = {1-2},
+ year = {1998},
+ pages = {125-176}
+}
+
+@article{brafman:domshlak:03,
+ author = {R. I. Brafman and
+ C. Domshlak},
+ title = {Structure and Complexity in Planning with Unary Operators},
+ journal = {Journal of Artificial Intelligence Research},
+ volume = {18},
+ year = {2003},
+ pages = {315--349},
+ ee = {http://dx.doi.org/10.1613/jair.1146},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@article{bylander:94,
+ author = {T. Bylander},
+ title = {The Computational Complexity of Propositional {STRIPS} Planning},
+ journal = {Artificial Intelligence},
+ volume = {69},
+ number = {1-2},
+ year = {1994},
+ pages = {165--204},
+ ee = {http://dx.doi.org/10.1016/0004-3702(94)90081-7},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{williams:nayak:97,
+ author = {Brian C. Williams and
+ P. Pandurang Nayak},
+ title = {A Reactive Planner for a Model-based Executive},
+ booktitle = {International Joint Conference on Artificial Intelligence},
+ publisher = {Morgan Kaufmann Publishers},
+ year = {1997},
+ pages = {1178--1185},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@article{knoblock:94,
+ author = {C. A. Knoblock},
+ title = {Automatically Generating Abstractions for Planning},
+ journal = {Artificial Intelligence},
+ volume = {68},
+ number = {2},
+ year = {1994},
+ pages = {243--302},
+ ee = {http://dx.doi.org/10.1016/0004-3702(94)90069-8},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+
+@article{rintanen:12,
+ author = {Jussi Rintanen},
+ title = {Planning as satisfiability: Heuristics},
+ journal = {Artificial Intelligence},
+ volume = {193},
+ year = {2012},
+ pages = {45--86},
+ ee = {http://dx.doi.org/10.1016/j.artint.2012.08.001},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{haslum:07,
+ author = {Patrik Haslum},
+ title = {Quality of Solutions to {IPC5} Benchmark Problems: Preliminary Results},
+ booktitle = {ICAPS workshop on the IPC: Past, Present and Future},
+ year = {2007}
+}
+
+@article{Helmert06,
+ author = {Malte Helmert},
+ title = {The {Fast} {Downward} Planning System},
+ journal = {Journal of Artificial Intelligence Research},
+ volume = {26},
+ year = {2006},
+ pages = {191-246}
+}
+
+
+@inproceedings{haslum:etal:07,
+ author = {P. Haslum and
+ A. Botea and
+ M. Helmert and
+ B. Bonet and
+ S. Koenig},
+ title = {Domain-Independent Construction of Pattern Database Heuristics
+ for Cost-Optimal Planning},
+ booktitle = {Proc 22nd AAAI Conf. on Artificial Intelligence},
+ publisher = {AAAI Press},
+ year = {2007},
+ pages = {1007--1012},
+ ee = {http://www.aaai.org/Library/AAAI/2007/aaai07-160.php},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+
+
+@inproceedings{kautz:selman:96,
+ author = {H. A. Kautz and
+ B. Selman},
+ title = {Pushing the Envelope: Planning, Propositional Logic and
+ Stochastic Search},
+ booktitle = {Proc. 13th National Conf. on Artificial Intelligence},
+ year = {1996},
+ publisher = {AAAI Press},
+ pages = {1194--1201},
+ ee = {http://www.aaai.org/Library/AAAI/1996/aaai96-177.php},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+
+@inproceedings{kautz:selman:92,
+ author = {H. A. Kautz and
+ B. Selman},
+ title = {Planning as Satisfiability},
+ booktitle = {ECAI},
+ year = {1992},
+ pages = {359--363},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@book{abelson-et-al:scheme,
+ author = {Harold Abelson and Gerald~Jay Sussman and Julie Sussman},
+ title = {Structure and Interpretation of Computer Programs},
+ publisher = {MIT Press},
+ address = {Cambridge, Massachusetts},
+ year = {1985}
+}
+
+@inproceedings{HOLsystem,
+ author = {Konrad Slind and Michael Norrish},
+ title = {A Brief Overview of {HOL4}},
+ booktitle = {TPHOLs},
+ year = 2008
+}
+
+@inproceedings{HOLsystemL,
+ author = {Konrad Slind and Michael Norrish},
+ title = {A Brief Overview of {HOL4}},
+ booktitle = {Theorem Proving in Higher Order Logics},
+ pages = {28--32},
+ year = 2008,
+ volume = 5170,
+ series = {LNCS},
+ publisher = {Springer}
+}
+
+
+@inproceedings{anonymous,
+ author = {Hidden},
+ title = {Title hidden to preserve anonymity.},
+ booktitle = {Hidden},
+ year = {2014}
+}
+
+
+@inproceedings{Selman94,
+ title = {Near-optimal plans, tractability, and reactivity},
+ author = {Selman, Bart},
+ booktitle = {KR},
+ pages = {521--529},
+ year = {1994}
+}
+
+@article{cooper:etal:11,
+ author = {M. C. Cooper and
+ M. de Roquemaurel and
+ P. R{\'e}gnier},
+ title = {A weighted {CSP} approach to cost-optimal planning},
+ journal = {AI Commun.},
+ volume = {24},
+ number = {1},
+ year = {2011},
+ pages = {1--9},
+ ee = {http://dx.doi.org/10.3233/AIC-2010-0473},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{gerevini:schubert:98,
+ author = {A. Gerevini and
+ L. K. Schubert},
+ title = {Inferring State Constraints for Domain-Independent Planning},
+ booktitle = {Proc. 15th National Conf. on Artificial Intelligence},
+ publisher = {AAAI Press},
+ year = {1998},
+ pages = {905--912},
+ ee = {http://www.aaai.org/Library/AAAI/1998/aaai98-128.php},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+
+
+@article{JonssonBackstrom98b,
+ author = {P. Jonsson and
+ C. B{\"a}ckstr{\"o}m},
+ title = {Tractable Plan Existence Does Not Imply Tractable Plan Generation},
+ journal = {Ann. Math. Artificial Intelligence},
+ volume = {22},
+ number = {3-4},
+ year = {1998},
+ pages = {281--296},
+ ee = {http://dx.doi.org/10.1023/A:1018995620232},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@article{hart:etal:68,
+ author = {P. E. Hart and
+ N. J. Nilsson and
+ B. Raphael},
+ title = {A Formal Basis for the Heuristic Determination of Minimum
+ Cost Paths},
+ journal = {IEEE Trans. Systems Science and Cybernetics},
+ volume = {4},
+ number = {2},
+ year = {1968},
+ pages = {100--107},
+ ee = {http://dx.doi.org/10.1109/TSSC.1968.300136},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+@inproceedings{haslum:geffner:00,
+ author = {P. Haslum and
+ H. Geffner},
+ title = {Admissible Heuristics for Optimal Planning},
+ booktitle = {Proc. Int. Conf. on AI Planning Systems},
+ year = {2000},
+ pages = {140--149},
+ ee = {http://www.aaai.org/Library/AIPS/2000/aips00-015.php},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@article{drager:etal:09,
+ author = {K. Dr{\"a}ger and
+ B. Finkbeiner and
+ A. Podelski},
+ title = {Directed model checking with distance-preserving abstractions},
+ journal = {STTT},
+ volume = {11},
+ number = {1},
+ year = {2009},
+ pages = {27--37},
+ ee = {http://dx.doi.org/10.1007/s10009-008-0092-z},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@article{bonet:geffner:01,
+ author = {Blai Bonet and
+ Hector Geffner},
+ title = {Planning as heuristic search},
+ journal = {Artificial Intelligence},
+ volume = {129},
+ number = {1-2},
+ year = {2001},
+ pages = {5--33},
+ ee = {http://dx.doi.org/10.1016/S0004-3702(01)00108-4},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+
+
+@inproceedings{korf:97,
+ author = {R. E. Korf},
+ title = {Finding Optimal Solutions to {R}ubik's Cube Using Pattern
+ Databases},
+ booktitle = {Proc. 14th National Conf. on Artificial Intelligence},
+ publisher = {AAAI Press},
+ year = {1997},
+ pages = {700--705},
+ ee = {http://www.aaai.org/Library/AAAI/1997/aaai97-109.php},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+
+@inproceedings{culberson:schaeffer:96,
+ author = {J. C. Culberson and
+ J. Schaeffer},
+ title = {Searching with Pattern Databases},
+ booktitle = {Canadian Conf. on AI},
+ publisher = {Springer-Verlag},
+ year = {1996},
+ pages = {402--416},
+ ee = {http://dx.doi.org/10.1007/3-540-61291-2_68},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@article{tarjan:72,
+ author = {R. E. Tarjan},
+ title = {Depth-First Search and Linear Graph Algorithms},
+ journal = {SIAM J. Comput.},
+ volume = {1},
+ number = {2},
+ year = {1972},
+ pages = {146--160},
+ ee = {http://dx.doi.org/10.1137/0201010},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{rintanen:08,
+ author = {Rintanen, Jussi},
+ title = {Regression for classical and nondeterministic planning},
+ booktitle = {Proc. 18th European Conf. on AI},
+ publisher = {IOS Press},
+ pages = {568--571},
+ year = 2008
+}
+
+@inproceedings{rintanen:04,
+ author = {Jussi Rintanen},
+ title = {Evaluation Strategies for Planning as Satisfiability},
+ booktitle = {Proc. 16th European Conf. on Artificial Intelligence},
+ publisher = {IOS Press},
+ year = {2004},
+ pages = {682--687},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+@inproceedings{robinson09,
+ author = {Nathan Robinson and
+ Charles Gretton and
+ Duc Nghia Pham and
+ Abdul Sattar},
+ title = {{SAT}-Based Parallel Planning Using a Split Representation
+ of Actions},
+ booktitle = {ICAPS},
+ year = {2009}
+}
+
+@inproceedings{bgf:Lixto,
+ author = {Robert Baumgartner and Georg Gottlob and Sergio Flesca},
+ title = {Visual Information Extraction with {Lixto}},
+ booktitle = {Proceedings of the 27th Intnl. Conf. on Very Large Databases},
+ pages = {119-128},
+ publisher = {Morgan Kaufmann},
+ address = {Rome, Italy},
+ month = {September},
+ year = {2001}
+}
+
+@article{brachman-schmolze:kl-one,
+ author = {Ronald~J. Brachman and James~G. Schmolze},
+ title = {An overview of the {KL-ONE} knowledge representation system},
+ journal = {Cognitive Science},
+ volume = {9},
+ number = {2},
+ pages = {171--216},
+ month = {April--June},
+ year = {1985}
+}
+
+@article{gottlob:nonmon,
+ author = {Georg Gottlob},
+ title = {Complexity results for nonmonotonic logics},
+ journal = {Journal of Logic and Computation},
+ volume = {2},
+ number = {3},
+ pages = {397--425},
+ month = {June},
+ year = {1992}
+}
+
+@article{gls:hypertrees,
+ author = {Georg Gottlob and Nicola Leone and Francesco Scarcello},
+ title = {Hypertree Decompositions and Tractable Queries},
+ journal = {Journal of Computer and System Sciences},
+ volume = {64},
+ number = {3},
+ pages = {579--627},
+ month = {May},
+ year = {2002}
+}
+
+@article{levesque:functional-foundations,
+ author = {Hector~J. Levesque},
+ title = {Foundations of a functional approach to knowledge representation},
+ journal = {Artificial Intelligence},
+ volume = {23},
+ number = {2},
+ pages = {155--212},
+ month = {July},
+ year = {1984}
+}
+
+@inproceedings{levesque:belief,
+ author = {Hector~J. Levesque},
+ title = {A logic of implicit and explicit belief},
+ booktitle = {Proceedings of the Fourth National Conf. on Artificial Intelligence},
+ publisher = {American Association for Artificial Intelligence},
+ pages = {198--202},
+ address = {Austin, Texas},
+ month = {August},
+ year = {1984}
+}
+
+@article{nebel:jair-2000,
+ author = {Bernhard Nebel},
+ title = {On the compilability and expressive power of propositional planning formalisms},
+ journal = {Journal of Artificial Intelligence Research},
+ volume = {12},
+ pages = {271--315},
+ year = {2000}
+}
+
+@book{hodges1993model,
+ title = {Model theory},
+ author = {Hodges, Wilfrid},
+ volume = {42},
+ year = {1993},
+ publisher = {Cambridge University Press Cambridge}
+}
+
+@book{jackson2006:alloy-book,
+ author = {Daniel Jackson},
+ title = {Software Abstractions: Logic, Language, and Analysis},
+ publisher = {{MIT} Press},
+ year = {2006},
+ isbn = {978-0-262-10114-1},
+ timestamp = {Fri, 20 Oct 4446299 22:18:08 +},
+ biburl = {http://dblp.uni-trier.de/rec/bib/books/daglib/0024034},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+@inproceedings{Nipkow-ICTAC06,
+ author = {Tobias Nipkow},
+ title = {Verifying a Hotel Key Card System},
+ booktitle = {Theoretical Aspects of Computing (ICTAC 2006)},
+ editor = {K. Barkaoui and A. Cavalcanti and A. Cerone},
+ publisher = {Springer},
+ series = LNCS,
+ volume = 4281,
+ year = 2006,
+ note = {Invited paper.}
+}
+
+@inproceedings{baumgartner2002property,
+ title = {Property Checking Via Structural Analysis},
+ author = {Baumgartner, Jason and Kuehlmann, Andreas and Abraham, Jacob},
+ booktitle = {Computer Aided Verification},
+ pages = {151--165},
+ year = {2002},
+ organization = {Springer}
+}
+
+@inproceedings{BlanchetteN10,
+ author = {Jasmin Christian Blanchette and
+ Tobias Nipkow},
+ title = {Nitpick: {A} Counterexample Generator for Higher-Order Logic Based
+ on a Relational Model Finder},
+ booktitle = {Interactive Theorem Proving, First International Conference, {ITP}
+ 2010},
+ pages = {131--146},
+ year = {2010},
+ doi = {10.1007/978-3-642-14052-5_11},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+@inproceedings{DBLP:conf/date/BaumgartnerK04,
+ author = {Jason Baumgartner and
+ Andreas Kuehlmann},
+ title = {Enhanced Diameter Bounding via Structural Analysis},
+ booktitle = {{DATE} 2004, 16-20 February 2004, Paris, France},
+ pages = {36--41},
+ year = {2004},
+ doi = {10.1109/DATE.2004.1268824},
+ timestamp = {Wed, 26 Oct 2011 12:00:27 +0200},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/date/BaumgartnerK04},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+
+@article{DBLP:journals/ac/BiereCCSZ03,
+ author = {Armin Biere and
+ Alessandro Cimatti and
+ Edmund M. Clarke and
+ Ofer Strichman and
+ Yunshan Zhu},
+ title = {Bounded model checking},
+ journal = {Advances in Computers},
+ volume = {58},
+ pages = {117--148},
+ year = {2003}
+}
+
+@inproceedings{DBLP:conf/fmcad/SheeranSS00,
+ author = {Mary Sheeran and
+ Satnam Singh and
+ Gunnar St{\aa}lmarck},
+ title = {Checking Safety Properties Using Induction and a {SAT}-Solver},
+ booktitle = {Formal Methods in Computer-Aided Design, Third International Conference,
+ {FMCAD} 2000, Austin, Texas, USA, November 1-3, 2000, Proceedings},
+ pages = {108--125},
+ year = {2000},
+ doi = {10.1007/3-540-40922-X_8},
+ timestamp = {Tue, 21 Jun 2011 16:40:02 +0200},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/fmcad/SheeranSS00},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+@inproceedings{DBLP:conf/nca/SastryW14,
+ author = {Srikanth Sastry and
+ Josef Widder},
+ title = {Solvability-Based Comparison of Failure Detectors},
+ booktitle = {2014 {IEEE} 13th International Symposium on Network Computing and
+ Applications, {NCA} 2014, Cambridge, MA, USA, 21-23 August, 2014},
+ pages = {269--276},
+ year = {2014},
+ doi = {10.1109/NCA.2014.46},
+ timestamp = {Tue, 25 Nov 2014 17:05:18 +0100},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/nca/SastryW14},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+
+@inproceedings{DBLP:conf/date/GanaiG08,
+ author = {Malay K. Ganai and
+ Aarti Gupta},
+ title = {Completeness in {SMT}-based {BMC} for Software Programs},
+ booktitle = {Design, Automation and Test in Europe, {DATE} 2008, Munich, Germany,
+ March 10-14, 2008},
+ pages = {831--836},
+ year = {2008},
+ doi = {10.1109/DATE.2008.4484777},
+ timestamp = {Mon, 21 Sep 2009 09:13:26 +0200},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/date/GanaiG08},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+@inproceedings{DBLP:conf/fmcad/CaseMBK09,
+ author = {Michael L. Case and
+ Hari Mony and
+ Jason Baumgartner and
+ Robert Kanzelman},
+ title = {Enhanced verification by temporal decomposition},
+ booktitle = {{FMCAD} 2009, 15-18 November 2009, Austin, Texas, {USA}},
+ pages = {17--24},
+ year = {2009},
+ timestamp = {Wed, 27 Jan 2010 15:12:16 +0100},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/fmcad/CaseMBK09},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+
+@article{soares1992maximum,
+ title = {Maximum diameter of regular digraphs},
+ author = {Soares, Jos{\'e}},
+ journal = {Journal of Graph Theory},
+ volume = {16},
+ number = {5},
+ pages = {437--450},
+ year = {1992},
+ publisher = {Wiley Online Library}
+}
+
+@article{erdHos1989radius,
+ title = {Radius, diameter, and minimum degree},
+ author = {Erd{\H{o}}s, Paul and Pach, Janos and Pollack, Richard and Tuza, Zsolt},
+ journal = {Journal of Combinatorial Theory, Series B},
+ volume = {47},
+ number = {1},
+ pages = {73--79},
+ year = {1989},
+ publisher = {Elsevier}
+}
+
+@article{moon1965diameter,
+ title = {On the diameter of a graph.},
+ author = {Moon, John W and others},
+ journal = {The Michigan Mathematical Journal},
+ volume = {12},
+ number = {3},
+ pages = {349--351},
+ year = {1965},
+ publisher = {The University of Michigan}
+}
+
+@article{knyazev1987diameters,
+ title = {Diameters of pseudosymmetric graphs},
+ author = {Knyazev, AV},
+ journal = {Mathematical Notes},
+ volume = {41},
+ number = {6},
+ pages = {473--482},
+ year = {1987},
+ publisher = {Springer}
+}
+
+@article{dankelmann2005diameter,
+ title = {The diameter of directed graphs},
+ author = {Dankelmann, Peter},
+ journal = {Journal of Combinatorial Theory, Series B},
+ volume = {94},
+ number = {1},
+ pages = {183--186},
+ year = {2005},
+ publisher = {Elsevier}
+}
+
+@article{dankelmann2010diameter,
+ title = {The diameter of almost Eulerian digraphs},
+ author = {Dankelmann, Peter and Volkmann, Lutz},
+ journal = {the electronic journal of combinatorics},
+ volume = {17},
+ number = {1},
+ pages = {R157},
+ year = {2010}
+}
+
+@article{dankelmann2016diameter,
+ title = {Diameter and maximum degree in Eulerian digraphs},
+ author = {Dankelmann, Peter and Dorfling, Michael},
+ journal = {Discrete Mathematics},
+ volume = {339},
+ number = {4},
+ pages = {1355--1361},
+ year = {2016},
+ publisher = {North-Holland}
+}
+
+@inproceedings{clarke2001progress,
+ title = {Progress on the state explosion problem in model checking},
+ author = {Clarke, Edmund and Grumberg, Orna and Jha, Somesh and Lu, Yuan and Veith, Helmut},
+ booktitle = {Informatics},
+ pages = {176--194},
+ year = {2001},
+ organization = {Springer}
+}
+
+
+@inproceedings{kroening2011linear,
+ title = {Linear completeness thresholds for bounded model checking},
+ author = {Kroening, Daniel and Ouaknine, Jo{\"e}l and Strichman, Ofer and Wahl, Thomas and Worrell, James},
+ booktitle = {Computer Aided Verification},
+ pages = {557--572},
+ year = {2011},
+ organization = {Springer}
+}
+
+@inproceedings{bundala2012magnitude,
+ title = {On the magnitude of completeness thresholds in bounded model checking},
+ author = {Bundala, Daniel and Ouaknine, Jo{\"e}l and Worrell, James},
+ booktitle = {Proceedings of the 2012 27th Annual IEEE/ACM Symposium on Logic in Computer Science},
+ pages = {155--164},
+ year = {2012},
+ organization = {IEEE Computer Society}
+}
+
+@article{fikes1971strips,
+ title = {STRIPS: A new approach to the application of theorem proving to problem solving},
+ author = {Fikes, Richard E and Nilsson, Nils J},
+ journal = {Artificial intelligence},
+ volume = {2},
+ number = {3-4},
+ pages = {189--208},
+ year = {1971},
+ publisher = {Elsevier}
+}
+
+@incollection{mcmillan1993symbolic,
+ title = {Symbolic model checking},
+ author = {McMillan, Kenneth L},
+ booktitle = {Symbolic Model Checking},
+ pages = {25--60},
+ year = {1993},
+ publisher = {Springer}
+}
+
+@article{kroening2006computing,
+ title = {Computing over-approximations with bounded model checking},
+ author = {Kroening, Daniel},
+ journal = {Electronic Notes in Theoretical Computer Science},
+ volume = {144},
+ number = {1},
+ pages = {79--92},
+ year = {2006},
+ publisher = {Elsevier}
+}
+
+@article{yuster2010computing,
+ title = {{Computing the diameter polynomially faster than APSP}},
+ author = {Yuster, Raphael},
+ journal = {arXiv preprint arXiv:1011.6181},
+ year = {2010}
+}
+
+@article{asgharian2016approximation,
+ title = {An approximation algorithm for the longest path problem in solid grid graphs},
+ author = {Asgharian Sardroud, Asghar and Bagheri, Alireza},
+ journal = {Optimization Methods and Software},
+ volume = {31},
+ number = {3},
+ pages = {479--493},
+ year = {2016},
+ publisher = {Taylor \& Francis}
+}
+
+@article{bjorklund2003finding,
+ title = {Finding a path of superlogarithmic length},
+ author = {Bj{\"o}rklund, Andreas and Husfeldt, Thore},
+ journal = {SIAM Journal on Computing},
+ volume = {32},
+ number = {6},
+ pages = {1395--1402},
+ year = {2003},
+ publisher = {SIAM}
+}
+
+@inproceedings{bjorklund2004approximating,
+ title = {Approximating longest directed paths and cycles},
+ author = {Bj{\"o}rklund, Andreas and Husfeldt, Thore and Khanna, Sanjeev},
+ booktitle = {International Colloquium on Automata, Languages, and Programming},
+ pages = {222--233},
+ year = {2004},
+ organization = {Springer}
+}
+
+@article{aingworth1999fast,
+ title = {Fast estimation of diameter and shortest paths (without matrix multiplication)},
+ author = {Aingworth, Donald and Chekuri, Chandra and Indyk, Piotr and Motwani, Rajeev},
+ journal = {SIAM Journal on Computing},
+ volume = {28},
+ number = {4},
+ pages = {1167--1181},
+ year = {1999},
+ publisher = {SIAM}
+}
+
+@incollection{berezin1998compositional,
+ title = {Compositional reasoning in model checking},
+ author = {Berezin, Sergey and Campos, S{\'e}rgio and Clarke, Edmund M},
+ booktitle = {Compositionality: The Significant Difference},
+ pages = {81--102},
+ year = {1998},
+ publisher = {Springer}
+}
+
+@article{alon1997exponent,
+ title = {On the exponent of the all pairs shortest path problem},
+ author = {Alon, Noga and Galil, Zvi and Margalit, Oded},
+ journal = {Journal of Computer and System Sciences},
+ volume = {54},
+ number = {2},
+ pages = {255--262},
+ year = {1997},
+ publisher = {Elsevier}
+}
+
+@article{chan2010more,
+ title = {More algorithms for all-pairs shortest paths in weighted graphs},
+ author = {Chan, Timothy M},
+ journal = {SIAM Journal on Computing},
+ volume = {39},
+ number = {5},
+ pages = {2075--2089},
+ year = {2010},
+ publisher = {SIAM}
+}
+
+@article{fredman1976new,
+ title = {New bounds on the complexity of the shortest path problem},
+ author = {Fredman, Michael L},
+ journal = {SIAM Journal on Computing},
+ volume = {5},
+ number = {1},
+ pages = {83--89},
+ year = {1976},
+ publisher = {SIAM}
+}
+
+@inproceedings{chechik2014better,
+ title = {Better approximation algorithms for the graph diameter},
+ author = {Chechik, Shiri and Larkin, Daniel H and Roditty, Liam and Schoenebeck, Grant and Tarjan, Robert E and Williams, Virginia Vassilevska},
+ booktitle = {Proceedings of the Twenty-Fifth Annual ACM-SIAM Symposium on Discrete Algorithms},
+ pages = {1041--1052},
+ year = {2014},
+ organization = {Society for Industrial and Applied Mathematics}
+}
+
+@inproceedings{roditty2013fast,
+ title = {Fast approximation algorithms for the diameter and radius of sparse graphs},
+ author = {Roditty, Liam and Vassilevska Williams, Virginia},
+ booktitle = {Proceedings of the forty-fifth annual ACM symposium on Theory of computing},
+ pages = {515--524},
+ year = {2013},
+ organization = {ACM}
+}
+
+@inproceedings{abboud2016approximation,
+ title = {Approximation and fixed parameter subquadratic algorithms for radius and diameter in sparse graphs},
+ author = {Abboud, Amir and Williams, Virginia Vassilevska and Wang, Joshua},
+ booktitle = {Proceedings of the twenty-seventh annual ACM-SIAM symposium on Discrete Algorithms},
+ pages = {377--391},
+ year = {2016},
+ organization = {SIAM}
+}
+
+@article{alon1995color,
+ title = {Color-coding},
+ author = {Alon, Noga and Yuster, Raphael and Zwick, Uri},
+ journal = {Journal of the ACM (JACM)},
+ volume = {42},
+ number = {4},
+ pages = {844--856},
+ year = {1995},
+ publisher = {ACM}
+}
+
+@article{bulterman2002computing,
+ title = {On computing a longest path in a tree},
+ author = {Bulterman, RW and van der Sommen, FW and Zwaan, Gerard and Verhoeff, Tom and van Gasteren, AJM and Feijen, WHJ},
+ journal = {Information Processing Letters},
+ volume = {81},
+ number = {2},
+ pages = {93--96},
+ year = {2002},
+ publisher = {Elsevier North-Holland, Inc.}
+}
+
+@article{gutin1993finding,
+ title = {Finding a longest path in a complete multipartite digraph},
+ author = {Gutin, Gregory},
+ journal = {SIAM Journal on Discrete Mathematics},
+ volume = {6},
+ number = {2},
+ pages = {270--273},
+ year = {1993},
+ publisher = {SIAM}
+}
+
+@article{clarke2009turing,
+ title = {Turing lecture: model checking--algorithmic verification and debugging},
+ author = {Clarke, Edmund M and Emerson, E Allen and Sifakis, Joseph},
+ journal = {Communications of the ACM},
+ volume = {52},
+ number = {11},
+ pages = {74--84},
+ year = {2009}
+}
+
+@inproceedings{knoblock1991characterizing,
+ title = {Characterizing Abstraction Hierarchies for Planning.},
+ author = {Knoblock, Craig A and Tenenberg, Josh D and Yang, Qiang},
+ booktitle = {AAAI},
+ pages = {692--697},
+ year = {1991}
+}
+
+@inproceedings{clarke2000counterexample,
+ title = {Counterexample-guided abstraction refinement},
+ author = {Clarke, Edmund and Grumberg, Orna and Jha, Somesh and Lu, Yuan and Veith, Helmut},
+ booktitle = {International Conference on Computer Aided Verification},
+ pages = {154--169},
+ year = {2000},
+ organization = {Springer}
+}
+
+@article{sacerdoti1974planning,
+ title = {Planning in a hierarchy of abstraction spaces},
+ author = {Sacerdoti, Earl D},
+ journal = {Artificial intelligence},
+ volume = {5},
+ number = {2},
+ pages = {115--135},
+ year = {1974},
+ publisher = {Elsevier}
+}
+
+@article{seippfast,
+ title = {{Fast Downward Aidos}},
+ author = {Seipp, Jendrik and Pommerening, Florian and Sievers, Silvan and Wehrle, Martin and Fawcett, Chris and Alkhazraji, Yusra}
+}
+
+@inproceedings{clarke2004completeness,
+ title = {Completeness and complexity of bounded model checking},
+ author = {Clarke, Edmund and Kroening, Daniel and Ouaknine, Jo{\"e}l and Strichman, Ofer},
+ booktitle = {International Workshop on Verification, Model Checking, and Abstract Interpretation},
+ pages = {85--96},
+ year = {2004},
+ organization = {Springer}
+}
+
+@inproceedings{uehara2004efficient,
+ title = {Efficient algorithms for the longest path problem},
+ author = {Uehara, Ryuhei and Uno, Yushi},
+ booktitle = {International Symposium on Algorithms and Computation},
+ pages = {871--883},
+ year = {2004},
+ organization = {Springer}
+}
+
+@inproceedings{porco2013automatic,
+ title = {Automatic Reductions from {PH} into {STRIPS} or How to Generate Short Problems with Very Long Solutions.},
+ author = {Porco, Aldo and Machado, Alejandro and Bonet, Blai},
+ booktitle = {ICAPS},
+ year = {2013}
+}
+
+
+
+@article{BrownFP96,
+ author = {Cynthia A. Brown and
+ Larry Finkelstein and
+ Paul Walton Purdom Jr.},
+ title = {Backtrack Searching in the Presence of Symmetry},
+ journal = {Nord. J. Comput.},
+ volume = {3},
+ number = {3},
+ pages = {203--219},
+ year = {1996},
+ timestamp = {Mon, 24 Jul 2006 10:22:32 +0200},
+ biburl = {http://dblp.uni-trier.de/rec/bib/journals/njc/BrownFP96},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+
+@inproceedings{DeMoura:2008:ZES:1792734.1792766,
+ author = {De Moura, Leonardo and Bj{\o}rner, Nikolaj},
+ title = {Z3: An Efficient SMT Solver},
+ booktitle = {Proc. TACAS'08/ETAPS'08},
+ year = {2008},
+ location = {Budapest, Hungary},
+ pages = {337--340}
+}
+
+
+
+@article{McKay201494,
+ title = {Practical graph isomorphism, \{II\} },
+ journal = {Journal of Symbolic Computation },
+ volume = {60},
+ number = {0},
+ pages = {94 - 112},
+ year = {2014},
+ note = {},
+ issn = {0747-7171},
+ doi = {http://dx.doi.org/10.1016/j.jsc.2013.09.003},
+ url = {http://www.sciencedirect.com/science/article/pii/S0747717113001193},
+ author = {Brendan D. McKay and Adolfo Piperno}
+}
+
+
+@article{richter2010lama,
+ title = {The {LAMA} Planner: Guiding Cost-based Anytime Planning with Landmarks},
+ author = {Richter, Silvia and Westphal, Matthias},
+ journal = {Journal of Artificial Intelligence Research},
+ volume = {39},
+ number = {1},
+ pages = {127--177},
+ year = {2010}
+}
+
+
+@inproceedings{shleyfman2015heuristics,
+ title = {Heuristics and Symmetries in Classical Planning},
+ author = {Shleyfman, Alexander and Katz, Michael and Helmert, Malte and Sievers, Silvan and Wehrle, Martin},
+ booktitle = {AAAI},
+ year = {2015}
+}
+
+@inproceedings{DomshlakKS13,
+ author = {Carmel Domshlak and
+ Michael Katz and
+ Alexander Shleyfman},
+ title = {Symmetry Breaking: Satisficing Planning and Landmark Heuristics},
+ booktitle = {ICAPS},
+ year = {2013}
+}
+
+@article{helmert2014merge,
+ title = {Merge-and-shrink abstraction: A method for generating lower bounds in factored state spaces},
+ author = {Helmert, Malte and Haslum, Patrik and Hoffmann, J{\"o}rg and Nissim, Raz},
+ journal = {Journal of the ACM (JACM)},
+ volume = {61},
+ number = {3},
+ pages = {16},
+ year = {2014},
+ publisher = {ACM}
+}
+
+
+@inproceedings{amir2003factored,
+ title = {Factored planning},
+ author = {Amir, Eyal and Engelhardt, Barbara},
+ booktitle = {IJCAI},
+ volume = {3},
+ pages = {929--935},
+ year = {2003},
+ organization = {Citeseer}
+}
+
+@inproceedings{brafman2006factored,
+ title = {Factored planning: How, when, and when not},
+ author = {Brafman, Ronen I and Domshlak, Carmel},
+ booktitle = {AAAI},
+ volume = {6},
+ pages = {809--814},
+ year = {2006}
+}
+
+@inproceedings{kelareva2007factored,
+ title = {Factored Planning Using Decomposition Trees.},
+ author = {Kelareva, Elena and Buffet, Olivier and Huang, Jinbo and Thi{\'e}baux, Sylvie},
+ booktitle = {IJCAI},
+ pages = {1942--1947},
+ year = {2007}
+}
+
+
+@inproceedings{sievers:2015,
+ author = {Silvan Sievers and Martin Wehrle and Malte Helmert and Alexander Shleyfman and Michael Katz},
+ title = {Factored Symmetries for Merge-and-Shrink Abstractions},
+ booktitle = {Proc. 29th National Conf. on Artificial Intelligence},
+ publisher = {AAAI Press},
+ year = {2015}
+}
+
+@article{crawford1996symmetry,
+ title = {Symmetry-breaking predicates for search problems},
+ author = {Crawford, James and Ginsberg, Matthew and Luks, Eugene and Roy, Amitabha},
+ journal = {KR},
+ volume = {96},
+ pages = {148--159},
+ year = {1996}
+}
+
+
+@inproceedings{GuereA01,
+ author = {Emmanuel Guere and
+ Rachid Alami},
+ title = {One action is enough to plan},
+ booktitle = {Proceedings of the Seventeenth International Joint Conference on Artificial
+ Intelligence, {IJCAI} 2001, Seattle, Washington, USA, August 4-10,
+ 2001},
+ pages = {439--444},
+ year = {2001},
+ timestamp = {Mon, 20 Apr 2009 09:38:06 +0200},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/ijcai/GuereA01},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+@inproceedings{JoslinR97,
+ author = {David Joslin and
+ Amitabha Roy},
+ title = {Exploiting Symmetry in Lifted {CSPs}},
+ booktitle = {Proceedings of the Fourteenth National Conference on Artificial Intelligence
+ and Ninth Innovative Applications of Artificial Intelligence Conference,
+ {AAAI} 97, {IAAI} 97, July 27-31, 1997, Providence, Rhode Island.},
+ pages = {197--202},
+ year = {1997},
+ timestamp = {Tue, 11 Dec 2012 12:57:22 +0100},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/aaai/JoslinR97},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+@inproceedings{rintanen2003symmetry,
+ title = {Symmetry Reduction for {SAT} Representations of Transition Systems.},
+ author = {Rintanen, Jussi},
+ booktitle = {ICAPS},
+ pages = {32--41},
+ year = {2003}
+}
+
+
+@inproceedings{domshlak2012enhanced,
+ title = {Enhanced Symmetry Breaking in Cost-Optimal Planning as Forward Search.},
+ author = {Domshlak, Carmel and Katz, Michael and Shleyfman, Alexander},
+ booktitle = {ICAPS},
+ year = {2012}
+}
+
+@inproceedings{pochter2011exploiting,
+ title = {Exploiting Problem Symmetries in State-Based Planners.},
+ author = {Pochter, Nir and Zohar, Aviv and Rosenschein, Jeffrey S},
+ booktitle = {AAAI},
+ year = {2011}
+}
+
+
+@article{WahlD10,
+ author = {Thomas Wahl and
+ Alastair F. Donaldson},
+ title = {Replication and Abstraction: Symmetry in Automated Formal Verification},
+ journal = {Symmetry},
+ volume = {2},
+ number = {2},
+ pages = {799--847},
+ year = {2010},
+ url = {http://dx.doi.org/10.3390/sym2020799},
+ doi = {10.3390/sym2020799},
+ timestamp = {Mon, 21 Feb 2011 21:51:20 +0100},
+ biburl = {http://dblp.uni-trier.de/rec/bib/journals/symmetry/WahlD10},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+@inproceedings{FoxL99,
+ author = {Maria Fox and
+ Derek Long},
+ title = {The Detection and Exploitation of Symmetry in Planning Problems},
+ booktitle = {Proceedings of the Sixteenth International Joint Conference on Artificial
+ Intelligence, {IJCAI} 99, Stockholm, Sweden, July 31 - August 6, 1999.
+ 2 Volumes, 1450 pages},
+ pages = {956--961},
+ year = {1999},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/ijcai/FoxL99},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+@inproceedings{FoxL02,
+ author = {Maria Fox and
+ Derek Long},
+ title = {Extending the Exploitation of Symmetries in Planning},
+ booktitle = {Proceedings of the Sixth International Conference on Artificial Intelligence
+ Planning Systems, April 23-27, 2002, Toulouse, France},
+ pages = {83--91},
+ year = {2002}
+}
+
+@article{helmert2006fast,
+ title = {The Fast Downward Planning System.},
+ author = {Helmert, Malte},
+ journal = {J. Artif. Intell. Res.(JAIR)},
+ volume = {26},
+ pages = {191--246},
+ year = {2006}
+}
+
+@inproceedings{miguel2001symmetry,
+ title = {Symmetry-breaking in planning: Schematic constraints},
+ author = {Miguel, Ian},
+ booktitle = {{Proceedings of the CP'01 Workshop on Symmetry in Constraints}},
+ pages = {17--24},
+ year = {2001}
+}
+
+@incollection{Walsh:07,
+ year = {2007},
+ isbn = {978-3-540-74969-1},
+ booktitle = {Principles and Practice of Constraint Programming – CP 2007},
+ volume = {4741},
+ series = {Lecture Notes in Computer Science},
+ editor = {Bessière, Christian},
+ doi = {10.1007/978-3-540-74970-7_67},
+ title = {Breaking Value Symmetry},
+ url = {http://dx.doi.org/10.1007/978-3-540-74970-7_67},
+ publisher = {Springer Berlin Heidelberg},
+ author = {Walsh, Toby},
+ pages = {880-887},
+ language = {English}
+}
+
+@inproceedings{eugene1993permutation,
+ title = {Permutation groups and polynomial-time computation},
+ author = {Eugene, M},
+ booktitle = {Groups and Computation: Workshop on Groups and Computation, October 7-10, 1991},
+ volume = {11},
+ pages = {139},
+ year = {1993},
+ organization = {American Mathematical Soc.}
+}
+
+
+@inproceedings{Babai:1983:CLG:800061.808746,
+ author = {Babai, L\'{a}szl\'{o} and Luks, Eugene M.},
+ title = {Canonical Labeling of Graphs},
+ booktitle = {Proceedings of the Fifteenth Annual ACM Symposium on Theory of Computing},
+ series = {STOC '83},
+ year = {1983},
+ isbn = {0-89791-099-0},
+ pages = {171--183},
+ numpages = {13},
+ url = {http://doi.acm.org/10.1145/800061.808746},
+ doi = {10.1145/800061.808746},
+ acmid = {808746},
+ publisher = {ACM},
+ address = {New York, NY, USA}
+}
+
+
+@inproceedings{clarke1998symmetry,
+ title = {Symmetry reductions in model checking},
+ author = {Clarke, Edmund M and Emerson, E Allen and Jha, Somesh and Sistla, A Prasad},
+ booktitle = {Computer Aided Verification},
+ pages = {147--158},
+ year = {1998},
+ organization = {Springer}
+}
+
+@article{bellman1958routing,
+ title = {On a routing problem},
+ author = {Bellman, Richard},
+ journal = {Quarterly of applied mathematics},
+ pages = {87--90},
+ year = {1958},
+ publisher = {JSTOR}
+}
+
+@article{dijkstra1959note,
+ title = {A note on two problems in connexion with graphs},
+ author = {Dijkstra, Edsger W},
+ journal = {Numerische mathematik},
+ volume = {1},
+ number = {1},
+ pages = {269--271},
+ year = {1959},
+ publisher = {Springer}
+}
+
+@article{fredman1987fibonacci,
+ title = {Fibonacci heaps and their uses in improved network optimization algorithms},
+ author = {Fredman, Michael L and Tarjan, Robert Endre},
+ journal = {Journal of the ACM (JACM)},
+ volume = {34},
+ number = {3},
+ pages = {596--615},
+ year = {1987},
+ publisher = {ACM}
+}
+
+@inproceedings{thorup2003integer,
+ title = {Integer priority queues with decrease key in constant time and the single source shortest paths problem},
+ author = {Thorup, Mikkel},
+ booktitle = {Proceedings of the thirty-fifth annual ACM symposium on Theory of computing},
+ pages = {149--158},
+ year = {2003},
+ organization = {ACM}
+}
+
+@article{dufourd2009intuitionistic,
+ title = {{An intuitionistic proof of a discrete form of the Jordan Curve Theorem formalized in Coq with combinatorial hypermaps}},
+ author = {Dufourd, Jean-Fran{\c{c}}ois},
+ journal = {Journal of Automated Reasoning},
+ volume = {43},
+ number = {1},
+ pages = {19--51},
+ year = {2009},
+ publisher = {Springer}
+}
+@article{bezem2008mechanization,
+ title = {{On the mechanization of the proof of Hessenberg's theorem in coherent logic}},
+ author = {Bezem, Marc and Hendriks, Dimitri},
+ journal = {Journal of Automated Reasoning},
+ volume = {40},
+ number = {1},
+ pages = {61--85},
+ year = {2008},
+ publisher = {Springer}
+}
+@article{mckinna1999some,
+ title = {Some lambda calculus and type theory formalized},
+ author = {McKinna, James and Pollack, Robert},
+ journal = {Journal of Automated Reasoning},
+ volume = {23},
+ number = {3},
+ pages = {373--409},
+ year = {1999},
+ publisher = {Springer}
+}
+
+@inproceedings{taylor1991fixed,
+ title = {The fixed point property in synthetic domain theory},
+ author = {Taylor, Paul},
+ booktitle = {Logic in Computer Science, 1991. LICS'91., Proceedings of Sixth Annual IEEE Symposium on},
+ pages = {152--160},
+ year = {1991},
+ organization = {IEEE}
+}
+
+@article{jaume1999full,
+ title = {A full formalization of SLD-resolution in the Calculus of Inductive Constructions},
+ author = {Jaume, Mathieu},
+ journal = {Journal of Automated Reasoning},
+ volume = {23},
+ number = {3},
+ pages = {347--371},
+ year = {1999},
+ publisher = {Springer}
+}
+
+@article{kamareddine2003formalizing,
+ title = {Formalizing strong normalization proofs of explicit substitution calculi in ALF},
+ author = {Kamareddine, Fairouz and Qiao, Haiyan},
+ journal = {Journal of Automated Reasoning},
+ volume = {30},
+ number = {1},
+ pages = {59--98},
+ year = {2003},
+ publisher = {Springer}
+}
+@article{manolios2005ordinal,
+ title = {Ordinal arithmetic: Algorithms and mechanization},
+ author = {Manolios, Panagiotis and Vroon, Daron},
+ journal = {Journal of Automated Reasoning},
+ volume = {34},
+ number = {4},
+ pages = {387--423},
+ year = {2005},
+ publisher = {Springer}
+}
+@article{maric2009formalization,
+ title = {{Formalization and implementation of modern SAT solvers}},
+ author = {Mari{\'c}, Filip},
+ journal = {Journal of Automated Reasoning},
+ volume = {43},
+ number = {1},
+ year = {2009},
+ publisher = {Springer}
+}
+
+
+@inproceedings{klein2009sel4L,
+ title = {{seL4: Formal verification of an OS kernel}},
+ author = {Klein, Gerwin and Elphinstone, Kevin and Heiser, Gernot and Andronick, June and Cock, David and Derrin, Philip and Elkaduwe, Dhammika and Engelhardt, Kai and Kolanski, Rafal and Norrish, Michael and others},
+ booktitle = {Proceedings of the ACM SIGOPS 22nd symposium on Operating systems principles},
+ pages = {207--220},
+ year = {2009},
+ organization = {ACM}
+}
+
+@inproceedings{klein2009sel4,
+ title = {{seL4: Formal verification of an OS kernel}},
+ author = {Klein, Gerwin and others},
+ booktitle = {SOSP},
+ pages = {207--220},
+ year = {2009},
+ organization = {ACM}
+}
+
+@book{gordon1993introduction,
+ title = {Introduction to HOL: a theorem proving environment for higher order logic},
+ author = {Gordon, Michael JC and Melham, Tom F},
+ year = {1993},
+ publisher = {Cambridge University Press}
+}
+
+@incollection{bauer2013tableaux,
+ title = {Tableaux for verification of data-centric processes},
+ author = {Bauer, Andreas and Baumgartner, Peter and Diller, Martin and Norrish, Michael},
+ booktitle = {Automated Reasoning with Analytic Tableaux and Related Methods},
+ pages = {28--43},
+ year = {2013},
+ publisher = {Springer}
+}
+
+@book{paulson1994isabelle,
+ title = {Isabelle: A generic theorem prover},
+ author = {Paulson, Lawrence C},
+ volume = {828},
+ year = {1994},
+ publisher = {Springer}
+}
+
+@book{bertot2004interactive,
+ title = {Interactive theorem proving and program development: Coq'Art: the calculus of inductive constructions},
+ author = {Bertot, Yves and Cast{\'e}ran, Pierre},
+ year = {2004},
+ publisher = {springer}
+}
+
+@article{gonthier2008formal,
+ title = {Formal proof--the four-color theorem},
+ author = {Gonthier, Georges},
+ journal = {Notices of the AMS},
+ volume = {55},
+ number = {11},
+ pages = {1382--1393},
+ year = {2008}
+}
+
+@incollection{hales2011revision,
+ title = {{A revision of the proof of the Kepler conjecture}},
+ author = {Hales, Thomas C and Harrison, John and McLaughlin, Sean and Nipkow, Tobias and Obua, Steven and Zumkeller, Roland},
+ booktitle = {The Kepler Conjecture},
+ pages = {341--376},
+ year = {2011},
+ publisher = {Springer}
+}
+
+@article{gamboa2009formalization,
+ title = {A Formalization of Powerlist Algebra in ACL2},
+ author = {Gamboa, Ruben A},
+ journal = {Journal of Automated Reasoning},
+ volume = {43},
+ number = {2},
+ pages = {139--172},
+ year = {2009},
+ publisher = {Springer}
+}
+
+@article{harrison2007formalizing,
+ title = {Formalizing basic complex analysis},
+ author = {Harrison, John},
+ journal = {From Insight to Proof: Festschrift in Honour of Andrzej Trybulec. Studies in Logic, Grammar and Rhetoric},
+ volume = {10},
+ number = {23},
+ pages = {151--165},
+ year = {2007}
+}
+
+@inproceedings{esparza2013fully,
+ title = {{A fully verified executable LTL model checker}},
+ author = {Esparza, Javier and Lammich, Peter and Neumann, Ren{\'e} and Nipkow, Tobias and Schimpf, Alexander and Smaus, Jan-Georg},
+ booktitle = {International Conference on Computer Aided Verification},
+ pages = {463--478},
+ year = {2013},
+ organization = {Springer}
+}
+
+@inproceedings{paulson2015formalisation,
+ title = {A formalisation of finite automata using hereditarily finite sets},
+ author = {Paulson, Lawrence C},
+ booktitle = {International Conference on Automated Deduction},
+ pages = {231--245},
+ year = {2015},
+ organization = {Springer}
+}
+
+@inproceedings{constable2000constructively,
+ title = {Constructively formalizing automata theory.},
+ author = {Constable, Robert L and Jackson, Paul B and Naumov, Pavel and Uribe, Juan C},
+ booktitle = {Proof, language, and interaction},
+ pages = {213--238},
+ year = {2000}
+}
+
+@inproceedings{doczkal2013constructive,
+ title = {A constructive theory of regular languages in Coq},
+ author = {Doczkal, Christian and Kaiser, Jan-Oliver and Smolka, Gert},
+ booktitle = {International Conference on Certified Programs and Proofs},
+ pages = {82--97},
+ year = {2013},
+ organization = {Springer}
+}
+
+@inproceedings{wu2011formalisation,
+ title = {{A formalisation of the Myhill-Nerode theorem based on regular expressions (proof pearl)}},
+ author = {Wu, Chunhan and Zhang, Xingyuan and Urban, Christian},
+ booktitle = {International Conference on Interactive Theorem Proving},
+ pages = {341--356},
+ year = {2011},
+ organization = {Springer}
+}
+
+@inproceedings{schimpf2009construction,
+ title = {{Construction of B{\"u}chi automata for LTL model checking verified in Isabelle/HOL}},
+ author = {Schimpf, Alexander and Merz, Stephan and Smaus, Jan-Georg},
+ booktitle = {International Conference on Theorem Proving in Higher Order Logics},
+ pages = {424--439},
+ year = {2009},
+ organization = {Springer}
+}
+
+@inproceedings{sprenger1998verified,
+ title = {A verified model checker for the modal $\mu$-calculus in Coq},
+ author = {Sprenger, Christoph},
+ booktitle = {International Conference on Tools and Algorithms for the Construction and Analysis of Systems},
+ pages = {167--183},
+ year = {1998},
+ organization = {Springer}
+}
+
+@inproceedings{nipkow2005proof,
+ title = {Proof pearl: Defining functions over finite sets},
+ author = {Nipkow, Tobias and Paulson, Lawrence C},
+ booktitle = {International Conference on Theorem Proving in Higher Order Logics},
+ pages = {385--396},
+ year = {2005},
+ organization = {Springer}
+}
+
+@article{sistla1985complexity,
+ title = {The complexity of propositional linear temporal logics},
+ author = {Sistla, A Prasad and Clarke, Edmund M},
+ journal = {Journal of the ACM (JACM)},
+ volume = {32},
+ number = {3},
+ pages = {733--749},
+ year = {1985},
+ publisher = {ACM}
+}
+
+@article{clarke1994model,
+ title = {Model checking and abstraction},
+ author = {Clarke, Edmund M and Grumberg, Orna and Long, David E},
+ journal = {ACM transactions on Programming Languages and Systems (TOPLAS)},
+ volume = {16},
+ number = {5},
+ pages = {1512--1542},
+ year = {1994},
+ publisher = {ACM}
+}
+
+@article{filiot2011antichains,
+ title = {{Antichains and compositional algorithms for LTL synthesis}},
+ author = {Filiot, Emmanuel and Jin, Naiyong and Raskin, Jean-Fran{\c{c}}ois},
+ journal = {Formal Methods in System Design},
+ volume = {39},
+ number = {3},
+ pages = {261--296},
+ year = {2011},
+ publisher = {Springer}
+}
+
+@inproceedings{abdulaziz2014mechanising,
+ title = {{Mechanising Theoretical Upper Bounds in Planning}},
+ author = {Abdulaziz, Mohammad and Gretton, Charles and Norrish, Michael},
+ booktitle = {{Workshop on Knowledge Engineering for Planning and Scheduling}},
+ year = {2014}
+}
+
+@inproceedings{abdulaziz2015exploiting,
+ title = {{Exploiting symmetries by planning for a descriptive quotient}},
+ author = {Abdulaziz, Mohammad and Norrish, Michael and Gretton, Charles},
+ booktitle = {{Proc. of the 24th International Joint Conference on Artificial Intelligence, IJCAI}},
+ pages = {25--31},
+ year = {2015}
+}
+
+@inproceedings{abdulaziz2016isabelle,
+ title = {{An Isabelle/HOL formalisation of Green's theorem}},
+ author = {Abdulaziz, Mohammad and Paulson, Lawrence C},
+ booktitle = {{International Conference on Interactive Theorem Proving}},
+ pages = {3--19},
+ year = {2016},
+ organization = {Springer}
+}
+
+@incollection{abdulaziz2015verified,
+ title = {{Verified Over-Approximation of the Diameter of Propositionally Factored Transition Systems}},
+ author = {Abdulaziz, Mohammad and Gretton, Charles and Norrish, Michael},
+ booktitle = {{Interactive Theorem Proving}},
+ pages = {1--16},
+ year = {2015},
+ publisher = {Springer}
+}
+
+@inproceedings{icaps2017,
+ title = {{A State Space Acyclicity Property for Exponentially Tighter Plan Length Bounds}},
+ author = {Abdulaziz, Mohammad and Gretton, Charles and Norrish, Michael},
+ booktitle = {International Conference on Automated Planning and Scheduling (ICAPS)},
+ year = {2017},
+ organization = {AAAI}
+}
+
+@article{DBLP:journals/jar/AbdulazizNG18,
+ author = {Mohammad Abdulaziz and
+ Michael Norrish and
+ Charles Gretton},
+ title = {{Formally Verified Algorithms for Upper-Bounding State Space Diameters}},
+ journal = {J. Autom. Reasoning},
+ volume = {61},
+ number = {1-4},
+ pages = {485--520},
+ year = {2018},
+ timestamp = {Sat, 02 Jun 2018 16:55:32 +0200},
+ biburl = {https://dblp.org/rec/bib/journals/jar/AbdulazizNG18},
+ bibsource = {dblp computer science bibliography, https://dblp.org}
+}
+
+@article{pardalos2004note,
+ title = {A note on the complexity of longest path problems related to graph coloring},
+ author = {Pardalos, Panos M and Migdalas, Athanasios},
+ journal = {Applied mathematics letters},
+ volume = {17},
+ number = {1},
+ pages = {13--15},
+ year = {2004},
+ publisher = {Elsevier}
+}
+
+@article{galperin1983succinct,
+ title = {Succinct representations of graphs},
+ author = {Galperin, Hana and Wigderson, Avi},
+ journal = {Information and Control},
+ volume = {56},
+ number = {3},
+ pages = {183--198},
+ year = {1983},
+ publisher = {Elsevier}
+}
+
+@inproceedings{feigenbaum1998complexity,
+ title = {Complexity of problems on graphs represented as OBDDs},
+ author = {Feigenbaum, Joan and Kannan, Sampath and Vardi, Moshe Y and Viswanathan, Mahesh},
+ booktitle = {Annual Symposium on Theoretical Aspects of Computer Science},
+ pages = {216--226},
+ year = {1998},
+ organization = {Springer}
+}
+
+@article{hemaspaandra2010complexity,
+ title = {On the complexity of kings},
+ author = {Hemaspaandra, Edith and Hemaspaandra, Lane A and Tantau, Till and Watanabe, Osamu},
+ journal = {Theoretical Computer Science},
+ volume = {411},
+ number = {4-5},
+ pages = {783--798},
+ year = {2010},
+ publisher = {Elsevier}
+}
+
+@inproceedings{lozano1989complexity,
+ title = {The complexity of graph problems for succinctly represented graphs},
+ author = {Lozano, Antonio and Balc{\'a}zar, Jos{\'e} L},
+ booktitle = {International Workshop on Graph-Theoretic Concepts in Computer Science},
+ pages = {277--286},
+ year = {1989},
+ organization = {Springer}
+}
+
+@article{papadimitriou1986note,
+ title = {A note on succinct representations of graphs},
+ author = {Papadimitriou, Christos H and Yannakakis, Mihalis},
+ journal = {Information and Control},
+ volume = {71},
+ number = {3},
+ pages = {181--185},
+ year = {1986},
+ publisher = {Elsevier}
+}
+
+@inproceedings{howey2004val,
+ title = {{VAL: Automatic plan validation, continuous effects and mixed initiative planning using PDDL}},
+ author = {Howey, Richard and Long, Derek and Fox, Maria},
+ booktitle = {Tools with Artificial Intelligence, 2004},
+ year = {2004}
+}
+
+
+@inproceedings{howey2004valL,
+ title = {{VAL: Automatic plan validation, continuous effects and mixed initiative planning using PDDL}},
+ author = {Howey, Richard and Long, Derek and Fox, Maria},
+ booktitle = {Tools with Artificial Intelligence, 2004. ICTAI 2004. 16th IEEE International Conference on},
+ pages = {294--301},
+ year = {2004},
+ organization = {IEEE}
+}
+
+
+@article{leroy2009formal,
+ title = {Formal verification of a realistic compiler},
+ author = {Leroy, Xavier},
+ journal = {Communications of the ACM},
+ volume = {52},
+ number = {7},
+ pages = {107--115},
+ year = {2009},
+ publisher = {ACM}
+}
+
+@article{fox2003pddl2,
+ title = {{PDDL2.1: An extension to PDDL for expressing temporal planning domains}},
+ author = {Fox, Maria and Long, Derek},
+ journal = {JAIR},
+ year = {2003}
+}
+
+@article{fox2003pddl2L,
+ title = {{PDDL2.1: An extension to PDDL for expressing temporal planning domains}},
+ author = {Fox, Maria and Long, Derek},
+ journal = {Journal of artificial intelligence research},
+ year = {2003}
+}
+
+
+@inproceedings{fox2005validating,
+ title = {Validating plans in the context of processes and exogenous events},
+ author = {Fox, Maria and Howey, Richard and Long, Derek},
+ booktitle = {AAAI},
+ volume = {5},
+ pages = {1151--1156},
+ year = {2005}
+}
+
+@inproceedings{brunner2016formal,
+ title = {{Formal Verification of an Executable LTL Model Checker with Partial Order Reduction}},
+ author = {Brunner, Julian and Lammich, Peter},
+ booktitle = {NASA Formal Methods Symposium},
+ pages = {307--321},
+ year = {2016},
+ organization = {Springer}
+}
+
+@article{holzmann1997model,
+ title = {The model checker SPIN},
+ author = {Holzmann, Gerard J.},
+ journal = {IEEE Transactions on software engineering},
+ volume = {23},
+ number = {5},
+ pages = {279--295},
+ year = {1997},
+ publisher = {IEEE}
+}
+
+@book{norell2007towards,
+ title = {Towards a practical programming language based on dependent type theory},
+ author = {Norell, Ulf},
+ volume = {32},
+ year = {2007},
+ publisher = {Chalmers University of Technology}
+}
+
+@article{coquand1988calculus,
+ title = {The calculus of constructions},
+ author = {Coquand, Thierry and Huet, G{\'e}rard},
+ journal = {Information and computation},
+ volume = {76},
+ number = {2-3},
+ pages = {95--120},
+ year = {1988},
+ publisher = {Elsevier}
+}
+
+@article{haftmann2007code,
+ title = {{A code generator framework for Isabelle/HOL}},
+ author = {Haftmann, Florian and Nipkow, Tobias},
+ journal = {Theorem Proving in Higher Order Logics (TPHOLs 2007). Lecture Notes in Computer Science},
+ volume = {4732},
+ pages = {128--143},
+ year = {2007}
+}
+
+@book{milner1997definition,
+ title = {{The definition of standard ML: revised}},
+ author = {Milner, Robin},
+ year = {1997},
+ publisher = {MIT press}
+}
+@article{thiebaux2005defense,
+ title = {{In defense of PDDL axioms}},
+ author = {Thi{\'e}baux, Sylvie and Hoffmann, J{\"o}rg and Nebel, Bernhard},
+ journal = {Artificial Intelligence},
+ volume = {168},
+ number = {1-2},
+ pages = {38--69},
+ year = {2005},
+ publisher = {Elsevier}
+}
+
+@article{eriksson2017unsolvability,
+ title = {Unsolvability Certificates for Classical Planning},
+ author = {Eriksson, Salom{\'e} and R{\"o}ger, Gabriele and Helmert, Malte},
+ year = {2017}
+}
+
+@article{backstrom1995complexity,
+ title = {Complexity results for SAS+ planning},
+ author = {B{\"a}ckstr{\"o}m, Christer and Nebel, Bernhard},
+ journal = {Computational Intelligence},
+ volume = {11},
+ number = {4},
+ pages = {625--655},
+ year = {1995},
+ publisher = {Wiley Online Library}
+}
+
+@article{jonsson1998state,
+ title = {State-variable planning under structural restrictions: Algorithms and complexity},
+ author = {Jonsson, Peter and B{\"a}ckstr{\"o}m, Christer},
+ journal = {Artificial Intelligence},
+ volume = {100},
+ number = {1-2},
+ pages = {125--176},
+ year = {1998},
+ publisher = {Elsevier}
+}
+
+@inproceedings{kumar2014hol,
+ title = {{HOL with definitions: Semantics, soundness, and a verified implementation}},
+ author = {Kumar, Ramana and Arthan, Rob and Myreen, Magnus O and Owens, Scott},
+ booktitle = {ITP},
+ year = {2014}
+}
+
+@inproceedings{kumar2014holL,
+ title = {HOL with definitions: Semantics, soundness, and a verified implementation},
+ author = {Kumar, Ramana and Arthan, Rob and Myreen, Magnus O and Owens, Scott},
+ booktitle = {International Conference on Interactive Theorem Proving},
+ pages = {308--324},
+ year = {2014},
+ organization = {Springer}
+}
+
+
+@inproceedings{blanchette2016verified,
+ title = {{A verified SAT solver framework with learn, forget, restart, and incrementality}},
+ author = {Blanchette, Jasmin Christian and Fleury, Mathias and Weidenbach, Christoph},
+ booktitle = {International Joint Conference on Automated Reasoning},
+ pages = {25--44},
+ year = {2016},
+ organization = {Springer}
+}
+
+@inproceedings{balyo2013relaxingL,
+ title = {Relaxing the relaxed exist-step parallel planning semantics},
+ author = {Balyo, Toma},
+ booktitle = {Tools with Artificial Intelligence (ICTAI), 2013 IEEE 25th International Conference on},
+ pages = {865--871},
+ year = {2013},
+ organization = {IEEE}
+}
+
+@inproceedings{balyo2013relaxing,
+ title = {Relaxing the relaxed exist-step parallel planning semantics},
+ author = {Balyo, Toma},
+ booktitle = {Tools with Artificial Intelligence (ICTAI), 2013},
+ pages = {865--871},
+ year = {2013},
+ organization = {IEEE}
+}
+
+@inproceedings{DBLP:conf/sat/Lammich17,
+ author = {Peter Lammich},
+ title = {The {GRAT} Tool Chain - Efficient {(UN)SAT} Certificate
+Checking with
+ Formal Correctness Guarantees},
+ booktitle = {Theory and Applications of Satisfiability Testing -
+{SAT} 2017 - 20th
+ International Conference, Melbourne, VIC, Australia,
+August 28 - September
+ 1, 2017, Proceedings},
+ year = {2017},
+ crossref = {DBLP:conf/sat/2017},
+ url = {https://doi.org/10.1007/978-3-319-66263-3_29},
+ doi = {10.1007/978-3-319-66263-3_29},
+ timestamp = {Tue, 15 Aug 2017 09:56:48 +0200},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/sat/Lammich17},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+
+@inproceedings{DBLP:conf/cade/Lammich17,
+ author = {Peter Lammich},
+ title = {Efficient Verified {(UN)SAT} Certificate Checking},
+ booktitle = {{CADE}},
+ year = {2017},
+ url = {https://doi.org/10.1007/978-3-319-63046-5_15},
+ doi = {10.1007/978-3-319-63046-5_15},
+ timestamp = {Wed, 12 Jul 2017 10:22:36 +0200},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/cade/Lammich17},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+@inproceedings{DBLP:conf/cade/Lammich17L,
+ author = {Peter Lammich},
+ title = {Efficient Verified {(UN)SAT} Certificate Checking},
+ booktitle = {Automated Deduction - {CADE} 26 - 26th International
+Conference on
+ Automated Deduction, Gothenburg, Sweden, August 6-11,
+2017, Proceedings},
+ pages = {237--254},
+ year = {2017},
+ url = {https://doi.org/10.1007/978-3-319-63046-5_15},
+ doi = {10.1007/978-3-319-63046-5_15},
+ timestamp = {Wed, 12 Jul 2017 10:22:36 +0200},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/cade/Lammich17},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+
+@inproceedings{lochbihler2013light,
+ title = {{Light-weight containers for Isabelle: efficient, extensible, nestable}},
+ author = {Lochbihler, Andreas},
+ booktitle = {International Conference on Interactive Theorem Proving},
+ pages = {116--132},
+ year = {2013},
+ organization = {Springer}
+}
+
+@article{kovacscomplete,
+ title = {{BNF definition of PDDL 3.1}},
+ author = {Kovacs, Daniel L},
+ journal = {IPC-2011},
+ year = {2011}
+}
+
+@techreport{milner1972logic,
+ title = {Logic for computable functions description of a machine implementation},
+ author = {Milner, Robin},
+ year = {1972},
+ institution = {Stanford University}
+}
+
+@techreport{green1969application,
+ title = {Application of theorem proving to problem solving},
+ author = {Green, Cordell},
+ year = {1969},
+ institution = {SRI}
+}
+
+@inproceedings{lifschitz1987semantics,
+ title = {On the semantics of STRIPS},
+ author = {Lifschitz, Vladimir},
+ booktitle = {Reasoning about Actions and Plans: Proceedings of the 1986 Workshop},
+ pages = {1--9},
+ year = {1987}
+}
+
+@article{pednault1989adl,
+ title = {ADL: Exploring the Middle Ground Between STRIPS and the Situation Calculus.},
+ author = {Pednault, Edwin PD},
+ journal = {Kr},
+ volume = {89},
+ pages = {324--332},
+ year = {1989}
+}
+
+@inproceedings{paulson2010three,
+ title = {Three Years of Experience with Sledgehammer, a Practical Link between Automatic and Interactive Theorem Provers.},
+ author = {Paulson, Lawrence C and Blanchette, Jasmin Christian},
+ booktitle = {PAAR@ IJCAR},
+ pages = {1--10},
+ year = {2010}
+}
+
+@inproceedings{zhan2016auto2,
+ title = {AUTO2, a saturation-based heuristic prover for higher-order logic},
+ author = {Zhan, Bohua},
+ booktitle = {International Conference on Interactive Theorem Proving},
+ pages = {441--456},
+ year = {2016},
+ organization = {Springer}
+}
+
+@article{DBLP:journals/afp/MichaelisN17,
+ author = {Julius Michaelis and
+ Tobias Nipkow},
+ title = {Propositional Proof Systems},
+ journal = {Archive of Formal Proofs},
+ volume = {2017},
+ year = {2017},
+ url = {https://www.isa-afp.org/entries/Propositional_Proof_Systems.shtml},
+ timestamp = {Fri, 30 Jun 2017 19:26:27 +0200},
+ biburl = {http://dblp.org/rec/bib/journals/afp/MichaelisN17},
+ bibsource = {dblp computer science bibliography, http://dblp.org}
+}
+
+@inproceedings{MichaelisN-TYPES17,
+ author = {Julius Michaelis and Tobias Nipkow},
+ title = {Formalized Proof Systems for Propositional Logic},
+ booktitle = {23rd Int.\ Conf.\ Types for Proofs and Programs (TYPES 2017)},
+ editor = {A. Abel and F. Nordvall Forsberg and A. Kaposi},
+ series = {LIPIcs},
+ volume = {104},
+ pages = {6:1--6:16},
+ publisher = {Schloss Dagstuhl - Leibniz-Zentrum fuer Informatik},
+ year = {2018}
+}
+
+@inproceedings{haslum2003domain,
+ title = {Domain knowledge in planning: Representation and use},
+ author = {Haslum, Patrik and Scholz, Ulrich},
+ booktitle = {ICAPS Workshop on PDDL},
+ year = {2003}
+}
+
+@article{haslum2011computing,
+ title = {Computing genome edit distances using domain-independent planning},
+ author = {Haslum, Patrik and et al.},
+ year = {2011},
+ publisher = {AAAI Press}
+}
+
+@techreport{mccarthy1985formalization,
+ title = {{Formalization of STRIPS in situation calculus}},
+ author = {McCarthy, John},
+ year = {1985},
+ institution = {Citeseer}
+}
+
+@techreport{norrish1998c,
+ title = {{C formalised in HOL}},
+ author = {Norrish, Michael},
+ year = {1998},
+ institution = {University of Cambridge, Computer Laboratory}
+}
+
+@inproceedings{ictai2018,
+ title = {{A Formally Verified Validator for Classical Planning Problems and Solutions}},
+ author = {Abdulaziz, Mohammad and Lammich, Peter},
+ booktitle = {International Conference on Tools in Artificial Intelligence (ICTAI)},
+ year = {2018},
+ organization = {IEEE}
+}
+
+@article{Propositional_Proof_Systems-AFP,
+ author = {Julius Michaelis and Tobias Nipkow},
+ title = {Propositional Proof Systems},
+ journal = {Archive of Formal Proofs},
+ month = jun,
+ year = 2017,
+ note = {\url{http://isa-afp.org/entries/Propositional_Proof_Systems.html},
+ Formal proof development},
+ issn = {2150-914x}
+}
\ No newline at end of file
diff --git a/thys/AI_Planning_Languages_Semantics/document/root.tex b/thys/AI_Planning_Languages_Semantics/document/root.tex
new file mode 100644
--- /dev/null
+++ b/thys/AI_Planning_Languages_Semantics/document/root.tex
@@ -0,0 +1,71 @@
+\documentclass[11pt,a4paper]{article}
+\usepackage{isabelle,isabellesym}
+
+% further packages required for unusual symbols (see also
+% isabellesym.sty), use only when needed
+
+%\usepackage{amssymb}
+ %for \<leadsto>, \<box>, \<diamond>, \<sqsupset>, \<mho>, \<Join>,
+ %\<lhd>, \<lesssim>, \<greatersim>, \<lessapprox>, \<greaterapprox>,
+ %\<triangleq>, \<yen>, \<lozenge>
+
+%\usepackage{eurosym}
+ %for \<euro>
+
+%\usepackage[only,bigsqcap]{stmaryrd}
+ %for \<Sqinter>
+
+%\usepackage{eufrak}
+ %for \<AA> ... \<ZZ>, \<aa> ... \<zz> (also included in amssymb)
+
+%\usepackage{textcomp}
+ %for \<onequarter>, \<onehalf>, \<threequarters>, \<degree>, \<cent>,
+ %\<currency>
+
+\usepackage{wasysym}
+
+% 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{Semantics of AI Planning Languages}
+\author{Mohammad Abdulaziz and Peter Lammich\footnote{Author names are alphabetically ordered.}}
+
+% \subtitle{Proof Document}
+% \author{M. Abdulaziz \and P. Lammich}
+\date{}
+
+\maketitle
+
+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~\cite{helmert2006fast}, the STRIPS~\cite{fikes1971strips} fragment of the Planning Domain Definition Language~\cite{PDDLref} (PDDL), and the STRIPS soundness meta-theory developed by Lifschitz~\cite{lifschitz1987semantics}.
+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~\cite{ictai2018}.
+
+\tableofcontents
+
+\clearpage
+
+% sane default for proof documents
+\parindent 0pt\parskip 0.5ex
+
+% generated text of all theories
+\input{session}
+
+\bibliographystyle{abbrv}
+\bibliography{root}
+
+\end{document}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: t
+%%% End:
diff --git a/thys/Core_SC_DOM/CITATION b/thys/Core_SC_DOM/CITATION
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/CITATION
@@ -0,0 +1,37 @@
+An overview of the formalization is given in:
+
+ Achim D. Brucker and Michael Herzberg. A Formal Semantics of the Core DOM
+ in Isabelle/HOL. In The 2018 Web Conference Companion (WWW). Pages 741-749,
+ ACM Press, 2018. doi:10.1145/3184558.3185980
+
+A BibTeX entry for LaTeX users is
+@InProceedings{ brucker.ea:core-dom:2018,
+ abstract = {At its core, the Document Object Model (DOM) defines a tree-like
+ data structure for representing documents in general and HTML
+ documents in particular. It forms the heart of any rendering engine
+ of modern web browsers. Formalizing the key concepts of the DOM is
+ a pre-requisite for the formal reasoning over client-side JavaScript
+ programs as well as for the analysis of security concepts in modern
+ web browsers. In this paper, 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.},
+ address = {New York, NY, USA},
+ author = {Achim D. Brucker and Michael Herzberg},
+ booktitle= {The 2018 Web Conference Companion (WWW)},
+ conf_date= {April 23-27, 2018},
+ doi = {10.1145/3184558.3185980},
+ editor = {Pierre{-}Antoine Champin and Fabien L. Gandon and Mounia Lalmas and Panagiotis G. Ipeirotis},
+ isbn = {978-1-4503-5640-4/18/04},
+ keywords = {Document Object Model, DOM, Formal Semantics, Isabelle/HOL},
+ location = {Lyon, France},
+ pages = {741--749},
+ pdf = {https://www.brucker.ch/bibliography/download/2018/brucker.ea-core-dom-2018.pdf},
+ publisher= {ACM Press},
+ title = {A Formal Semantics of the Core {DOM} in {Isabelle/HOL}},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-core-dom-2018},
+ year = {2018},
+}
diff --git a/thys/Core_SC_DOM/ROOT b/thys/Core_SC_DOM/ROOT
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/ROOT
@@ -0,0 +1,20 @@
+chapter AFP
+
+session "Core_SC_DOM" (AFP) = "HOL-Library" +
+ options [timeout = 1200]
+ directories
+ "common"
+ "common/classes"
+ "common/monads"
+ "common/pointers"
+ "common/preliminaries"
+ "common/tests"
+ "safely_composable"
+ "safely_composable/classes"
+ "safely_composable/pointers"
+ theories
+ Core_DOM
+ Core_DOM_Tests
+ document_files (in "document")
+ "root.tex"
+ "root.bib"
diff --git a/thys/Core_SC_DOM/common/Core_DOM.thy b/thys/Core_SC_DOM/common/Core_DOM.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/Core_DOM.thy
@@ -0,0 +1,39 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>The Core DOM\<close>
+text\<open>This theory is the main entry point of our formalization of the core DOM.\<close>
+
+theory Core_DOM
+imports
+ "Core_DOM_Heap_WF"
+begin
+
+
+end
diff --git a/thys/Core_SC_DOM/common/Core_DOM_Basic_Datatypes.thy b/thys/Core_SC_DOM/common/Core_DOM_Basic_Datatypes.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/Core_DOM_Basic_Datatypes.thy
@@ -0,0 +1,66 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ *******************************************************************************\***)
+
+section\<open>Basic Data Types\<close>
+text\<open>
+ \label{sec:Core_DOM_Basic_Datatypes}
+ This theory formalizes the primitive data types used by the DOM standard~\cite{dom-specification}.
+\<close>
+theory Core_DOM_Basic_Datatypes
+ imports
+ Main
+begin
+
+type_synonym USVString = string
+text\<open>
+ In the official standard, the type @{type "USVString"} corresponds to the set of all possible
+ sequences of Unicode scalar values. As we are not interested in analyzing the specifics of Unicode
+ strings, we just model @{type "USVString"} using the standard type @{type "string"} of Isabelle/HOL.
+\<close>
+
+type_synonym DOMString = string
+text\<open>
+ In the official standard, the type @{type "DOMString"} corresponds to the set of all possible
+ sequences of code units, commonly interpreted as UTF-16 encoded strings. Again, as we are not
+ interested in analyzing the specifics of Unicode strings, we just model @{type "DOMString"} using
+ the standard type @{type "string"} of Isabelle/HOL.
+\<close>
+
+type_synonym doctype = DOMString
+
+paragraph\<open>Examples\<close>
+definition html :: doctype
+ where "html = ''<!DOCTYPE html>''"
+
+hide_const id
+
+text \<open>This dummy locale is used to create scoped definitions by using global interpretations
+ and defines.\<close>
+locale l_dummy
+end
diff --git a/thys/Core_SC_DOM/common/Core_DOM_Functions.thy b/thys/Core_SC_DOM/common/Core_DOM_Functions.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/Core_DOM_Functions.thy
@@ -0,0 +1,3813 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Querying and Modifying the DOM\<close>
+text\<open>In this theory, we are formalizing the functions for querying and modifying
+the DOM.\<close>
+
+theory Core_DOM_Functions
+imports
+ "monads/DocumentMonad"
+begin
+
+text \<open>If we do not declare show\_variants, then all abbreviations that contain
+ constants that are overloaded by using adhoc\_overloading get immediately unfolded.\<close>
+declare [[show_variants]]
+
+subsection \<open>Various Functions\<close>
+
+lemma insort_split: "x \<in> set (insort y xs) \<longleftrightarrow> (x = y \<or> x \<in> set xs)"
+ apply(induct xs)
+ by(auto)
+
+lemma concat_map_distinct:
+ "distinct (concat (map f xs)) \<Longrightarrow> y \<in> set (concat (map f xs)) \<Longrightarrow> \<exists>!x \<in> set xs. y \<in> set (f x)"
+ apply(induct xs)
+ by(auto)
+
+lemma concat_map_all_distinct: "distinct (concat (map f xs)) \<Longrightarrow> x \<in> set xs \<Longrightarrow> distinct (f x)"
+ apply(induct xs)
+ by(auto)
+
+lemma distinct_concat_map_I:
+ assumes "distinct xs"
+ and "\<And>x. x \<in> set xs \<Longrightarrow> distinct (f x)"
+and "\<And>x y. x \<in> set xs \<Longrightarrow> y \<in> set xs \<Longrightarrow> x \<noteq> y \<Longrightarrow> (set (f x)) \<inter> (set (f y)) = {}"
+shows "distinct (concat ((map f xs)))"
+ using assms
+ apply(induct xs)
+ by(auto)
+
+lemma distinct_concat_map_E:
+ assumes "distinct (concat ((map f xs)))"
+ shows "\<And>x y. x \<in> set xs \<Longrightarrow> y \<in> set xs \<Longrightarrow> x \<noteq> y \<Longrightarrow> (set (f x)) \<inter> (set (f y)) = {}"
+ and "\<And>x. x \<in> set xs \<Longrightarrow> distinct (f x)"
+ using assms
+ apply(induct xs)
+ by(auto)
+
+lemma bind_is_OK_E3 [elim]:
+ assumes "h \<turnstile> ok (f \<bind> g)" and "pure f h"
+ obtains x where "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> ok (g x)"
+ using assms
+ by(auto simp add: bind_def returns_result_def returns_heap_def is_OK_def execute_def pure_def
+ split: sum.splits)
+
+
+subsection \<open>Basic Functions\<close>
+
+subsubsection \<open>get\_child\_nodes\<close>
+
+locale l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+
+definition get_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) element_ptr \<Rightarrow> unit \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ where
+ "get_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr _ = get_M element_ptr RElement.child_nodes"
+
+definition get_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) character_data_ptr \<Rightarrow> unit \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ where
+ "get_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r _ _ = return []"
+
+definition get_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) document_ptr \<Rightarrow> unit \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ where
+ "get_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr _ = do {
+ doc_elem \<leftarrow> get_M document_ptr document_element;
+ (case doc_elem of
+ Some element_ptr \<Rightarrow> return [cast element_ptr]
+ | None \<Rightarrow> return [])
+ }"
+
+definition a_get_child_nodes_tups :: "(((_) object_ptr \<Rightarrow> bool) \<times> ((_) object_ptr \<Rightarrow> unit
+ \<Rightarrow> (_, (_) node_ptr list) dom_prog)) list"
+ where
+ "a_get_child_nodes_tups = [
+ (is_element_ptr, get_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast),
+ (is_character_data_ptr, get_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast),
+ (is_document_ptr, get_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast)
+ ]"
+
+definition a_get_child_nodes :: "(_) object_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ where
+ "a_get_child_nodes ptr = invoke a_get_child_nodes_tups ptr ()"
+
+definition a_get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ where
+ "a_get_child_nodes_locs ptr \<equiv>
+ (if is_element_ptr_kind ptr then {preserved (get_M (the (cast ptr)) RElement.child_nodes)} else {}) \<union>
+ (if is_document_ptr_kind ptr then {preserved (get_M (the (cast ptr)) RDocument.document_element)} else {}) \<union>
+ {preserved (get_M ptr RObject.nothing)}"
+
+definition first_child :: "(_) object_ptr \<Rightarrow> (_, (_) node_ptr option) dom_prog"
+ where
+ "first_child ptr = do {
+ children \<leftarrow> a_get_child_nodes ptr;
+ return (case children of [] \<Rightarrow> None | child#_ \<Rightarrow> Some child)}"
+end
+
+locale l_get_child_nodes_defs =
+ fixes get_child_nodes :: "(_) object_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ fixes get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_known_ptr known_ptr +
+ l_get_child_nodes_defs get_child_nodes get_child_nodes_locs +
+ l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes known_ptr_impl: "known_ptr = DocumentClass.known_ptr"
+ assumes type_wf_impl: "type_wf = DocumentClass.type_wf"
+ assumes get_child_nodes_impl: "get_child_nodes = a_get_child_nodes"
+ assumes get_child_nodes_locs_impl: "get_child_nodes_locs = a_get_child_nodes_locs"
+begin
+lemmas get_child_nodes_def = get_child_nodes_impl[unfolded a_get_child_nodes_def]
+lemmas get_child_nodes_locs_def = get_child_nodes_locs_impl[unfolded a_get_child_nodes_locs_def]
+
+lemma get_child_nodes_split:
+ "P (invoke (a_get_child_nodes_tups @ xs) ptr ()) =
+ ((known_ptr ptr \<longrightarrow> P (get_child_nodes ptr))
+ \<and> (\<not>(known_ptr ptr) \<longrightarrow> P (invoke xs ptr ())))"
+ by(auto simp add: known_ptr_impl get_child_nodes_impl a_get_child_nodes_def a_get_child_nodes_tups_def
+ known_ptr_defs CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs
+ NodeClass.known_ptr_defs
+ split: invoke_splits)
+
+lemma get_child_nodes_split_asm:
+ "P (invoke (a_get_child_nodes_tups @ xs) ptr ()) =
+ (\<not>((known_ptr ptr \<and> \<not>P (get_child_nodes ptr))
+ \<or> (\<not>(known_ptr ptr) \<and> \<not>P (invoke xs ptr ()))))"
+ by(auto simp add: known_ptr_impl get_child_nodes_impl a_get_child_nodes_def
+ a_get_child_nodes_tups_def known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ split: invoke_splits)
+
+lemmas get_child_nodes_splits = get_child_nodes_split get_child_nodes_split_asm
+
+lemma get_child_nodes_ok [simp]:
+ assumes "known_ptr ptr"
+ assumes "type_wf h"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ shows "h \<turnstile> ok (get_child_nodes ptr)"
+ using assms(1) assms(2) assms(3)
+ apply(auto simp add: known_ptr_impl type_wf_impl get_child_nodes_def a_get_child_nodes_tups_def)[1]
+ apply(split invoke_splits, rule conjI)+
+ apply((rule impI)+, drule(1) known_ptr_not_document_ptr, drule(1) known_ptr_not_character_data_ptr,
+ drule(1) known_ptr_not_element_ptr)
+ apply(auto simp add: NodeClass.known_ptr_defs)[1]
+ apply(auto simp add: get_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def dest: get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok
+ split: list.splits option.splits intro!: bind_is_OK_I2)[1]
+ apply(auto simp add: get_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)[1]
+ apply (auto simp add: get_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CharacterDataClass.type_wf_defs
+ DocumentClass.type_wf_defs intro!: bind_is_OK_I2 split: option.splits)[1]
+ using get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok \<open>type_wf h\<close>[unfolded type_wf_impl] by blast
+
+lemma get_child_nodes_ptr_in_heap [simp]:
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ by(auto simp add: get_child_nodes_impl a_get_child_nodes_def invoke_ptr_in_heap
+ dest: is_OK_returns_result_I)
+
+lemma get_child_nodes_pure [simp]:
+ "pure (get_child_nodes ptr) h"
+ apply (auto simp add: get_child_nodes_impl a_get_child_nodes_def a_get_child_nodes_tups_def)[1]
+ apply(split invoke_splits, rule conjI)+
+ by(auto simp add: get_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def get_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ get_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: bind_pure_I split: option.splits)
+
+lemma get_child_nodes_reads: "reads (get_child_nodes_locs ptr) (get_child_nodes ptr) h h'"
+ apply(simp add: get_child_nodes_locs_impl get_child_nodes_impl a_get_child_nodes_def
+ a_get_child_nodes_tups_def a_get_child_nodes_locs_def)
+ apply(split invoke_splits, rule conjI)+
+ apply(auto)[1]
+ apply(auto simp add: get_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro: reads_subset[OF reads_singleton]
+ reads_subset[OF check_in_heap_reads]
+ intro!: reads_bind_pure reads_subset[OF return_reads] split: option.splits)[1] (* slow: ca 1min *)
+ apply(auto simp add: get_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro: reads_subset[OF check_in_heap_reads]
+ intro!: reads_bind_pure reads_subset[OF return_reads] )[1]
+ apply(auto simp add: get_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro: reads_subset[OF reads_singleton]
+ reads_subset[OF check_in_heap_reads] intro!: reads_bind_pure reads_subset[OF return_reads]
+ split: option.splits)[1]
+ done
+end
+
+locale l_get_child_nodes = l_type_wf + l_known_ptr + l_get_child_nodes_defs +
+ assumes get_child_nodes_reads: "reads (get_child_nodes_locs ptr) (get_child_nodes ptr) h h'"
+ assumes get_child_nodes_ok: "type_wf h \<Longrightarrow> known_ptr ptr \<Longrightarrow> ptr |\<in>| object_ptr_kinds h
+ \<Longrightarrow> h \<turnstile> ok (get_child_nodes ptr)"
+ assumes get_child_nodes_ptr_in_heap: "h \<turnstile> ok (get_child_nodes ptr) \<Longrightarrow> ptr |\<in>| object_ptr_kinds h"
+ assumes get_child_nodes_pure [simp]: "pure (get_child_nodes ptr) h"
+
+global_interpretation l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs defines
+ get_child_nodes = l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_child_nodes and
+ get_child_nodes_locs = l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_child_nodes_locs
+ .
+
+interpretation
+ i_get_child_nodes?: l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr get_child_nodes get_child_nodes_locs
+ by(auto simp add: l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def get_child_nodes_def get_child_nodes_locs_def)
+declare l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_child_nodes_is_l_get_child_nodes [instances]:
+ "l_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs"
+ apply(unfold_locales)
+ using get_child_nodes_reads get_child_nodes_ok get_child_nodes_ptr_in_heap get_child_nodes_pure
+ by blast+
+
+
+paragraph \<open>new\_element\<close>
+
+locale l_new_element_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr get_child_nodes get_child_nodes_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_child_nodes_new_element:
+ "ptr' \<noteq> cast new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+ by (auto simp add: get_child_nodes_locs_def new_element_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t new_element_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ new_element_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t split: prod.splits if_splits option.splits
+ elim!: bind_returns_result_E bind_returns_heap_E intro: is_element_ptr_kind_obtains)
+
+lemma new_element_no_child_nodes:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []"
+ apply(auto simp add: get_child_nodes_def a_get_child_nodes_tups_def
+ split: prod.splits elim!: bind_returns_result_E bind_returns_heap_E)[1]
+ apply(split invoke_splits, rule conjI)+
+ apply(auto intro: new_element_is_element_ptr)[1]
+ by(auto simp add: new_element_ptr_in_heap get_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def check_in_heap_def
+ new_element_child_nodes intro!: bind_pure_returns_result_I
+ intro: new_element_is_element_ptr elim!: new_element_ptr_in_heap)
+end
+
+locale l_new_element_get_child_nodes = l_new_element + l_get_child_nodes +
+ assumes get_child_nodes_new_element:
+ "ptr' \<noteq> cast new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr
+ \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+ assumes new_element_no_child_nodes:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []"
+
+interpretation i_new_element_get_child_nodes?:
+ l_new_element_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr get_child_nodes get_child_nodes_locs
+ by(unfold_locales)
+declare l_new_element_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma new_element_get_child_nodes_is_l_new_element_get_child_nodes [instances]:
+ "l_new_element_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs"
+ using new_element_is_l_new_element get_child_nodes_is_l_get_child_nodes
+ apply(auto simp add: l_new_element_get_child_nodes_def l_new_element_get_child_nodes_axioms_def)[1]
+ using get_child_nodes_new_element new_element_no_child_nodes
+ by fast+
+
+
+paragraph \<open>new\_character\_data\<close>
+
+locale l_new_character_data_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr get_child_nodes get_child_nodes_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_child_nodes_new_character_data:
+ "ptr' \<noteq> cast new_character_data_ptr \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr
+ \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+ by (auto simp add: get_child_nodes_locs_def new_character_data_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ new_character_data_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t new_character_data_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ split: prod.splits if_splits option.splits
+ elim!: bind_returns_result_E bind_returns_heap_E
+ intro: is_character_data_ptr_kind_obtains)
+
+lemma new_character_data_no_child_nodes:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []"
+ apply(auto simp add: get_child_nodes_def a_get_child_nodes_tups_def
+ split: prod.splits elim!: bind_returns_result_E bind_returns_heap_E)[1]
+ apply(split invoke_splits, rule conjI)+
+ apply(auto intro: new_character_data_is_character_data_ptr)[1]
+ by(auto simp add: new_character_data_ptr_in_heap get_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ check_in_heap_def new_character_data_child_nodes
+ intro!: bind_pure_returns_result_I
+ intro: new_character_data_is_character_data_ptr elim!: new_character_data_ptr_in_heap)
+end
+
+locale l_new_character_data_get_child_nodes = l_new_character_data + l_get_child_nodes +
+ assumes get_child_nodes_new_character_data:
+ "ptr' \<noteq> cast new_character_data_ptr \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr
+ \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+ assumes new_character_data_no_child_nodes:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []"
+
+interpretation i_new_character_data_get_child_nodes?:
+ l_new_character_data_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr get_child_nodes get_child_nodes_locs
+ by(unfold_locales)
+declare l_new_character_data_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma new_character_data_get_child_nodes_is_l_new_character_data_get_child_nodes [instances]:
+ "l_new_character_data_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs"
+ using new_character_data_is_l_new_character_data get_child_nodes_is_l_get_child_nodes
+ apply(simp add: l_new_character_data_get_child_nodes_def l_new_character_data_get_child_nodes_axioms_def)
+ using get_child_nodes_new_character_data new_character_data_no_child_nodes
+ by fast
+
+
+
+paragraph \<open>new\_document\<close>
+
+locale l_new_document_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr get_child_nodes get_child_nodes_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_child_nodes_new_document:
+ "ptr' \<noteq> cast new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr
+ \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+ by (auto simp add: get_child_nodes_locs_def new_document_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t new_document_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ new_document_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t split: prod.splits if_splits option.splits
+ elim!: bind_returns_result_E bind_returns_heap_E
+ intro: is_document_ptr_kind_obtains)
+
+lemma new_document_no_child_nodes:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_child_nodes (cast new_document_ptr) \<rightarrow>\<^sub>r []"
+ apply(auto simp add: get_child_nodes_def a_get_child_nodes_tups_def
+ split: prod.splits
+ elim!: bind_returns_result_E bind_returns_heap_E)[1]
+ apply(split invoke_splits, rule conjI)+
+ apply(auto intro: new_document_is_document_ptr)[1]
+ by(auto simp add: new_document_ptr_in_heap get_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def check_in_heap_def
+ new_document_document_element
+ intro!: bind_pure_returns_result_I
+ intro: new_document_is_document_ptr elim!: new_document_ptr_in_heap split: option.splits)
+end
+
+locale l_new_document_get_child_nodes = l_new_document + l_get_child_nodes +
+ assumes get_child_nodes_new_document:
+ "ptr' \<noteq> cast new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr
+ \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+ assumes new_document_no_child_nodes:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_child_nodes (cast new_document_ptr) \<rightarrow>\<^sub>r []"
+
+interpretation i_new_document_get_child_nodes?:
+ l_new_document_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr get_child_nodes get_child_nodes_locs
+ by(unfold_locales)
+declare l_new_document_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma new_document_get_child_nodes_is_l_new_document_get_child_nodes [instances]:
+ "l_new_document_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs"
+ using new_document_is_l_new_document get_child_nodes_is_l_get_child_nodes
+ apply(simp add: l_new_document_get_child_nodes_def l_new_document_get_child_nodes_axioms_def)
+ using get_child_nodes_new_document new_document_no_child_nodes
+ by fast
+
+subsubsection \<open>set\_child\_nodes\<close>
+
+locale l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+definition set_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ::
+ "(_) element_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ where
+ "set_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr children = put_M element_ptr RElement.child_nodes_update children"
+
+definition set_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r ::
+ "(_) character_data_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ where
+ "set_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r _ _ = error HierarchyRequestError"
+
+definition set_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ where
+ "set_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr children = do {
+ (case children of
+ [] \<Rightarrow> put_M document_ptr document_element_update None
+ | child # [] \<Rightarrow> (case cast child of
+ Some element_ptr \<Rightarrow> put_M document_ptr document_element_update (Some element_ptr)
+ | None \<Rightarrow> error HierarchyRequestError)
+ | _ \<Rightarrow> error HierarchyRequestError)
+ }"
+
+definition a_set_child_nodes_tups ::
+ "(((_) object_ptr \<Rightarrow> bool) \<times> ((_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog)) list"
+ where
+ "a_set_child_nodes_tups \<equiv> [
+ (is_element_ptr, set_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast),
+ (is_character_data_ptr, set_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast),
+ (is_document_ptr, set_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast)
+ ]"
+
+definition a_set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_set_child_nodes ptr children = invoke a_set_child_nodes_tups ptr (children)"
+lemmas set_child_nodes_defs = a_set_child_nodes_def
+
+definition a_set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> (_, unit) dom_prog set"
+ where
+ "a_set_child_nodes_locs ptr \<equiv>
+ (if is_element_ptr_kind ptr
+ then all_args (put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t (the (cast ptr)) RElement.child_nodes_update) else {}) \<union>
+ (if is_document_ptr_kind ptr
+ then all_args (put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t (the (cast ptr)) document_element_update) else {})"
+end
+
+locale l_set_child_nodes_defs =
+ fixes set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ fixes set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> (_, unit) dom_prog set"
+
+locale l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_known_ptr known_ptr +
+ l_set_child_nodes_defs set_child_nodes set_child_nodes_locs +
+ l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ and set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> (_, unit) dom_prog set" +
+ assumes known_ptr_impl: "known_ptr = DocumentClass.known_ptr"
+ assumes type_wf_impl: "type_wf = DocumentClass.type_wf"
+ assumes set_child_nodes_impl: "set_child_nodes = a_set_child_nodes"
+ assumes set_child_nodes_locs_impl: "set_child_nodes_locs = a_set_child_nodes_locs"
+begin
+lemmas set_child_nodes_def = set_child_nodes_impl[unfolded a_set_child_nodes_def]
+lemmas set_child_nodes_locs_def = set_child_nodes_locs_impl[unfolded a_set_child_nodes_locs_def]
+
+lemma set_child_nodes_split:
+ "P (invoke (a_set_child_nodes_tups @ xs) ptr (children)) =
+ ((known_ptr ptr \<longrightarrow> P (set_child_nodes ptr children))
+ \<and> (\<not>(known_ptr ptr) \<longrightarrow> P (invoke xs ptr (children))))"
+ by(auto simp add: known_ptr_impl set_child_nodes_impl a_set_child_nodes_def
+ a_set_child_nodes_tups_def known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: invoke_splits)
+
+lemma set_child_nodes_split_asm:
+ "P (invoke (a_set_child_nodes_tups @ xs) ptr (children)) =
+ (\<not>((known_ptr ptr \<and> \<not>P (set_child_nodes ptr children))
+ \<or> (\<not>(known_ptr ptr) \<and> \<not>P (invoke xs ptr (children)))))"
+ by(auto simp add: known_ptr_impl set_child_nodes_impl a_set_child_nodes_def
+ a_set_child_nodes_tups_def known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: invoke_splits)[1]
+lemmas set_child_nodes_splits = set_child_nodes_split set_child_nodes_split_asm
+
+lemma set_child_nodes_writes: "writes (set_child_nodes_locs ptr) (set_child_nodes ptr children) h h'"
+ apply(simp add: set_child_nodes_locs_impl set_child_nodes_impl a_set_child_nodes_def
+ a_set_child_nodes_tups_def a_set_child_nodes_locs_def)
+ apply(split invoke_splits, rule conjI)+
+ apply(auto)[1]
+ apply(auto simp add: set_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: writes_bind_pure
+ intro: writes_union_right_I split: list.splits)[1]
+ apply(auto intro: writes_union_right_I split: option.splits)[1]
+ apply(auto intro: writes_union_right_I split: option.splits)[1]
+ apply(auto intro: writes_union_right_I split: option.splits)[1]
+ apply(auto intro: writes_union_right_I split: option.splits)[1]
+ apply(auto intro: writes_union_right_I split: option.splits)[1]
+ apply(auto intro: writes_union_right_I split: option.splits)[1] (*slow: ca. 1min *)
+ apply(auto simp add: set_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: writes_bind_pure)[1]
+ apply(auto simp add: set_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro: writes_union_left_I
+ intro!: writes_bind_pure split: list.splits option.splits)[1]
+ done
+
+lemma set_child_nodes_pointers_preserved:
+ assumes "w \<in> set_child_nodes_locs object_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms(1) object_ptr_kinds_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: set_child_nodes_locs_impl all_args_def a_set_child_nodes_locs_def
+ split: if_splits)
+
+lemma set_child_nodes_typess_preserved:
+ assumes "w \<in> set_child_nodes_locs object_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ using assms(1) type_wf_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: set_child_nodes_locs_impl type_wf_impl all_args_def a_set_child_nodes_locs_def
+ split: if_splits)
+end
+
+locale l_set_child_nodes = l_type_wf + l_set_child_nodes_defs +
+ assumes set_child_nodes_writes:
+ "writes (set_child_nodes_locs ptr) (set_child_nodes ptr children) h h'"
+ assumes set_child_nodes_pointers_preserved:
+ "w \<in> set_child_nodes_locs object_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> object_ptr_kinds h = object_ptr_kinds h'"
+ assumes set_child_nodes_types_preserved:
+ "w \<in> set_child_nodes_locs object_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+
+global_interpretation l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs defines
+ set_child_nodes = l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_child_nodes and
+ set_child_nodes_locs = l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_child_nodes_locs .
+
+interpretation
+ i_set_child_nodes?: l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr set_child_nodes set_child_nodes_locs
+ apply(unfold_locales)
+ by (auto simp add: set_child_nodes_def set_child_nodes_locs_def)
+declare l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+lemma set_child_nodes_is_l_set_child_nodes [instances]:
+ "l_set_child_nodes type_wf set_child_nodes set_child_nodes_locs"
+ apply(unfold_locales)
+ using set_child_nodes_pointers_preserved set_child_nodes_typess_preserved set_child_nodes_writes
+ by blast+
+
+
+paragraph \<open>get\_child\_nodes\<close>
+
+locale l_set_child_nodes_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M + l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma set_child_nodes_get_child_nodes:
+ assumes "known_ptr ptr"
+ assumes "type_wf h"
+ assumes "h \<turnstile> set_child_nodes ptr children \<rightarrow>\<^sub>h h'"
+ shows "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+proof -
+ have "h \<turnstile> check_in_heap ptr \<rightarrow>\<^sub>r ()"
+ using assms set_child_nodes_impl[unfolded a_set_child_nodes_def] invoke_ptr_in_heap
+ by (metis (full_types) check_in_heap_ptr_in_heap is_OK_returns_heap_I is_OK_returns_result_E
+ old.unit.exhaust)
+ then have ptr_in_h: "ptr |\<in>| object_ptr_kinds h"
+ by (simp add: check_in_heap_ptr_in_heap is_OK_returns_result_I)
+
+ have "type_wf h'"
+ apply(unfold type_wf_impl)
+ apply(rule subst[where P=id, OF type_wf_preserved[OF set_child_nodes_writes assms(3),
+ unfolded all_args_def], simplified])
+ by(auto simp add: all_args_def assms(2)[unfolded type_wf_impl]
+ set_child_nodes_locs_impl[unfolded a_set_child_nodes_locs_def]
+ split: if_splits)
+ have "h' \<turnstile> check_in_heap ptr \<rightarrow>\<^sub>r ()"
+ using check_in_heap_reads set_child_nodes_writes assms(3) \<open>h \<turnstile> check_in_heap ptr \<rightarrow>\<^sub>r ()\<close>
+ apply(rule reads_writes_separate_forwards)
+ by(auto simp add: all_args_def set_child_nodes_locs_impl[unfolded a_set_child_nodes_locs_def])
+ then have "ptr |\<in>| object_ptr_kinds h'"
+ using check_in_heap_ptr_in_heap by blast
+ with assms ptr_in_h \<open>type_wf h'\<close> show ?thesis
+ apply(auto simp add: get_child_nodes_impl set_child_nodes_impl type_wf_impl known_ptr_impl
+ a_get_child_nodes_def a_get_child_nodes_tups_def a_set_child_nodes_def
+ a_set_child_nodes_tups_def
+ del: bind_pure_returns_result_I2
+ intro!: bind_pure_returns_result_I2)[1]
+ apply(split invoke_splits, rule conjI)
+ apply(split invoke_splits, rule conjI)
+ apply(split invoke_splits, rule conjI)
+ apply(auto simp add: NodeClass.known_ptr_defs
+ dest!: known_ptr_not_document_ptr known_ptr_not_character_data_ptr
+ known_ptr_not_element_ptr)[1]
+ apply(auto simp add: NodeClass.known_ptr_defs
+ dest!: known_ptr_not_document_ptr known_ptr_not_character_data_ptr
+ known_ptr_not_element_ptr)[1]
+ apply(auto simp add: get_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def set_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok
+ split: list.splits option.splits
+ intro!: bind_pure_returns_result_I2
+ dest: get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok; auto dest: returns_result_eq
+ dest!: document_put_get[where getter = document_element])[1] (* slow, ca 1min *)
+ apply(auto simp add: get_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def set_child_nodes\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)[1]
+ by(auto simp add: get_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def set_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def dest: element_put_get)
+qed
+
+lemma set_child_nodes_get_child_nodes_different_pointers:
+ assumes "ptr \<noteq> ptr'"
+ assumes "w \<in> set_child_nodes_locs ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ assumes "r \<in> get_child_nodes_locs ptr'"
+ shows "r h h'"
+ using assms
+ apply(auto simp add: get_child_nodes_locs_impl set_child_nodes_locs_impl all_args_def
+ a_set_child_nodes_locs_def a_get_child_nodes_locs_def
+ split: if_splits option.splits )[1]
+ apply(rule is_document_ptr_kind_obtains)
+ apply(simp)
+ apply(rule is_document_ptr_kind_obtains)
+ apply(auto)[1]
+ apply(auto)[1]
+ apply(rule is_element_ptr_kind_obtains)
+ apply(auto)[1]
+ apply(auto)[1]
+ apply(rule is_element_ptr_kind_obtains)
+ apply(auto)[1]
+ apply(auto)[1]
+ done
+
+lemma set_child_nodes_element_ok [simp]:
+ assumes "known_ptr ptr"
+ assumes "type_wf h"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ assumes "is_element_ptr_kind ptr"
+ shows "h \<turnstile> ok (set_child_nodes ptr children)"
+proof -
+ have "is_element_ptr ptr"
+ using \<open>known_ptr ptr\<close> assms(4)
+ by(auto simp add: known_ptr_impl known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+ then show ?thesis
+ using assms
+ apply(auto simp add: set_child_nodes_def a_set_child_nodes_tups_def set_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: option.splits)[1]
+ by (simp add: DocumentMonad.put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok local.type_wf_impl)
+qed
+
+lemma set_child_nodes_document1_ok [simp]:
+ assumes "known_ptr ptr"
+ assumes "type_wf h"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ assumes "is_document_ptr_kind ptr"
+ assumes "children = []"
+ shows "h \<turnstile> ok (set_child_nodes ptr children)"
+proof -
+ have "is_document_ptr ptr"
+ using \<open>known_ptr ptr\<close> assms(4)
+ by(auto simp add: known_ptr_impl known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+ then show ?thesis
+ using assms
+ apply(auto simp add: set_child_nodes_def a_set_child_nodes_tups_def set_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: option.splits)[1]
+ by (simp add: DocumentMonad.put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok local.type_wf_impl)
+qed
+
+lemma set_child_nodes_document2_ok [simp]:
+ assumes "known_ptr ptr"
+ assumes "type_wf h"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ assumes "is_document_ptr_kind ptr"
+ assumes "children = [child]"
+ assumes "is_element_ptr_kind child"
+ shows "h \<turnstile> ok (set_child_nodes ptr children)"
+proof -
+ have "is_document_ptr ptr"
+ using \<open>known_ptr ptr\<close> assms(4)
+ by(auto simp add: known_ptr_impl known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+ then show ?thesis
+ using assms
+ apply(auto simp add: set_child_nodes_def a_set_child_nodes_tups_def set_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)[1]
+ apply(split invoke_splits, rule conjI)+
+ apply(auto simp add: is_element_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def set_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def split: option.splits)[1]
+ apply(auto simp add: is_element_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def set_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def split: option.splits)[1]
+ apply (simp add: local.type_wf_impl put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok)
+ apply(auto simp add: is_element_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def set_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def split: option.splits)[1]
+ by(auto simp add: is_element_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def set_child_nodes\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def split: option.splits)[1]
+qed
+end
+
+locale l_set_child_nodes_get_child_nodes = l_get_child_nodes + l_set_child_nodes +
+ assumes set_child_nodes_get_child_nodes:
+ "type_wf h \<Longrightarrow> known_ptr ptr
+ \<Longrightarrow> h \<turnstile> set_child_nodes ptr children \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assumes set_child_nodes_get_child_nodes_different_pointers:
+ "ptr \<noteq> ptr' \<Longrightarrow> w \<in> set_child_nodes_locs ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+
+interpretation
+ i_set_child_nodes_get_child_nodes?: l_set_child_nodes_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ known_ptr get_child_nodes get_child_nodes_locs set_child_nodes set_child_nodes_locs
+ by unfold_locales
+declare l_set_child_nodes_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_child_nodes_get_child_nodes_is_l_set_child_nodes_get_child_nodes [instances]:
+ "l_set_child_nodes_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs
+ set_child_nodes set_child_nodes_locs"
+ using get_child_nodes_is_l_get_child_nodes set_child_nodes_is_l_set_child_nodes
+ apply(auto simp add: l_set_child_nodes_get_child_nodes_def l_set_child_nodes_get_child_nodes_axioms_def)[1]
+ using set_child_nodes_get_child_nodes apply blast
+ using set_child_nodes_get_child_nodes_different_pointers apply metis
+ done
+
+
+subsubsection \<open>get\_attribute\<close>
+
+locale l_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+definition a_get_attribute :: "(_) element_ptr \<Rightarrow> attr_key \<Rightarrow> (_, attr_value option) dom_prog"
+ where
+ "a_get_attribute ptr k = do {m \<leftarrow> get_M ptr attrs; return (fmlookup m k)}"
+lemmas get_attribute_defs = a_get_attribute_def
+
+definition a_get_attribute_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ where
+ "a_get_attribute_locs element_ptr = {preserved (get_M element_ptr attrs)}"
+end
+
+locale l_get_attribute_defs =
+ fixes get_attribute :: "(_) element_ptr \<Rightarrow> attr_key \<Rightarrow> (_, attr_value option) dom_prog"
+ fixes get_attribute_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_get_attribute_defs get_attribute get_attribute_locs +
+ l_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_attribute :: "(_) element_ptr \<Rightarrow> attr_key \<Rightarrow> (_, attr_value option) dom_prog"
+ and get_attribute_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes type_wf_impl: "type_wf = DocumentClass.type_wf"
+ assumes get_attribute_impl: "get_attribute = a_get_attribute"
+ assumes get_attribute_locs_impl: "get_attribute_locs = a_get_attribute_locs"
+begin
+lemma get_attribute_pure [simp]: "pure (get_attribute ptr k) h"
+ by (auto simp add: bind_pure_I get_attribute_impl[unfolded a_get_attribute_def])
+
+lemma get_attribute_ok:
+ "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_attribute element_ptr k)"
+ apply(unfold type_wf_impl)
+ unfolding get_attribute_impl[unfolded a_get_attribute_def] using get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok
+ by (metis bind_is_OK_pure_I return_ok ElementMonad.get_M_pure)
+
+lemma get_attribute_ptr_in_heap:
+ "h \<turnstile> ok (get_attribute element_ptr k) \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h"
+ unfolding get_attribute_impl[unfolded a_get_attribute_def]
+ by (meson DocumentMonad.get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap bind_is_OK_E is_OK_returns_result_I)
+
+lemma get_attribute_reads:
+ "reads (get_attribute_locs element_ptr) (get_attribute element_ptr k) h h'"
+ by(auto simp add: get_attribute_impl[unfolded a_get_attribute_def]
+ get_attribute_locs_impl[unfolded a_get_attribute_locs_def]
+ reads_insert_writes_set_right
+ intro!: reads_bind_pure)
+end
+
+locale l_get_attribute = l_type_wf + l_get_attribute_defs +
+assumes get_attribute_reads:
+ "reads (get_attribute_locs element_ptr) (get_attribute element_ptr k) h h'"
+assumes get_attribute_ok:
+ "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_attribute element_ptr k)"
+assumes get_attribute_ptr_in_heap:
+ "h \<turnstile> ok (get_attribute element_ptr k) \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h"
+assumes get_attribute_pure [simp]: "pure (get_attribute element_ptr k) h"
+
+global_interpretation l_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs defines
+ get_attribute = l_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_attribute and
+ get_attribute_locs = l_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_attribute_locs .
+
+interpretation
+ i_get_attribute?: l_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_attribute get_attribute_locs
+ apply(unfold_locales)
+ by (auto simp add: get_attribute_def get_attribute_locs_def)
+declare l_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_attribute_is_l_get_attribute [instances]:
+ "l_get_attribute type_wf get_attribute get_attribute_locs"
+ apply(unfold_locales)
+ using get_attribute_reads get_attribute_ok get_attribute_ptr_in_heap get_attribute_pure
+ by blast+
+
+
+subsubsection \<open>set\_attribute\<close>
+
+locale l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+
+definition
+ a_set_attribute :: "(_) element_ptr \<Rightarrow> attr_key \<Rightarrow> attr_value option \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_set_attribute ptr k v = do {
+ m \<leftarrow> get_M ptr attrs;
+ put_M ptr attrs_update (if v = None then fmdrop k m else fmupd k (the v) m)
+ }"
+
+definition a_set_attribute_locs :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog set"
+ where
+ "a_set_attribute_locs element_ptr \<equiv> all_args (put_M element_ptr attrs_update)"
+end
+
+locale l_set_attribute_defs =
+ fixes set_attribute :: "(_) element_ptr \<Rightarrow> attr_key \<Rightarrow> attr_value option \<Rightarrow> (_, unit) dom_prog"
+ fixes set_attribute_locs :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog set"
+
+locale l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_set_attribute_defs set_attribute set_attribute_locs +
+ l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and set_attribute :: "(_) element_ptr \<Rightarrow> attr_key \<Rightarrow> attr_value option \<Rightarrow> (_, unit) dom_prog"
+ and set_attribute_locs :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog set" +
+ assumes type_wf_impl: "type_wf = DocumentClass.type_wf"
+ assumes set_attribute_impl: "set_attribute = a_set_attribute"
+ assumes set_attribute_locs_impl: "set_attribute_locs = a_set_attribute_locs"
+begin
+lemmas set_attribute_def = set_attribute_impl[folded a_set_attribute_def]
+lemmas set_attribute_locs_def = set_attribute_locs_impl[unfolded a_set_attribute_locs_def]
+
+lemma set_attribute_ok: "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (set_attribute element_ptr k v)"
+ apply(unfold type_wf_impl)
+ unfolding set_attribute_impl[unfolded a_set_attribute_def] using get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok
+ by(metis (no_types, lifting) DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ElementMonad.get_M_pure bind_is_OK_E
+ bind_is_OK_pure_I is_OK_returns_result_I)
+
+lemma set_attribute_writes:
+ "writes (set_attribute_locs element_ptr) (set_attribute element_ptr k v) h h'"
+ by(auto simp add: set_attribute_impl[unfolded a_set_attribute_def]
+ set_attribute_locs_impl[unfolded a_set_attribute_locs_def]
+ intro: writes_bind_pure)
+end
+
+locale l_set_attribute = l_type_wf + l_set_attribute_defs +
+ assumes set_attribute_writes:
+ "writes (set_attribute_locs element_ptr) (set_attribute element_ptr k v) h h'"
+ assumes set_attribute_ok:
+ "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (set_attribute element_ptr k v)"
+
+global_interpretation l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs defines
+ set_attribute = l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_attribute and
+ set_attribute_locs = l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_attribute_locs .
+interpretation
+ i_set_attribute?: l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_attribute set_attribute_locs
+ apply(unfold_locales)
+ by (auto simp add: set_attribute_def set_attribute_locs_def)
+declare l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_attribute_is_l_set_attribute [instances]:
+ "l_set_attribute type_wf set_attribute set_attribute_locs"
+ apply(unfold_locales)
+ using set_attribute_ok set_attribute_writes
+ by blast+
+
+
+paragraph \<open>get\_attribute\<close>
+
+locale l_set_attribute_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma set_attribute_get_attribute:
+ "h \<turnstile> set_attribute ptr k v \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> get_attribute ptr k \<rightarrow>\<^sub>r v"
+ by(auto simp add: set_attribute_impl[unfolded a_set_attribute_def]
+ get_attribute_impl[unfolded a_get_attribute_def]
+ elim!: bind_returns_heap_E2
+ intro!: bind_pure_returns_result_I
+ elim: element_put_get)
+end
+
+locale l_set_attribute_get_attribute = l_get_attribute + l_set_attribute +
+ assumes set_attribute_get_attribute:
+ "h \<turnstile> set_attribute ptr k v \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> get_attribute ptr k \<rightarrow>\<^sub>r v"
+
+interpretation
+ i_set_attribute_get_attribute?: l_set_attribute_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ get_attribute get_attribute_locs set_attribute set_attribute_locs
+ by(unfold_locales)
+declare l_set_attribute_get_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_attribute_get_attribute_is_l_set_attribute_get_attribute [instances]:
+ "l_set_attribute_get_attribute type_wf get_attribute get_attribute_locs set_attribute set_attribute_locs"
+ using get_attribute_is_l_get_attribute set_attribute_is_l_set_attribute
+ apply(simp add: l_set_attribute_get_attribute_def l_set_attribute_get_attribute_axioms_def)
+ using set_attribute_get_attribute
+ by blast
+
+paragraph \<open>get\_child\_nodes\<close>
+
+locale l_set_attribute_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_attribute_get_child_nodes:
+ "\<forall>w \<in> set_attribute_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+ by(auto simp add: set_attribute_locs_def get_child_nodes_locs_def all_args_def
+ intro: element_put_get_preserved[where setter=attrs_update])
+end
+
+locale l_set_attribute_get_child_nodes =
+ l_set_attribute +
+ l_get_child_nodes +
+ assumes set_attribute_get_child_nodes:
+ "\<forall>w \<in> set_attribute_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+
+interpretation
+ i_set_attribute_get_child_nodes?: l_set_attribute_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ set_attribute set_attribute_locs known_ptr get_child_nodes get_child_nodes_locs
+ by unfold_locales
+declare l_set_attribute_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_attribute_get_child_nodes_is_l_set_attribute_get_child_nodes [instances]:
+ "l_set_attribute_get_child_nodes type_wf set_attribute set_attribute_locs known_ptr
+ get_child_nodes get_child_nodes_locs"
+ using set_attribute_is_l_set_attribute get_child_nodes_is_l_get_child_nodes
+ apply(simp add: l_set_attribute_get_child_nodes_def l_set_attribute_get_child_nodes_axioms_def)
+ using set_attribute_get_child_nodes
+ by blast
+
+
+subsubsection \<open>get\_disconnected\_nodes\<close>
+
+locale l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+definition a_get_disconnected_nodes :: "(_) document_ptr
+ \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ where
+ "a_get_disconnected_nodes document_ptr = get_M document_ptr disconnected_nodes"
+lemmas get_disconnected_nodes_defs = a_get_disconnected_nodes_def
+
+definition a_get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ where
+ "a_get_disconnected_nodes_locs document_ptr = {preserved (get_M document_ptr disconnected_nodes)}"
+end
+
+locale l_get_disconnected_nodes_defs =
+ fixes get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ fixes get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_get_disconnected_nodes_defs get_disconnected_nodes get_disconnected_nodes_locs +
+ l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes type_wf_impl: "type_wf = DocumentClass.type_wf"
+ assumes get_disconnected_nodes_impl: "get_disconnected_nodes = a_get_disconnected_nodes"
+ assumes get_disconnected_nodes_locs_impl: "get_disconnected_nodes_locs = a_get_disconnected_nodes_locs"
+begin
+lemmas
+ get_disconnected_nodes_def = get_disconnected_nodes_impl[unfolded a_get_disconnected_nodes_def]
+lemmas
+ get_disconnected_nodes_locs_def = get_disconnected_nodes_locs_impl[unfolded a_get_disconnected_nodes_locs_def]
+
+lemma get_disconnected_nodes_ok:
+ "type_wf h \<Longrightarrow> document_ptr |\<in>| document_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_disconnected_nodes document_ptr)"
+ apply(unfold type_wf_impl)
+ unfolding get_disconnected_nodes_impl[unfolded a_get_disconnected_nodes_def] using get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok
+ by fast
+
+lemma get_disconnected_nodes_ptr_in_heap:
+ "h \<turnstile> ok (get_disconnected_nodes document_ptr) \<Longrightarrow> document_ptr |\<in>| document_ptr_kinds h"
+ unfolding get_disconnected_nodes_impl[unfolded a_get_disconnected_nodes_def]
+ by (simp add: DocumentMonad.get_M_ptr_in_heap)
+
+lemma get_disconnected_nodes_pure [simp]: "pure (get_disconnected_nodes document_ptr) h"
+ unfolding get_disconnected_nodes_impl[unfolded a_get_disconnected_nodes_def] by simp
+
+lemma get_disconnected_nodes_reads:
+ "reads (get_disconnected_nodes_locs document_ptr) (get_disconnected_nodes document_ptr) h h'"
+ by(simp add: get_disconnected_nodes_impl[unfolded a_get_disconnected_nodes_def]
+ get_disconnected_nodes_locs_impl[unfolded a_get_disconnected_nodes_locs_def]
+ reads_bind_pure reads_insert_writes_set_right)
+end
+
+locale l_get_disconnected_nodes = l_type_wf + l_get_disconnected_nodes_defs +
+ assumes get_disconnected_nodes_reads:
+ "reads (get_disconnected_nodes_locs document_ptr) (get_disconnected_nodes document_ptr) h h'"
+ assumes get_disconnected_nodes_ok:
+ "type_wf h \<Longrightarrow> document_ptr |\<in>| document_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_disconnected_nodes document_ptr)"
+ assumes get_disconnected_nodes_ptr_in_heap:
+ "h \<turnstile> ok (get_disconnected_nodes document_ptr) \<Longrightarrow> document_ptr |\<in>| document_ptr_kinds h"
+ assumes get_disconnected_nodes_pure [simp]:
+ "pure (get_disconnected_nodes document_ptr) h"
+
+global_interpretation l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs defines
+ get_disconnected_nodes = l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_disconnected_nodes and
+ get_disconnected_nodes_locs = l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_disconnected_nodes_locs .
+interpretation
+ i_get_disconnected_nodes?: l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_disconnected_nodes
+ get_disconnected_nodes_locs
+ apply(unfold_locales)
+ by (auto simp add: get_disconnected_nodes_def get_disconnected_nodes_locs_def)
+declare l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_disconnected_nodes_is_l_get_disconnected_nodes [instances]:
+ "l_get_disconnected_nodes type_wf get_disconnected_nodes get_disconnected_nodes_locs"
+ apply(simp add: l_get_disconnected_nodes_def)
+ using get_disconnected_nodes_reads get_disconnected_nodes_ok get_disconnected_nodes_ptr_in_heap
+ get_disconnected_nodes_pure
+ by blast+
+
+
+paragraph \<open>set\_child\_nodes\<close>
+
+locale l_set_child_nodes_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ CD: l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_child_nodes_get_disconnected_nodes:
+ "\<forall>w \<in> a_set_child_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> a_get_disconnected_nodes_locs ptr'. r h h'))"
+ by(auto simp add: a_set_child_nodes_locs_def a_get_disconnected_nodes_locs_def all_args_def)
+end
+
+locale l_set_child_nodes_get_disconnected_nodes = l_set_child_nodes + l_get_disconnected_nodes +
+ assumes set_child_nodes_get_disconnected_nodes:
+ "\<forall>w \<in> set_child_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+
+interpretation
+ i_set_child_nodes_get_disconnected_nodes?: l_set_child_nodes_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ known_ptr set_child_nodes set_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs
+ by(unfold_locales)
+declare l_set_child_nodes_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_child_nodes_get_disconnected_nodes_is_l_set_child_nodes_get_disconnected_nodes [instances]:
+ "l_set_child_nodes_get_disconnected_nodes type_wf set_child_nodes set_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs"
+ using set_child_nodes_is_l_set_child_nodes get_disconnected_nodes_is_l_get_disconnected_nodes
+ apply(simp add: l_set_child_nodes_get_disconnected_nodes_def
+ l_set_child_nodes_get_disconnected_nodes_axioms_def)
+ using set_child_nodes_get_disconnected_nodes
+ by fast
+
+
+paragraph \<open>set\_attribute\<close>
+
+locale l_set_attribute_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_attribute_get_disconnected_nodes:
+ "\<forall>w \<in> a_set_attribute_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> a_get_disconnected_nodes_locs ptr'. r h h'))"
+ by(auto simp add: a_set_attribute_locs_def a_get_disconnected_nodes_locs_def all_args_def)
+end
+
+locale l_set_attribute_get_disconnected_nodes = l_set_attribute + l_get_disconnected_nodes +
+ assumes set_attribute_get_disconnected_nodes:
+ "\<forall>w \<in> set_attribute_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+
+interpretation
+ i_set_attribute_get_disconnected_nodes?: l_set_attribute_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ set_attribute set_attribute_locs get_disconnected_nodes get_disconnected_nodes_locs
+ by(unfold_locales)
+declare l_set_attribute_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_attribute_get_disconnected_nodes_is_l_set_attribute_get_disconnected_nodes [instances]:
+ "l_set_attribute_get_disconnected_nodes type_wf set_attribute set_attribute_locs
+ get_disconnected_nodes get_disconnected_nodes_locs"
+ using set_attribute_is_l_set_attribute get_disconnected_nodes_is_l_get_disconnected_nodes
+ apply(simp add: l_set_attribute_get_disconnected_nodes_def
+ l_set_attribute_get_disconnected_nodes_axioms_def)
+ using set_attribute_get_disconnected_nodes
+ by fast
+
+
+paragraph \<open>new\_element\<close>
+
+locale l_new_element_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_disconnected_nodes get_disconnected_nodes_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_disconnected_nodes_new_element:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_disconnected_nodes_locs ptr' \<Longrightarrow> r h h'"
+ by(auto simp add: get_disconnected_nodes_locs_def new_element_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+end
+
+locale l_new_element_get_disconnected_nodes = l_get_disconnected_nodes_defs +
+ assumes get_disconnected_nodes_new_element:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_disconnected_nodes_locs ptr' \<Longrightarrow> r h h'"
+
+interpretation i_new_element_get_disconnected_nodes?:
+ l_new_element_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_disconnected_nodes
+ get_disconnected_nodes_locs
+ by unfold_locales
+declare l_new_element_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma new_element_get_disconnected_nodes_is_l_new_element_get_disconnected_nodes [instances]:
+ "l_new_element_get_disconnected_nodes get_disconnected_nodes_locs"
+ by (simp add: get_disconnected_nodes_new_element l_new_element_get_disconnected_nodes_def)
+
+
+paragraph \<open>new\_character\_data\<close>
+
+locale l_new_character_data_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_disconnected_nodes get_disconnected_nodes_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_disconnected_nodes_new_character_data:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_disconnected_nodes_locs ptr' \<Longrightarrow> r h h'"
+ by(auto simp add: get_disconnected_nodes_locs_def new_character_data_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+end
+
+locale l_new_character_data_get_disconnected_nodes = l_get_disconnected_nodes_defs +
+ assumes get_disconnected_nodes_new_character_data:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_disconnected_nodes_locs ptr' \<Longrightarrow> r h h'"
+
+interpretation i_new_character_data_get_disconnected_nodes?:
+ l_new_character_data_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_disconnected_nodes
+ get_disconnected_nodes_locs
+ by unfold_locales
+declare l_new_character_data_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma new_character_data_get_disconnected_nodes_is_l_new_character_data_get_disconnected_nodes [instances]:
+ "l_new_character_data_get_disconnected_nodes get_disconnected_nodes_locs"
+ by (simp add: get_disconnected_nodes_new_character_data l_new_character_data_get_disconnected_nodes_def)
+
+
+paragraph \<open>new\_document\<close>
+
+locale l_new_document_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_disconnected_nodes get_disconnected_nodes_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_disconnected_nodes_new_document_different_pointers:
+ "new_document_ptr \<noteq> ptr' \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_disconnected_nodes_locs ptr' \<Longrightarrow> r h h'"
+ by(auto simp add: get_disconnected_nodes_locs_def new_document_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+
+lemma new_document_no_disconnected_nodes:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_disconnected_nodes new_document_ptr \<rightarrow>\<^sub>r []"
+ by(simp add: get_disconnected_nodes_def new_document_disconnected_nodes)
+
+end
+
+interpretation i_new_document_get_disconnected_nodes?:
+ l_new_document_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_disconnected_nodes get_disconnected_nodes_locs
+ by unfold_locales
+declare l_new_document_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+locale l_new_document_get_disconnected_nodes = l_get_disconnected_nodes_defs +
+ assumes get_disconnected_nodes_new_document_different_pointers:
+ "new_document_ptr \<noteq> ptr' \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_disconnected_nodes_locs ptr' \<Longrightarrow> r h h'"
+ assumes new_document_no_disconnected_nodes:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_disconnected_nodes new_document_ptr \<rightarrow>\<^sub>r []"
+
+lemma new_document_get_disconnected_nodes_is_l_new_document_get_disconnected_nodes [instances]:
+ "l_new_document_get_disconnected_nodes get_disconnected_nodes get_disconnected_nodes_locs"
+ apply (auto simp add: l_new_document_get_disconnected_nodes_def)[1]
+ using get_disconnected_nodes_new_document_different_pointers apply fast
+ using new_document_no_disconnected_nodes apply blast
+ done
+
+
+
+subsubsection \<open>set\_disconnected\_nodes\<close>
+
+locale l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+
+definition a_set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_set_disconnected_nodes document_ptr disc_nodes =
+put_M document_ptr disconnected_nodes_update disc_nodes"
+lemmas set_disconnected_nodes_defs = a_set_disconnected_nodes_def
+
+definition a_set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+ where
+ "a_set_disconnected_nodes_locs document_ptr \<equiv> all_args (put_M document_ptr disconnected_nodes_update)"
+end
+
+locale l_set_disconnected_nodes_defs =
+ fixes set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ fixes set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+
+locale l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_set_disconnected_nodes_defs set_disconnected_nodes set_disconnected_nodes_locs +
+ l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> (_, unit) dom_prog set" +
+ assumes type_wf_impl: "type_wf = DocumentClass.type_wf"
+ assumes set_disconnected_nodes_impl: "set_disconnected_nodes = a_set_disconnected_nodes"
+ assumes set_disconnected_nodes_locs_impl: "set_disconnected_nodes_locs = a_set_disconnected_nodes_locs"
+begin
+lemmas set_disconnected_nodes_def = set_disconnected_nodes_impl[unfolded a_set_disconnected_nodes_def]
+lemmas set_disconnected_nodes_locs_def =
+ set_disconnected_nodes_locs_impl[unfolded a_set_disconnected_nodes_locs_def]
+lemma set_disconnected_nodes_ok:
+ "type_wf h \<Longrightarrow> document_ptr |\<in>| document_ptr_kinds h \<Longrightarrow>
+h \<turnstile> ok (set_disconnected_nodes document_ptr node_ptrs)"
+ by (simp add: type_wf_impl put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok
+ set_disconnected_nodes_impl[unfolded a_set_disconnected_nodes_def])
+
+lemma set_disconnected_nodes_ptr_in_heap:
+ "h \<turnstile> ok (set_disconnected_nodes document_ptr disc_nodes) \<Longrightarrow> document_ptr |\<in>| document_ptr_kinds h"
+ by (simp add: set_disconnected_nodes_impl[unfolded a_set_disconnected_nodes_def]
+ DocumentMonad.put_M_ptr_in_heap)
+
+lemma set_disconnected_nodes_writes:
+ "writes (set_disconnected_nodes_locs document_ptr) (set_disconnected_nodes document_ptr disc_nodes) h h'"
+ by(auto simp add: set_disconnected_nodes_impl[unfolded a_set_disconnected_nodes_def]
+ set_disconnected_nodes_locs_impl[unfolded a_set_disconnected_nodes_locs_def]
+ intro: writes_bind_pure)
+
+lemma set_disconnected_nodes_pointers_preserved:
+ assumes "w \<in> set_disconnected_nodes_locs object_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms(1) object_ptr_kinds_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: all_args_def set_disconnected_nodes_locs_impl[unfolded
+ a_set_disconnected_nodes_locs_def]
+ split: if_splits)
+
+lemma set_disconnected_nodes_typess_preserved:
+ assumes "w \<in> set_disconnected_nodes_locs object_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ using assms(1) type_wf_preserved[OF writes_singleton2 assms(2)]
+ apply(unfold type_wf_impl)
+ by(auto simp add: all_args_def
+ set_disconnected_nodes_locs_impl[unfolded a_set_disconnected_nodes_locs_def]
+ split: if_splits)
+end
+
+locale l_set_disconnected_nodes = l_type_wf + l_set_disconnected_nodes_defs +
+ assumes set_disconnected_nodes_writes:
+ "writes (set_disconnected_nodes_locs document_ptr)
+(set_disconnected_nodes document_ptr disc_nodes) h h'"
+ assumes set_disconnected_nodes_ok:
+ "type_wf h \<Longrightarrow> document_ptr |\<in>| document_ptr_kinds h \<Longrightarrow>
+h \<turnstile> ok (set_disconnected_nodes document_ptr disc_noded)"
+ assumes set_disconnected_nodes_ptr_in_heap:
+ "h \<turnstile> ok (set_disconnected_nodes document_ptr disc_noded) \<Longrightarrow>
+document_ptr |\<in>| document_ptr_kinds h"
+ assumes set_disconnected_nodes_pointers_preserved:
+ "w \<in> set_disconnected_nodes_locs document_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow>
+object_ptr_kinds h = object_ptr_kinds h'"
+ assumes set_disconnected_nodes_types_preserved:
+ "w \<in> set_disconnected_nodes_locs document_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+
+global_interpretation l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs defines
+ set_disconnected_nodes = l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_disconnected_nodes and
+ set_disconnected_nodes_locs = l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_disconnected_nodes_locs .
+interpretation
+ i_set_disconnected_nodes?: l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_disconnected_nodes
+ set_disconnected_nodes_locs
+ apply unfold_locales
+ by (auto simp add: set_disconnected_nodes_def set_disconnected_nodes_locs_def)
+declare l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_disconnected_nodes_is_l_set_disconnected_nodes [instances]:
+ "l_set_disconnected_nodes type_wf set_disconnected_nodes set_disconnected_nodes_locs"
+ apply(simp add: l_set_disconnected_nodes_def)
+ using set_disconnected_nodes_ok set_disconnected_nodes_writes
+ set_disconnected_nodes_pointers_preserved
+ set_disconnected_nodes_ptr_in_heap set_disconnected_nodes_typess_preserved
+ by blast+
+
+
+paragraph \<open>get\_disconnected\_nodes\<close>
+
+locale l_set_disconnected_nodes_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_disconnected_nodes_get_disconnected_nodes:
+ assumes "h \<turnstile> a_set_disconnected_nodes document_ptr disc_nodes \<rightarrow>\<^sub>h h'"
+ shows "h' \<turnstile> a_get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using assms
+ by(auto simp add: a_get_disconnected_nodes_def a_set_disconnected_nodes_def)
+
+lemma set_disconnected_nodes_get_disconnected_nodes_different_pointers:
+ assumes "ptr \<noteq> ptr'"
+ assumes "w \<in> a_set_disconnected_nodes_locs ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ assumes "r \<in> a_get_disconnected_nodes_locs ptr'"
+ shows "r h h'"
+ using assms
+ by(auto simp add: all_args_def a_set_disconnected_nodes_locs_def a_get_disconnected_nodes_locs_def
+ split: if_splits option.splits )
+end
+
+locale l_set_disconnected_nodes_get_disconnected_nodes = l_get_disconnected_nodes
+ + l_set_disconnected_nodes +
+ assumes set_disconnected_nodes_get_disconnected_nodes:
+ "h \<turnstile> set_disconnected_nodes document_ptr disc_nodes \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes"
+ assumes set_disconnected_nodes_get_disconnected_nodes_different_pointers:
+ "ptr \<noteq> ptr' \<Longrightarrow> w \<in> set_disconnected_nodes_locs ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_disconnected_nodes_locs ptr' \<Longrightarrow> r h h'"
+
+interpretation i_set_disconnected_nodes_get_disconnected_nodes?:
+ l_set_disconnected_nodes_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs
+ by unfold_locales
+declare l_set_disconnected_nodes_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_disconnected_nodes_get_disconnected_nodes_is_l_set_disconnected_nodes_get_disconnected_nodes
+ [instances]:
+ "l_set_disconnected_nodes_get_disconnected_nodes type_wf get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs"
+ using set_disconnected_nodes_is_l_set_disconnected_nodes get_disconnected_nodes_is_l_get_disconnected_nodes
+ apply(simp add: l_set_disconnected_nodes_get_disconnected_nodes_def
+ l_set_disconnected_nodes_get_disconnected_nodes_axioms_def)
+ using set_disconnected_nodes_get_disconnected_nodes
+ set_disconnected_nodes_get_disconnected_nodes_different_pointers
+ by fast+
+
+
+paragraph \<open>get\_child\_nodes\<close>
+
+locale l_set_disconnected_nodes_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_disconnected_nodes_get_child_nodes:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+ by(auto simp add: set_disconnected_nodes_locs_impl[unfolded a_set_disconnected_nodes_locs_def]
+ get_child_nodes_locs_impl[unfolded a_get_child_nodes_locs_def] all_args_def)
+end
+
+locale l_set_disconnected_nodes_get_child_nodes = l_set_disconnected_nodes_defs + l_get_child_nodes_defs +
+ assumes set_disconnected_nodes_get_child_nodes [simp]:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+
+interpretation
+ i_set_disconnected_nodes_get_child_nodes?: l_set_disconnected_nodes_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf
+ set_disconnected_nodes set_disconnected_nodes_locs
+ known_ptr get_child_nodes get_child_nodes_locs
+ by unfold_locales
+declare l_set_disconnected_nodes_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_disconnected_nodes_get_child_nodes_is_l_set_disconnected_nodes_get_child_nodes [instances]:
+ "l_set_disconnected_nodes_get_child_nodes set_disconnected_nodes_locs get_child_nodes_locs"
+ using set_disconnected_nodes_is_l_set_disconnected_nodes get_child_nodes_is_l_get_child_nodes
+ apply(simp add: l_set_disconnected_nodes_get_child_nodes_def)
+ using set_disconnected_nodes_get_child_nodes
+ by fast
+
+
+subsubsection \<open>get\_tag\_name\<close>
+
+locale l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+definition a_get_tag_name :: "(_) element_ptr \<Rightarrow> (_, tag_name) dom_prog"
+ where
+ "a_get_tag_name element_ptr = get_M element_ptr tag_name"
+
+definition a_get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ where
+ "a_get_tag_name_locs element_ptr \<equiv> {preserved (get_M element_ptr tag_name)}"
+end
+
+locale l_get_tag_name_defs =
+ fixes get_tag_name :: "(_) element_ptr \<Rightarrow> (_, tag_name) dom_prog"
+ fixes get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_get_tag_name_defs get_tag_name get_tag_name_locs +
+ l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> (_, tag_name) dom_prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes type_wf_impl: "type_wf = DocumentClass.type_wf"
+ assumes get_tag_name_impl: "get_tag_name = a_get_tag_name"
+ assumes get_tag_name_locs_impl: "get_tag_name_locs = a_get_tag_name_locs"
+begin
+lemmas get_tag_name_def = get_tag_name_impl[unfolded a_get_tag_name_def]
+lemmas get_tag_name_locs_def = get_tag_name_locs_impl[unfolded a_get_tag_name_locs_def]
+
+
+
+lemma get_tag_name_ok:
+ "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_tag_name element_ptr)"
+ apply(unfold type_wf_impl get_tag_name_impl[unfolded a_get_tag_name_def])
+ using get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok
+ by blast
+
+lemma get_tag_name_pure [simp]: "pure (get_tag_name element_ptr) h"
+ unfolding get_tag_name_impl[unfolded a_get_tag_name_def]
+ by simp
+
+lemma get_tag_name_ptr_in_heap [simp]:
+ assumes "h \<turnstile> get_tag_name element_ptr \<rightarrow>\<^sub>r children"
+ shows "element_ptr |\<in>| element_ptr_kinds h"
+ using assms
+ by(auto simp add: get_tag_name_impl[unfolded a_get_tag_name_def] get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap
+ dest: is_OK_returns_result_I)
+
+lemma get_tag_name_reads: "reads (get_tag_name_locs element_ptr) (get_tag_name element_ptr) h h'"
+ by(simp add: get_tag_name_impl[unfolded a_get_tag_name_def]
+ get_tag_name_locs_impl[unfolded a_get_tag_name_locs_def] reads_bind_pure
+ reads_insert_writes_set_right)
+end
+
+locale l_get_tag_name = l_type_wf + l_get_tag_name_defs +
+ assumes get_tag_name_reads:
+ "reads (get_tag_name_locs element_ptr) (get_tag_name element_ptr) h h'"
+ assumes get_tag_name_ok:
+ "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_tag_name element_ptr)"
+ assumes get_tag_name_ptr_in_heap:
+ "h \<turnstile> ok (get_tag_name element_ptr) \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h"
+ assumes get_tag_name_pure [simp]:
+ "pure (get_tag_name element_ptr) h"
+
+
+global_interpretation l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs defines
+ get_tag_name = l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_tag_name and
+ get_tag_name_locs = l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_tag_name_locs .
+
+interpretation
+ i_get_tag_name?: l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_tag_name get_tag_name_locs
+ apply(unfold_locales)
+ by (auto simp add: get_tag_name_def get_tag_name_locs_def)
+declare l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_tag_name_is_l_get_tag_name [instances]:
+ "l_get_tag_name type_wf get_tag_name get_tag_name_locs"
+ apply(unfold_locales)
+ using get_tag_name_reads get_tag_name_ok get_tag_name_ptr_in_heap get_tag_name_pure
+ by blast+
+
+
+paragraph \<open>set\_disconnected\_nodes\<close>
+
+locale l_set_disconnected_nodes_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_disconnected_nodes_get_tag_name:
+ "\<forall>w \<in> a_set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> a_get_tag_name_locs ptr'. r h h'))"
+ by(auto simp add: a_set_disconnected_nodes_locs_def a_get_tag_name_locs_def all_args_def)
+end
+
+locale l_set_disconnected_nodes_get_tag_name = l_set_disconnected_nodes + l_get_tag_name +
+ assumes set_disconnected_nodes_get_tag_name:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_tag_name_locs ptr'. r h h'))"
+
+interpretation
+ i_set_disconnected_nodes_get_tag_name?: l_set_disconnected_nodes_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ set_disconnected_nodes set_disconnected_nodes_locs
+ get_tag_name get_tag_name_locs
+ by unfold_locales
+declare l_set_disconnected_nodes_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_disconnected_nodes_get_tag_name_is_l_set_disconnected_nodes_get_tag_name [instances]:
+ "l_set_disconnected_nodes_get_tag_name type_wf set_disconnected_nodes set_disconnected_nodes_locs
+ get_tag_name get_tag_name_locs"
+ using set_disconnected_nodes_is_l_set_disconnected_nodes get_tag_name_is_l_get_tag_name
+ apply(simp add: l_set_disconnected_nodes_get_tag_name_def l_set_disconnected_nodes_get_tag_name_axioms_def)
+ using set_disconnected_nodes_get_tag_name
+ by fast
+
+
+paragraph \<open>set\_child\_nodes\<close>
+
+locale l_set_child_nodes_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_child_nodes_get_tag_name:
+ "\<forall>w \<in> set_child_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_tag_name_locs ptr'. r h h'))"
+ by(auto simp add: set_child_nodes_locs_def get_tag_name_locs_def all_args_def
+ intro: element_put_get_preserved[where getter=tag_name and setter=child_nodes_update])
+end
+
+locale l_set_child_nodes_get_tag_name = l_set_child_nodes + l_get_tag_name +
+ assumes set_child_nodes_get_tag_name:
+ "\<forall>w \<in> set_child_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_tag_name_locs ptr'. r h h'))"
+
+interpretation
+ i_set_child_nodes_get_tag_name?: l_set_child_nodes_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr
+ set_child_nodes set_child_nodes_locs get_tag_name get_tag_name_locs
+ by unfold_locales
+declare l_set_child_nodes_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_child_nodes_get_tag_name_is_l_set_child_nodes_get_tag_name [instances]:
+ "l_set_child_nodes_get_tag_name type_wf set_child_nodes set_child_nodes_locs get_tag_name get_tag_name_locs"
+ using set_child_nodes_is_l_set_child_nodes get_tag_name_is_l_get_tag_name
+ apply(simp add: l_set_child_nodes_get_tag_name_def l_set_child_nodes_get_tag_name_axioms_def)
+ using set_child_nodes_get_tag_name
+ by fast
+
+
+subsubsection \<open>set\_tag\_type\<close>
+
+locale l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+
+definition a_set_tag_name :: "(_) element_ptr \<Rightarrow> tag_name \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_set_tag_name ptr tag = do {
+ m \<leftarrow> get_M ptr attrs;
+ put_M ptr tag_name_update tag
+ }"
+lemmas set_tag_name_defs = a_set_tag_name_def
+
+definition a_set_tag_name_locs :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog set"
+ where
+ "a_set_tag_name_locs element_ptr \<equiv> all_args (put_M element_ptr tag_name_update)"
+end
+
+locale l_set_tag_name_defs =
+ fixes set_tag_name :: "(_) element_ptr \<Rightarrow> tag_name \<Rightarrow> (_, unit) dom_prog"
+ fixes set_tag_name_locs :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog set"
+
+locale l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_set_tag_name_defs set_tag_name set_tag_name_locs +
+ l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and set_tag_name :: "(_) element_ptr \<Rightarrow> char list \<Rightarrow> (_, unit) dom_prog"
+ and set_tag_name_locs :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog set" +
+ assumes type_wf_impl: "type_wf = DocumentClass.type_wf"
+ assumes set_tag_name_impl: "set_tag_name = a_set_tag_name"
+ assumes set_tag_name_locs_impl: "set_tag_name_locs = a_set_tag_name_locs"
+begin
+
+lemma set_tag_name_ok:
+ "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (set_tag_name element_ptr tag)"
+ apply(unfold type_wf_impl)
+ unfolding set_tag_name_impl[unfolded a_set_tag_name_def] using get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok
+ by (metis (no_types, lifting) DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ElementMonad.get_M_pure bind_is_OK_E
+ bind_is_OK_pure_I is_OK_returns_result_I)
+
+lemma set_tag_name_writes:
+ "writes (set_tag_name_locs element_ptr) (set_tag_name element_ptr tag) h h'"
+ by(auto simp add: set_tag_name_impl[unfolded a_set_tag_name_def]
+ set_tag_name_locs_impl[unfolded a_set_tag_name_locs_def] intro: writes_bind_pure)
+
+lemma set_tag_name_pointers_preserved:
+ assumes "w \<in> set_tag_name_locs element_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms(1) object_ptr_kinds_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: all_args_def set_tag_name_locs_impl[unfolded a_set_tag_name_locs_def]
+ split: if_splits)
+
+lemma set_tag_name_typess_preserved:
+ assumes "w \<in> set_tag_name_locs element_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ apply(unfold type_wf_impl)
+ using assms(1) type_wf_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: all_args_def set_tag_name_locs_impl[unfolded a_set_tag_name_locs_def]
+ split: if_splits)
+end
+
+locale l_set_tag_name = l_type_wf + l_set_tag_name_defs +
+ assumes set_tag_name_writes:
+ "writes (set_tag_name_locs element_ptr) (set_tag_name element_ptr tag) h h'"
+ assumes set_tag_name_ok:
+ "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (set_tag_name element_ptr tag)"
+ assumes set_tag_name_pointers_preserved:
+ "w \<in> set_tag_name_locs element_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> object_ptr_kinds h = object_ptr_kinds h'"
+ assumes set_tag_name_types_preserved:
+ "w \<in> set_tag_name_locs element_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+
+
+global_interpretation l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs defines
+ set_tag_name = l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_tag_name and
+ set_tag_name_locs = l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_tag_name_locs .
+interpretation
+ i_set_tag_name?: l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_tag_name set_tag_name_locs
+ apply(unfold_locales)
+ by (auto simp add: set_tag_name_def set_tag_name_locs_def)
+declare l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_tag_name_is_l_set_tag_name [instances]:
+ "l_set_tag_name type_wf set_tag_name set_tag_name_locs"
+ apply(simp add: l_set_tag_name_def)
+ using set_tag_name_ok set_tag_name_writes set_tag_name_pointers_preserved
+ set_tag_name_typess_preserved
+ by blast
+
+paragraph \<open>get\_child\_nodes\<close>
+
+locale l_set_tag_name_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_tag_name_get_child_nodes:
+ "\<forall>w \<in> set_tag_name_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+ by(auto simp add: set_tag_name_locs_impl[unfolded a_set_tag_name_locs_def]
+ get_child_nodes_locs_impl[unfolded a_get_child_nodes_locs_def] all_args_def
+ intro: element_put_get_preserved[where setter=tag_name_update and getter=child_nodes])
+end
+
+locale l_set_tag_name_get_child_nodes = l_set_tag_name + l_get_child_nodes +
+ assumes set_tag_name_get_child_nodes:
+ "\<forall>w \<in> set_tag_name_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+
+interpretation
+ i_set_tag_name_get_child_nodes?: l_set_tag_name_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ set_tag_name set_tag_name_locs known_ptr
+ get_child_nodes get_child_nodes_locs
+ by unfold_locales
+declare l_set_tag_name_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_tag_name_get_child_nodes_is_l_set_tag_name_get_child_nodes [instances]:
+ "l_set_tag_name_get_child_nodes type_wf set_tag_name set_tag_name_locs known_ptr get_child_nodes
+ get_child_nodes_locs"
+ using set_tag_name_is_l_set_tag_name get_child_nodes_is_l_get_child_nodes
+ apply(simp add: l_set_tag_name_get_child_nodes_def l_set_tag_name_get_child_nodes_axioms_def)
+ using set_tag_name_get_child_nodes
+ by fast
+
+
+paragraph \<open>get\_disconnected\_nodes\<close>
+
+locale l_set_tag_name_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_tag_name_get_disconnected_nodes:
+ "\<forall>w \<in> set_tag_name_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+ by(auto simp add: set_tag_name_locs_impl[unfolded a_set_tag_name_locs_def]
+ get_disconnected_nodes_locs_impl[unfolded a_get_disconnected_nodes_locs_def]
+ all_args_def)
+end
+
+locale l_set_tag_name_get_disconnected_nodes = l_set_tag_name + l_get_disconnected_nodes +
+ assumes set_tag_name_get_disconnected_nodes:
+ "\<forall>w \<in> set_tag_name_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+
+interpretation
+ i_set_tag_name_get_disconnected_nodes?: l_set_tag_name_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ set_tag_name set_tag_name_locs get_disconnected_nodes
+ get_disconnected_nodes_locs
+ by unfold_locales
+declare l_set_tag_name_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_tag_name_get_disconnected_nodes_is_l_set_tag_name_get_disconnected_nodes [instances]:
+ "l_set_tag_name_get_disconnected_nodes type_wf set_tag_name set_tag_name_locs get_disconnected_nodes
+ get_disconnected_nodes_locs"
+ using set_tag_name_is_l_set_tag_name get_disconnected_nodes_is_l_get_disconnected_nodes
+ apply(simp add: l_set_tag_name_get_disconnected_nodes_def
+ l_set_tag_name_get_disconnected_nodes_axioms_def)
+ using set_tag_name_get_disconnected_nodes
+ by fast
+
+
+paragraph \<open>get\_tag\_type\<close>
+
+locale l_set_tag_name_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_tag_name_get_tag_name:
+ assumes "h \<turnstile> a_set_tag_name element_ptr tag \<rightarrow>\<^sub>h h'"
+ shows "h' \<turnstile> a_get_tag_name element_ptr \<rightarrow>\<^sub>r tag"
+ using assms
+ by(auto simp add: a_get_tag_name_def a_set_tag_name_def)
+
+lemma set_tag_name_get_tag_name_different_pointers:
+ assumes "ptr \<noteq> ptr'"
+ assumes "w \<in> a_set_tag_name_locs ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ assumes "r \<in> a_get_tag_name_locs ptr'"
+ shows "r h h'"
+ using assms
+ by(auto simp add: all_args_def a_set_tag_name_locs_def a_get_tag_name_locs_def
+ split: if_splits option.splits )
+end
+
+locale l_set_tag_name_get_tag_name = l_get_tag_name + l_set_tag_name +
+ assumes set_tag_name_get_tag_name:
+ "h \<turnstile> set_tag_name element_ptr tag \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_tag_name element_ptr \<rightarrow>\<^sub>r tag"
+ assumes set_tag_name_get_tag_name_different_pointers:
+ "ptr \<noteq> ptr' \<Longrightarrow> w \<in> set_tag_name_locs ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_tag_name_locs ptr' \<Longrightarrow> r h h'"
+
+interpretation i_set_tag_name_get_tag_name?:
+ l_set_tag_name_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_tag_name
+ get_tag_name_locs set_tag_name set_tag_name_locs
+ by unfold_locales
+declare l_set_tag_name_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_tag_name_get_tag_name_is_l_set_tag_name_get_tag_name [instances]:
+ "l_set_tag_name_get_tag_name type_wf get_tag_name get_tag_name_locs
+ set_tag_name set_tag_name_locs"
+ using set_tag_name_is_l_set_tag_name get_tag_name_is_l_get_tag_name
+ apply(simp add: l_set_tag_name_get_tag_name_def
+ l_set_tag_name_get_tag_name_axioms_def)
+ using set_tag_name_get_tag_name
+ set_tag_name_get_tag_name_different_pointers
+ by fast+
+subsubsection \<open>set\_val\<close>
+
+locale l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+
+definition a_set_val :: "(_) character_data_ptr \<Rightarrow> DOMString \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_set_val ptr v = do {
+ m \<leftarrow> get_M ptr val;
+ put_M ptr val_update v
+ }"
+lemmas set_val_defs = a_set_val_def
+
+definition a_set_val_locs :: "(_) character_data_ptr \<Rightarrow> (_, unit) dom_prog set"
+ where
+ "a_set_val_locs character_data_ptr \<equiv> all_args (put_M character_data_ptr val_update)"
+end
+
+locale l_set_val_defs =
+ fixes set_val :: "(_) character_data_ptr \<Rightarrow> DOMString \<Rightarrow> (_, unit) dom_prog"
+ fixes set_val_locs :: "(_) character_data_ptr \<Rightarrow> (_, unit) dom_prog set"
+
+locale l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_set_val_defs set_val set_val_locs +
+ l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and set_val :: "(_) character_data_ptr \<Rightarrow> char list \<Rightarrow> (_, unit) dom_prog"
+ and set_val_locs :: "(_) character_data_ptr \<Rightarrow> (_, unit) dom_prog set" +
+ assumes type_wf_impl: "type_wf = DocumentClass.type_wf"
+ assumes set_val_impl: "set_val = a_set_val"
+ assumes set_val_locs_impl: "set_val_locs = a_set_val_locs"
+begin
+
+lemma set_val_ok:
+ "type_wf h \<Longrightarrow> character_data_ptr |\<in>| character_data_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (set_val character_data_ptr tag)"
+ apply(unfold type_wf_impl)
+ unfolding set_val_impl[unfolded a_set_val_def] using get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ok put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ok
+ by (metis (no_types, lifting) DocumentClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a CharacterDataMonad.get_M_pure
+ bind_is_OK_E bind_is_OK_pure_I is_OK_returns_result_I)
+
+lemma set_val_writes: "writes (set_val_locs character_data_ptr) (set_val character_data_ptr tag) h h'"
+ by(auto simp add: set_val_impl[unfolded a_set_val_def] set_val_locs_impl[unfolded a_set_val_locs_def]
+ intro: writes_bind_pure)
+
+lemma set_val_pointers_preserved:
+ assumes "w \<in> set_val_locs character_data_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms(1) object_ptr_kinds_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: all_args_def set_val_locs_impl[unfolded a_set_val_locs_def] split: if_splits)
+
+lemma set_val_typess_preserved:
+ assumes "w \<in> set_val_locs character_data_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ apply(unfold type_wf_impl)
+ using assms(1) type_wf_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: all_args_def set_val_locs_impl[unfolded a_set_val_locs_def] split: if_splits)
+end
+
+locale l_set_val = l_type_wf + l_set_val_defs +
+ assumes set_val_writes:
+ "writes (set_val_locs character_data_ptr) (set_val character_data_ptr tag) h h'"
+ assumes set_val_ok:
+ "type_wf h \<Longrightarrow> character_data_ptr |\<in>| character_data_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (set_val character_data_ptr tag)"
+ assumes set_val_pointers_preserved:
+ "w \<in> set_val_locs character_data_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> object_ptr_kinds h = object_ptr_kinds h'"
+ assumes set_val_types_preserved:
+ "w \<in> set_val_locs character_data_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+
+
+global_interpretation l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs defines
+ set_val = l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_val and
+ set_val_locs = l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_val_locs .
+interpretation
+ i_set_val?: l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_val set_val_locs
+ apply(unfold_locales)
+ by (auto simp add: set_val_def set_val_locs_def)
+declare l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_val_is_l_set_val [instances]: "l_set_val type_wf set_val set_val_locs"
+ apply(simp add: l_set_val_def)
+ using set_val_ok set_val_writes set_val_pointers_preserved set_val_typess_preserved
+ by blast
+
+paragraph \<open>get\_child\_nodes\<close>
+
+locale l_set_val_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_val_get_child_nodes:
+ "\<forall>w \<in> set_val_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+ by(auto simp add: set_val_locs_impl[unfolded a_set_val_locs_def]
+ get_child_nodes_locs_impl[unfolded a_get_child_nodes_locs_def] all_args_def)
+end
+
+locale l_set_val_get_child_nodes = l_set_val + l_get_child_nodes +
+ assumes set_val_get_child_nodes:
+ "\<forall>w \<in> set_val_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+
+interpretation
+ i_set_val_get_child_nodes?: l_set_val_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_val set_val_locs known_ptr
+ get_child_nodes get_child_nodes_locs
+ by unfold_locales
+declare l_set_val_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_val_get_child_nodes_is_l_set_val_get_child_nodes [instances]:
+ "l_set_val_get_child_nodes type_wf set_val set_val_locs known_ptr get_child_nodes get_child_nodes_locs"
+ using set_val_is_l_set_val get_child_nodes_is_l_get_child_nodes
+ apply(simp add: l_set_val_get_child_nodes_def l_set_val_get_child_nodes_axioms_def)
+ using set_val_get_child_nodes
+ by fast
+
+
+paragraph \<open>get\_disconnected\_nodes\<close>
+
+locale l_set_val_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_val_get_disconnected_nodes:
+ "\<forall>w \<in> set_val_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+ by(auto simp add: set_val_locs_impl[unfolded a_set_val_locs_def]
+ get_disconnected_nodes_locs_impl[unfolded a_get_disconnected_nodes_locs_def]
+ all_args_def)
+end
+
+locale l_set_val_get_disconnected_nodes = l_set_val + l_get_disconnected_nodes +
+ assumes set_val_get_disconnected_nodes:
+ "\<forall>w \<in> set_val_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+
+interpretation
+ i_set_val_get_disconnected_nodes?: l_set_val_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_val
+ set_val_locs get_disconnected_nodes get_disconnected_nodes_locs
+ by unfold_locales
+declare l_set_val_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_val_get_disconnected_nodes_is_l_set_val_get_disconnected_nodes [instances]:
+ "l_set_val_get_disconnected_nodes type_wf set_val set_val_locs get_disconnected_nodes
+get_disconnected_nodes_locs"
+ using set_val_is_l_set_val get_disconnected_nodes_is_l_get_disconnected_nodes
+ apply(simp add: l_set_val_get_disconnected_nodes_def l_set_val_get_disconnected_nodes_axioms_def)
+ using set_val_get_disconnected_nodes
+ by fast
+
+
+
+subsubsection \<open>get\_parent\<close>
+
+locale l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_child_nodes_defs get_child_nodes get_child_nodes_locs
+ for get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+definition a_get_parent :: "(_) node_ptr \<Rightarrow> (_, (_::linorder) object_ptr option) dom_prog"
+ where
+ "a_get_parent node_ptr = do {
+ check_in_heap (cast node_ptr);
+ parent_ptrs \<leftarrow> object_ptr_kinds_M \<bind> filter_M (\<lambda>ptr. do {
+ children \<leftarrow> get_child_nodes ptr;
+ return (node_ptr \<in> set children)
+ });
+ (if parent_ptrs = []
+ then return None
+ else return (Some (hd parent_ptrs)))
+ }"
+
+definition
+ "a_get_parent_locs \<equiv> (\<Union>ptr. get_child_nodes_locs ptr \<union> {preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr RObject.nothing)})"
+end
+
+locale l_get_parent_defs =
+ fixes get_parent :: "(_) node_ptr \<Rightarrow> (_, (_::linorder) object_ptr option) dom_prog"
+ fixes get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs +
+ l_known_ptrs known_ptr known_ptrs +
+ l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs +
+ l_get_parent_defs get_parent get_parent_locs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes (* :: "(_) object_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog" *)
+ and get_child_nodes_locs (* :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" *)
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs (* :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" *) +
+ assumes get_parent_impl: "get_parent = a_get_parent"
+ assumes get_parent_locs_impl: "get_parent_locs = a_get_parent_locs"
+begin
+lemmas get_parent_def = get_parent_impl[unfolded a_get_parent_def]
+lemmas get_parent_locs_def = get_parent_locs_impl[unfolded a_get_parent_locs_def]
+
+lemma get_parent_pure [simp]: "pure (get_parent ptr) h"
+ using get_child_nodes_pure
+ by(auto simp add: get_parent_def intro!: bind_pure_I filter_M_pure_I)
+
+lemma get_parent_ok [simp]:
+ assumes "type_wf h"
+ assumes "known_ptrs h"
+ assumes "ptr |\<in>| node_ptr_kinds h"
+ shows "h \<turnstile> ok (get_parent ptr)"
+ using assms get_child_nodes_ok get_child_nodes_pure
+ by(auto simp add: get_parent_impl[unfolded a_get_parent_def] known_ptrs_known_ptr
+ intro!: bind_is_OK_pure_I filter_M_pure_I filter_M_is_OK_I bind_pure_I)
+
+lemma get_parent_ptr_in_heap [simp]: "h \<turnstile> ok (get_parent node_ptr) \<Longrightarrow> node_ptr |\<in>| node_ptr_kinds h"
+ using get_parent_def is_OK_returns_result_I check_in_heap_ptr_in_heap
+ by (metis (no_types, lifting) bind_returns_heap_E get_parent_pure node_ptr_kinds_commutes pure_pure)
+
+lemma get_parent_parent_in_heap:
+ assumes "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent"
+ shows "parent |\<in>| object_ptr_kinds h"
+ using assms get_child_nodes_pure
+ by(auto simp add: get_parent_def elim!: bind_returns_result_E2
+ dest!: filter_M_not_more_elements[where x=parent]
+ intro!: filter_M_pure_I bind_pure_I
+ split: if_splits)
+
+lemma get_parent_child_dual:
+ assumes "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some ptr"
+ obtains children where "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children" and "child \<in> set children"
+ using assms get_child_nodes_pure
+ by(auto simp add: get_parent_def bind_pure_I
+ dest!: filter_M_holds_for_result
+ elim!: bind_returns_result_E2
+ intro!: filter_M_pure_I
+ split: if_splits)
+
+lemma get_parent_reads: "reads get_parent_locs (get_parent node_ptr) h h'"
+ using get_child_nodes_reads[unfolded reads_def]
+ by(auto simp add: get_parent_def get_parent_locs_def
+ intro!: reads_bind_pure reads_subset[OF check_in_heap_reads]
+ reads_subset[OF get_child_nodes_reads] reads_subset[OF return_reads]
+ reads_subset[OF object_ptr_kinds_M_reads] filter_M_reads filter_M_pure_I bind_pure_I)
+
+lemma get_parent_reads_pointers: "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr RObject.nothing) \<in> get_parent_locs"
+ by(auto simp add: get_parent_locs_def)
+end
+
+locale l_get_parent = l_type_wf + l_known_ptrs + l_get_parent_defs + l_get_child_nodes +
+ assumes get_parent_reads:
+ "reads get_parent_locs (get_parent node_ptr) h h'"
+ assumes get_parent_ok:
+ "type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> node_ptr |\<in>| node_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_parent node_ptr)"
+ assumes get_parent_ptr_in_heap:
+ "h \<turnstile> ok (get_parent node_ptr) \<Longrightarrow> node_ptr |\<in>| node_ptr_kinds h"
+ assumes get_parent_pure [simp]:
+ "pure (get_parent node_ptr) h"
+ assumes get_parent_parent_in_heap:
+ "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent \<Longrightarrow> parent |\<in>| object_ptr_kinds h"
+ assumes get_parent_child_dual:
+ "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some ptr \<Longrightarrow> (\<And>children. h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> child \<in> set children \<Longrightarrow> thesis) \<Longrightarrow> thesis"
+ assumes get_parent_reads_pointers:
+ "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr RObject.nothing) \<in> get_parent_locs"
+
+global_interpretation l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs defines
+ get_parent = "l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_parent get_child_nodes" and
+ get_parent_locs = "l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_parent_locs get_child_nodes_locs" .
+
+interpretation
+ i_get_parent?: l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes get_child_nodes_locs known_ptrs
+ get_parent get_parent_locs
+ using instances
+ apply(simp add: l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def)
+ apply(simp add: get_parent_def get_parent_locs_def)
+ done
+declare l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_parent_is_l_get_parent [instances]:
+ "l_get_parent type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs"
+ using instances
+ apply(auto simp add: l_get_parent_def l_get_parent_axioms_def)[1]
+ using get_parent_reads get_parent_ok get_parent_ptr_in_heap get_parent_pure
+ get_parent_parent_in_heap get_parent_child_dual
+ using get_parent_reads_pointers
+ by blast+
+
+
+paragraph \<open>set\_disconnected\_nodes\<close>
+
+locale l_set_disconnected_nodes_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes_get_child_nodes
+ set_disconnected_nodes set_disconnected_nodes_locs get_child_nodes get_child_nodes_locs
+ + l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf set_disconnected_nodes set_disconnected_nodes_locs
+ + l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf get_child_nodes get_child_nodes_locs known_ptrs get_parent get_parent_locs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma set_disconnected_nodes_get_parent [simp]:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_parent_locs. r h h'))"
+ by(auto simp add: get_parent_locs_def set_disconnected_nodes_locs_def all_args_def)
+end
+
+locale l_set_disconnected_nodes_get_parent = l_set_disconnected_nodes_defs + l_get_parent_defs +
+ assumes set_disconnected_nodes_get_parent [simp]:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_parent_locs. r h h'))"
+
+interpretation i_set_disconnected_nodes_get_parent?:
+ l_set_disconnected_nodes_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf set_disconnected_nodes
+ set_disconnected_nodes_locs get_child_nodes get_child_nodes_locs known_ptrs get_parent get_parent_locs
+ using instances
+ by (simp add: l_set_disconnected_nodes_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_set_disconnected_nodes_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_disconnected_nodes_get_parent_is_l_set_disconnected_nodes_get_parent [instances]:
+ "l_set_disconnected_nodes_get_parent set_disconnected_nodes_locs get_parent_locs"
+ by(simp add: l_set_disconnected_nodes_get_parent_def)
+
+
+
+subsubsection \<open>get\_root\_node\<close>
+
+locale l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_parent_defs get_parent get_parent_locs
+ for get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_::linorder) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+partial_function (dom_prog)
+ a_get_ancestors :: "(_::linorder) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ where
+ "a_get_ancestors ptr = do {
+ check_in_heap ptr;
+ ancestors \<leftarrow> (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some node_ptr \<Rightarrow> do {
+ parent_ptr_opt \<leftarrow> get_parent node_ptr;
+ (case parent_ptr_opt of
+ Some parent_ptr \<Rightarrow> a_get_ancestors parent_ptr
+ | None \<Rightarrow> return [])
+ }
+ | None \<Rightarrow> return []);
+ return (ptr # ancestors)
+ }"
+
+definition "a_get_ancestors_locs = get_parent_locs"
+
+definition a_get_root_node :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr) dom_prog"
+ where
+ "a_get_root_node ptr = do {
+ ancestors \<leftarrow> a_get_ancestors ptr;
+ return (last ancestors)
+ }"
+definition "a_get_root_node_locs = a_get_ancestors_locs"
+end
+
+locale l_get_ancestors_defs =
+ fixes get_ancestors :: "(_::linorder) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ fixes get_ancestors_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_root_node_defs =
+ fixes get_root_node :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr) dom_prog"
+ fixes get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_parent +
+ l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_get_ancestors_defs +
+ l_get_root_node_defs +
+ assumes get_ancestors_impl: "get_ancestors = a_get_ancestors"
+ assumes get_ancestors_locs_impl: "get_ancestors_locs = a_get_ancestors_locs"
+ assumes get_root_node_impl: "get_root_node = a_get_root_node"
+ assumes get_root_node_locs_impl: "get_root_node_locs = a_get_root_node_locs"
+begin
+lemmas get_ancestors_def = a_get_ancestors.simps[folded get_ancestors_impl]
+lemmas get_ancestors_locs_def = a_get_ancestors_locs_def[folded get_ancestors_locs_impl]
+lemmas get_root_node_def = a_get_root_node_def[folded get_root_node_impl get_ancestors_impl]
+lemmas get_root_node_locs_def = a_get_root_node_locs_def[folded get_root_node_locs_impl
+ get_ancestors_locs_impl]
+
+lemma get_ancestors_pure [simp]:
+ "pure (get_ancestors ptr) h"
+proof -
+ have "\<forall>ptr h h' x. h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r x \<longrightarrow> h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>h h' \<longrightarrow> h = h'"
+ proof (induct rule: a_get_ancestors.fixp_induct[folded get_ancestors_impl])
+ case 1
+ then show ?case
+ by(rule admissible_dom_prog)
+ next
+ case 2
+ then show ?case
+ by simp
+ next
+ case (3 f)
+ then show ?case
+ using get_parent_pure
+ apply(auto simp add: pure_returns_heap_eq pure_def
+ split: option.splits
+ elim!: bind_returns_heap_E bind_returns_result_E
+ dest!: pure_returns_heap_eq[rotated, OF check_in_heap_pure])[1]
+ apply (meson option.simps(3) returns_result_eq)
+ by (metis get_parent_pure pure_returns_heap_eq)
+ qed
+ then show ?thesis
+ by (meson pure_eq_iff)
+qed
+
+
+lemma get_root_node_pure [simp]: "pure (get_root_node ptr) h"
+ by(auto simp add: get_root_node_def bind_pure_I)
+
+
+lemma get_ancestors_ptr_in_heap:
+ assumes "h \<turnstile> ok (get_ancestors ptr)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ by(auto simp add: get_ancestors_def check_in_heap_ptr_in_heap
+ elim!: bind_is_OK_E dest: is_OK_returns_result_I)
+
+lemma get_ancestors_ptr:
+ assumes "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors"
+ shows "ptr \<in> set ancestors"
+ using assms
+ apply(simp add: get_ancestors_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits intro!: bind_pure_I)
+
+lemma get_ancestors_not_node:
+ assumes "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors"
+ assumes "\<not>is_node_ptr_kind ptr"
+ shows "ancestors = [ptr]"
+ using assms
+ apply(simp add: get_ancestors_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits)
+
+lemma get_root_node_no_parent:
+ "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r None \<Longrightarrow> h \<turnstile> get_root_node (cast node_ptr) \<rightarrow>\<^sub>r cast node_ptr"
+ apply(auto simp add: check_in_heap_def get_root_node_def get_ancestors_def
+ intro!: bind_pure_returns_result_I )[1]
+ using get_parent_ptr_in_heap by blast
+
+end
+
+locale l_get_ancestors = l_get_ancestors_defs +
+ assumes get_ancestors_pure [simp]: "pure (get_ancestors node_ptr) h"
+ assumes get_ancestors_ptr_in_heap: "h \<turnstile> ok (get_ancestors ptr) \<Longrightarrow> ptr |\<in>| object_ptr_kinds h"
+ assumes get_ancestors_ptr: "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors \<Longrightarrow> ptr \<in> set ancestors"
+
+locale l_get_root_node = l_get_root_node_defs + l_get_parent_defs +
+ assumes get_root_node_pure[simp]:
+ "pure (get_root_node ptr) h"
+ assumes get_root_node_no_parent:
+ "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r None \<Longrightarrow> h \<turnstile> get_root_node (cast node_ptr) \<rightarrow>\<^sub>r cast node_ptr"
+
+global_interpretation l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_parent get_parent_locs
+ defines get_root_node = "l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_root_node get_parent"
+ and get_root_node_locs = "l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_root_node_locs get_parent_locs"
+ and get_ancestors = "l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_ancestors get_parent"
+ and get_ancestors_locs = "l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_ancestors_locs get_parent_locs"
+ .
+declare a_get_ancestors.simps [code]
+
+interpretation
+ i_get_root_node?: l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr known_ptrs get_parent get_parent_locs
+ get_child_nodes get_child_nodes_locs get_ancestors get_ancestors_locs
+ get_root_node get_root_node_locs
+ using instances
+ apply(simp add: l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def)
+ by(simp add: get_root_node_def get_root_node_locs_def get_ancestors_def get_ancestors_locs_def)
+declare l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_ancestors_is_l_get_ancestors [instances]: "l_get_ancestors get_ancestors"
+ unfolding l_get_ancestors_def
+ using get_ancestors_pure get_ancestors_ptr get_ancestors_ptr_in_heap
+ by blast
+
+lemma get_root_node_is_l_get_root_node [instances]: "l_get_root_node get_root_node get_parent"
+ apply(simp add: l_get_root_node_def)
+ using get_root_node_no_parent
+ by fast
+
+
+paragraph \<open>set\_disconnected\_nodes\<close>
+
+locale l_set_disconnected_nodes_get_ancestors\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes_get_parent
+ set_disconnected_nodes set_disconnected_nodes_locs get_parent get_parent_locs
+ + l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_ancestors get_ancestors_locs get_root_node get_root_node_locs
+ + l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf set_disconnected_nodes set_disconnected_nodes_locs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and get_ancestors :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_ancestors_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_root_node :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma set_disconnected_nodes_get_ancestors:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_ancestors_locs. r h h'))"
+ by(auto simp add: get_parent_locs_def set_disconnected_nodes_locs_def get_ancestors_locs_def
+ all_args_def)
+end
+
+locale l_set_disconnected_nodes_get_ancestors = l_set_disconnected_nodes_defs + l_get_ancestors_defs +
+ assumes set_disconnected_nodes_get_ancestors:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_ancestors_locs. r h h'))"
+
+interpretation
+ i_set_disconnected_nodes_get_ancestors?: l_set_disconnected_nodes_get_ancestors\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr
+ set_disconnected_nodes set_disconnected_nodes_locs
+ get_child_nodes get_child_nodes_locs get_parent
+ get_parent_locs type_wf known_ptrs get_ancestors
+ get_ancestors_locs get_root_node get_root_node_locs
+ using instances
+ by (simp add: l_set_disconnected_nodes_get_ancestors\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_set_disconnected_nodes_get_ancestors\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+lemma set_disconnected_nodes_get_ancestors_is_l_set_disconnected_nodes_get_ancestors [instances]:
+ "l_set_disconnected_nodes_get_ancestors set_disconnected_nodes_locs get_ancestors_locs"
+ using instances
+ apply(simp add: l_set_disconnected_nodes_get_ancestors_def)
+ using set_disconnected_nodes_get_ancestors
+ by fast
+
+
+
+subsubsection \<open>get\_owner\_document\<close>
+
+locale l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_disconnected_nodes_defs get_disconnected_nodes get_disconnected_nodes_locs +
+ l_get_root_node_defs get_root_node get_root_node_locs
+ for get_root_node :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+
+definition a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) node_ptr \<Rightarrow> unit \<Rightarrow> (_, (_) document_ptr) dom_prog"
+ where
+ "a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr _ = do {
+ root \<leftarrow> get_root_node (cast node_ptr);
+ (case cast root of
+ Some document_ptr \<Rightarrow> return document_ptr
+ | None \<Rightarrow> do {
+ ptrs \<leftarrow> document_ptr_kinds_M;
+ candidates \<leftarrow> filter_M (\<lambda>document_ptr. do {
+ disconnected_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ return (root \<in> cast ` set disconnected_nodes)
+ }) ptrs;
+ return (hd candidates)
+ })
+ }"
+
+definition
+ a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) document_ptr \<Rightarrow> unit \<Rightarrow> (_, (_) document_ptr) dom_prog"
+ where
+ "a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr _ = do {
+ document_ptrs \<leftarrow> document_ptr_kinds_M;
+ (if document_ptr \<in> set document_ptrs then return document_ptr else error SegmentationFault)}"
+
+definition
+ a_get_owner_document_tups :: "(((_) object_ptr \<Rightarrow> bool) \<times> ((_) object_ptr \<Rightarrow> unit
+ \<Rightarrow> (_, (_) document_ptr) dom_prog)) list"
+ where
+ "a_get_owner_document_tups = [
+ (is_element_ptr, a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast),
+ (is_character_data_ptr, a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast),
+ (is_document_ptr, a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast)
+ ]"
+
+definition a_get_owner_document :: "(_) object_ptr \<Rightarrow> (_, (_) document_ptr) dom_prog"
+ where
+ "a_get_owner_document ptr = invoke a_get_owner_document_tups ptr ()"
+end
+
+locale l_get_owner_document_defs =
+ fixes get_owner_document :: "(_::linorder) object_ptr \<Rightarrow> (_, (_) document_ptr) dom_prog"
+
+locale l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_known_ptr known_ptr +
+ l_get_disconnected_nodes type_wf get_disconnected_nodes get_disconnected_nodes_locs +
+ l_get_root_node get_root_node get_root_node_locs +
+ l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_root_node get_root_node_locs get_disconnected_nodes
+ get_disconnected_nodes_locs +
+ l_get_owner_document_defs get_owner_document
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_root_node :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_owner_document :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog" +
+ assumes known_ptr_impl: "known_ptr = a_known_ptr"
+ assumes get_owner_document_impl: "get_owner_document = a_get_owner_document"
+begin
+lemmas known_ptr_def = known_ptr_impl[unfolded a_known_ptr_def]
+lemmas get_owner_document_def = a_get_owner_document_def[folded get_owner_document_impl]
+
+lemma get_owner_document_split:
+ "P (invoke (a_get_owner_document_tups @ xs) ptr ()) =
+ ((known_ptr ptr \<longrightarrow> P (get_owner_document ptr))
+ \<and> (\<not>(known_ptr ptr) \<longrightarrow> P (invoke xs ptr ())))"
+ by(auto simp add: get_owner_document_def a_get_owner_document_tups_def known_ptr_def
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs
+ NodeClass.known_ptr_defs
+ split: invoke_splits option.splits)
+
+lemma get_owner_document_split_asm:
+ "P (invoke (a_get_owner_document_tups @ xs) ptr ()) =
+ (\<not>((known_ptr ptr \<and> \<not>P (get_owner_document ptr))
+ \<or> (\<not>(known_ptr ptr) \<and> \<not>P (invoke xs ptr ()))))"
+ by(auto simp add: get_owner_document_def a_get_owner_document_tups_def known_ptr_def
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs
+ NodeClass.known_ptr_defs
+ split: invoke_splits)
+lemmas get_owner_document_splits = get_owner_document_split get_owner_document_split_asm
+
+lemma get_owner_document_pure [simp]:
+ "pure (get_owner_document ptr) h"
+proof -
+ have "\<And>node_ptr. pure (a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr ()) h"
+ by(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ intro!: bind_pure_I filter_M_pure_I
+ split: option.splits)
+ moreover have "\<And>document_ptr. pure (a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr ()) h"
+ by(auto simp add: a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def bind_pure_I)
+ ultimately show ?thesis
+ by(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ intro!: bind_pure_I
+ split: invoke_splits)
+qed
+
+lemma get_owner_document_ptr_in_heap:
+ assumes "h \<turnstile> ok (get_owner_document ptr)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ by(auto simp add: get_owner_document_def invoke_ptr_in_heap dest: is_OK_returns_heap_I)
+end
+
+locale l_get_owner_document = l_get_owner_document_defs +
+ assumes get_owner_document_ptr_in_heap:
+ "h \<turnstile> ok (get_owner_document ptr) \<Longrightarrow> ptr |\<in>| object_ptr_kinds h"
+ assumes get_owner_document_pure [simp]:
+ "pure (get_owner_document ptr) h"
+
+global_interpretation l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_root_node get_root_node_locs
+ get_disconnected_nodes get_disconnected_nodes_locs
+ defines get_owner_document_tups =
+ "l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_owner_document_tups get_root_node get_disconnected_nodes"
+ and get_owner_document =
+ "l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_owner_document get_root_node get_disconnected_nodes"
+ and get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r =
+ "l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r get_root_node get_disconnected_nodes"
+ .
+interpretation
+ i_get_owner_document?: l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_parent get_parent_locs known_ptr type_wf
+ get_disconnected_nodes get_disconnected_nodes_locs get_root_node
+ get_root_node_locs get_owner_document
+ using instances
+ apply(auto simp add: l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def)[1]
+ by(auto simp add: get_owner_document_tups_def get_owner_document_def get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)[1]
+declare l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_owner_document_is_l_get_owner_document [instances]:
+ "l_get_owner_document get_owner_document"
+ using get_owner_document_ptr_in_heap
+ by(auto simp add: l_get_owner_document_def)
+
+subsubsection \<open>remove\_child\<close>
+
+locale l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_child_nodes_defs get_child_nodes get_child_nodes_locs +
+ l_set_child_nodes_defs set_child_nodes set_child_nodes_locs +
+ l_get_parent_defs get_parent get_parent_locs +
+ l_get_owner_document_defs get_owner_document +
+ l_get_disconnected_nodes_defs get_disconnected_nodes get_disconnected_nodes_locs +
+ l_set_disconnected_nodes_defs set_disconnected_nodes set_disconnected_nodes_locs
+ for get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_owner_document :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+begin
+definition a_remove_child :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_remove_child ptr child = do {
+ children \<leftarrow> get_child_nodes ptr;
+ if child \<notin> set children then
+ error NotFoundError
+ else do {
+ owner_document \<leftarrow> get_owner_document (cast child);
+ disc_nodes \<leftarrow> get_disconnected_nodes owner_document;
+ set_disconnected_nodes owner_document (child # disc_nodes);
+ set_child_nodes ptr (remove1 child children)
+ }
+ }"
+
+definition a_remove_child_locs :: "(_) object_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+ where
+ "a_remove_child_locs ptr owner_document = set_child_nodes_locs ptr
+ \<union> set_disconnected_nodes_locs owner_document"
+
+definition a_remove :: "(_) node_ptr \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_remove node_ptr = do {
+ parent_opt \<leftarrow> get_parent node_ptr;
+ (case parent_opt of
+ Some parent \<Rightarrow> do {
+ a_remove_child parent node_ptr;
+ return ()
+ }
+ | None \<Rightarrow> return ())
+ }"
+end
+
+locale l_remove_child_defs =
+ fixes remove_child :: "(_::linorder) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> (_, unit) dom_prog"
+ fixes remove_child_locs :: "(_) object_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+
+locale l_remove_defs =
+ fixes remove :: "(_) node_ptr \<Rightarrow> (_, unit) dom_prog"
+
+locale l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_remove_child_defs +
+ l_remove_defs +
+ l_get_parent +
+ l_get_owner_document +
+ l_set_child_nodes_get_child_nodes +
+ l_set_child_nodes_get_disconnected_nodes +
+ l_set_disconnected_nodes_get_disconnected_nodes +
+ l_set_disconnected_nodes_get_child_nodes +
+ assumes remove_child_impl: "remove_child = a_remove_child"
+ assumes remove_child_locs_impl: "remove_child_locs = a_remove_child_locs"
+ assumes remove_impl: "remove = a_remove"
+begin
+lemmas remove_child_def = a_remove_child_def[folded remove_child_impl]
+lemmas remove_child_locs_def = a_remove_child_locs_def[folded remove_child_locs_impl]
+lemmas remove_def = a_remove_def[folded remove_child_impl remove_impl]
+
+lemma remove_child_ptr_in_heap:
+ assumes "h \<turnstile> ok (remove_child ptr child)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+proof -
+ obtain children where children: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using assms
+ by(auto simp add: remove_child_def)
+ moreover have "children \<noteq> []"
+ using assms calculation
+ by(auto simp add: remove_child_def elim!: bind_is_OK_E2)
+ ultimately show ?thesis
+ using assms(1) get_child_nodes_ptr_in_heap by blast
+qed
+
+
+lemma remove_child_child_in_heap:
+ assumes "h \<turnstile> remove_child ptr' child \<rightarrow>\<^sub>h h'"
+ shows "child |\<in>| node_ptr_kinds h"
+ using assms
+ apply(auto simp add: remove_child_def
+ elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ split: if_splits)[1]
+ by (meson is_OK_returns_result_I local.get_owner_document_ptr_in_heap node_ptr_kinds_commutes)
+
+
+lemma remove_child_in_disconnected_nodes:
+ (* assumes "known_ptrs h" *)
+ assumes "h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> get_owner_document (cast child) \<rightarrow>\<^sub>r owner_document"
+ assumes "h' \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes"
+ shows "child \<in> set disc_nodes"
+proof -
+ obtain prev_disc_nodes h2 children where
+ disc_nodes: "h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r prev_disc_nodes" and
+ h2: "h \<turnstile> set_disconnected_nodes owner_document (child # prev_disc_nodes) \<rightarrow>\<^sub>h h2" and
+ h': "h2 \<turnstile> set_child_nodes ptr (remove1 child children) \<rightarrow>\<^sub>h h'"
+ using assms(1)
+ apply(auto simp add: remove_child_def
+ elim!: bind_returns_heap_E
+ dest!: returns_result_eq[OF assms(2)]
+ pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_child_nodes_pure]
+ split: if_splits)[1]
+ by (metis get_disconnected_nodes_pure pure_returns_heap_eq)
+ have "h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes"
+ apply(rule reads_writes_separate_backwards[OF get_disconnected_nodes_reads
+ set_child_nodes_writes h' assms(3)])
+ by (simp add: set_child_nodes_get_disconnected_nodes)
+ then show ?thesis
+ by (metis (no_types, lifting) h2 set_disconnected_nodes_get_disconnected_nodes
+ list.set_intros(1) select_result_I2)
+qed
+
+lemma remove_child_writes [simp]:
+ "writes (remove_child_locs ptr |h \<turnstile> get_owner_document (cast child)|\<^sub>r) (remove_child ptr child) h h'"
+ apply(auto simp add: remove_child_def intro!: writes_bind_pure[OF get_child_nodes_pure]
+ writes_bind_pure[OF get_owner_document_pure]
+ writes_bind_pure[OF get_disconnected_nodes_pure])[1]
+ by(auto simp add: remove_child_locs_def set_disconnected_nodes_writes writes_union_right_I
+ set_child_nodes_writes writes_union_left_I
+ intro!: writes_bind)
+
+lemma remove_writes:
+ "writes (remove_child_locs (the |h \<turnstile> get_parent child|\<^sub>r) |h \<turnstile> get_owner_document (cast child)|\<^sub>r)
+(remove child) h h'"
+ by(auto simp add: remove_def intro!: writes_bind_pure split: option.splits)
+
+lemma remove_child_children_subset:
+ assumes "h \<turnstile> remove_child parent child \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ and "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "set children' \<subseteq> set children"
+proof -
+ obtain ptr_children owner_document h2 disc_nodes where
+ owner_document: "h \<turnstile> get_owner_document (cast child) \<rightarrow>\<^sub>r owner_document" and
+ ptr_children: "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r ptr_children" and
+ disc_nodes: "h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes" and
+ h2: "h \<turnstile> set_disconnected_nodes owner_document (child # disc_nodes) \<rightarrow>\<^sub>h h2" and
+ h': "h2 \<turnstile> set_child_nodes parent (remove1 child ptr_children) \<rightarrow>\<^sub>h h'"
+ using assms(1)
+ by(auto simp add: remove_child_def
+ elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_disconnected_nodes_pure]
+ pure_returns_heap_eq[rotated, OF get_child_nodes_pure]
+ split: if_splits)
+ have "parent |\<in>| object_ptr_kinds h"
+ using get_child_nodes_ptr_in_heap ptr_children by blast
+ have "object_ptr_kinds h = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h2])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ have "type_wf h2"
+ using type_wf writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'",
+ OF set_disconnected_nodes_writes h2]
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ have "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h2 assms(2)
+ apply(rule reads_writes_separate_forwards)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ moreover have "h2 \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r ptr_children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h2 ptr_children
+ apply(rule reads_writes_separate_forwards)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ moreover have
+ "ptr \<noteq> parent \<Longrightarrow> h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_child_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by (metis set_child_nodes_get_child_nodes_different_pointers)
+ moreover have "h' \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r remove1 child ptr_children"
+ using h' set_child_nodes_get_child_nodes known_ptrs type_wf known_ptrs_known_ptr
+ \<open>parent |\<in>| object_ptr_kinds h\<close> \<open>object_ptr_kinds h = object_ptr_kinds h2\<close> \<open>type_wf h2\<close>
+ by fast
+ moreover have "set ( remove1 child ptr_children) \<subseteq> set ptr_children"
+ by (simp add: set_remove1_subset)
+ ultimately show ?thesis
+ by (metis assms(3) order_refl returns_result_eq)
+qed
+
+
+lemma remove_child_pointers_preserved:
+ assumes "w \<in> remove_child_locs ptr owner_document"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms
+ using set_child_nodes_pointers_preserved
+ using set_disconnected_nodes_pointers_preserved
+ unfolding remove_child_locs_def
+ by auto
+
+lemma remove_child_types_preserved:
+ assumes "w \<in> remove_child_locs ptr owner_document"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ using assms
+ using set_child_nodes_types_preserved
+ using set_disconnected_nodes_types_preserved
+ unfolding remove_child_locs_def
+ by auto
+end
+
+locale l_remove_child = l_type_wf + l_known_ptrs + l_remove_child_defs + l_get_owner_document_defs
+ + l_get_child_nodes_defs + l_get_disconnected_nodes_defs +
+ assumes remove_child_writes:
+ "writes (remove_child_locs object_ptr |h \<turnstile> get_owner_document (cast child)|\<^sub>r)
+(remove_child object_ptr child) h h'"
+ assumes remove_child_pointers_preserved:
+ "w \<in> remove_child_locs ptr owner_document \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> object_ptr_kinds h = object_ptr_kinds h'"
+ assumes remove_child_types_preserved:
+ "w \<in> remove_child_locs ptr owner_document \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ assumes remove_child_in_disconnected_nodes:
+ "known_ptrs h \<Longrightarrow> h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h \<turnstile> get_owner_document (cast child) \<rightarrow>\<^sub>r owner_document
+ \<Longrightarrow> h' \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes
+ \<Longrightarrow> child \<in> set disc_nodes"
+ assumes remove_child_ptr_in_heap: "h \<turnstile> ok (remove_child ptr child) \<Longrightarrow> ptr |\<in>| object_ptr_kinds h"
+ assumes remove_child_child_in_heap: "h \<turnstile> remove_child ptr' child \<rightarrow>\<^sub>h h' \<Longrightarrow> child |\<in>| node_ptr_kinds h"
+ assumes remove_child_children_subset:
+ "known_ptrs h \<Longrightarrow> type_wf h \<Longrightarrow> h \<turnstile> remove_child parent child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'
+ \<Longrightarrow> set children' \<subseteq> set children"
+
+locale l_remove
+
+
+global_interpretation l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs set_child_nodes
+ set_child_nodes_locs get_parent get_parent_locs
+ get_owner_document get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs
+ defines remove =
+ "l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_remove get_child_nodes set_child_nodes get_parent get_owner_document
+ get_disconnected_nodes set_disconnected_nodes"
+ and remove_child =
+ "l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_remove_child get_child_nodes set_child_nodes get_owner_document
+ get_disconnected_nodes set_disconnected_nodes"
+ and remove_child_locs =
+ "l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_remove_child_locs set_child_nodes_locs set_disconnected_nodes_locs"
+ .
+interpretation
+ i_remove_child?: l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs set_child_nodes
+ set_child_nodes_locs get_parent get_parent_locs get_owner_document
+ get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs remove_child remove_child_locs remove type_wf
+ known_ptr known_ptrs
+ using instances
+ apply(simp add: l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def)
+ by(simp add: remove_child_def remove_child_locs_def remove_def)
+declare l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma remove_child_is_l_remove_child [instances]:
+ "l_remove_child type_wf known_ptr known_ptrs remove_child remove_child_locs get_owner_document
+ get_child_nodes get_disconnected_nodes"
+ using instances
+ apply(auto simp add: l_remove_child_def l_remove_child_axioms_def)[1] (*slow, ca 1min *)
+ using remove_child_pointers_preserved apply(blast)
+ using remove_child_pointers_preserved apply(blast)
+ using remove_child_types_preserved apply(blast)
+ using remove_child_types_preserved apply(blast)
+ using remove_child_in_disconnected_nodes apply(blast)
+ using remove_child_ptr_in_heap apply(blast)
+ using remove_child_child_in_heap apply(blast)
+ using remove_child_children_subset apply(blast)
+ done
+
+
+
+subsubsection \<open>adopt\_node\<close>
+
+locale l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_owner_document_defs get_owner_document +
+ l_get_parent_defs get_parent get_parent_locs +
+ l_remove_child_defs remove_child remove_child_locs +
+ l_get_disconnected_nodes_defs get_disconnected_nodes get_disconnected_nodes_locs +
+ l_set_disconnected_nodes_defs set_disconnected_nodes set_disconnected_nodes_locs
+ for get_owner_document :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and remove_child :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and remove_child_locs :: "(_) object_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+begin
+definition a_adopt_node :: "(_) document_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_adopt_node document node = do {
+ old_document \<leftarrow> get_owner_document (cast node);
+ parent_opt \<leftarrow> get_parent node;
+ (case parent_opt of
+ Some parent \<Rightarrow> do {
+ remove_child parent node
+ } | None \<Rightarrow> do {
+ return ()
+ });
+ (if document \<noteq> old_document then do {
+ old_disc_nodes \<leftarrow> get_disconnected_nodes old_document;
+ set_disconnected_nodes old_document (remove1 node old_disc_nodes);
+ disc_nodes \<leftarrow> get_disconnected_nodes document;
+ set_disconnected_nodes document (node # disc_nodes)
+ } else do {
+ return ()
+ })
+ }"
+
+definition
+ a_adopt_node_locs :: "(_) object_ptr option \<Rightarrow> (_) document_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+ where
+ "a_adopt_node_locs parent owner_document document_ptr =
+ ((if parent = None
+ then {}
+ else remove_child_locs (the parent) owner_document) \<union> set_disconnected_nodes_locs document_ptr
+ \<union> set_disconnected_nodes_locs owner_document)"
+end
+
+locale l_adopt_node_defs =
+ fixes
+ adopt_node :: "(_) document_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> (_, unit) dom_prog"
+ fixes
+ adopt_node_locs :: "(_) object_ptr option \<Rightarrow> (_) document_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+
+global_interpretation l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_owner_document get_parent get_parent_locs remove_child
+ remove_child_locs get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs
+ defines adopt_node = "l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_adopt_node get_owner_document get_parent remove_child
+ get_disconnected_nodes set_disconnected_nodes"
+ and adopt_node_locs = "l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_adopt_node_locs
+ remove_child_locs set_disconnected_nodes_locs"
+ .
+
+locale l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ get_owner_document get_parent get_parent_locs remove_child remove_child_locs get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs
+ + l_adopt_node_defs
+ adopt_node adopt_node_locs
+ + l_get_owner_document
+ get_owner_document
+ + l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf get_child_nodes get_child_nodes_locs known_ptrs get_parent get_parent_locs
+ + l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_child_nodes get_child_nodes_locs set_child_nodes set_child_nodes_locs get_parent
+ get_parent_locs get_owner_document get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs remove_child remove_child_locs remove type_wf
+ known_ptr known_ptrs
+ + l_set_disconnected_nodes_get_disconnected_nodes
+ type_wf get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs
+ for get_owner_document :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and remove_child :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and remove_child_locs :: "(_) object_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and adopt_node :: "(_) document_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and adopt_node_locs :: "(_) object_ptr option \<Rightarrow> (_) document_ptr \<Rightarrow> (_) document_ptr
+ \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and remove :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog" +
+ assumes adopt_node_impl: "adopt_node = a_adopt_node"
+ assumes adopt_node_locs_impl: "adopt_node_locs = a_adopt_node_locs"
+begin
+lemmas adopt_node_def = a_adopt_node_def[folded adopt_node_impl]
+lemmas adopt_node_locs_def = a_adopt_node_locs_def[folded adopt_node_locs_impl]
+
+lemma adopt_node_writes:
+ shows "writes (adopt_node_locs |h \<turnstile> get_parent node|\<^sub>r |h
+ \<turnstile> get_owner_document (cast node)|\<^sub>r document_ptr) (adopt_node document_ptr node) h h'"
+ apply(auto simp add: adopt_node_def adopt_node_locs_def
+ intro!: writes_bind_pure[OF get_owner_document_pure] writes_bind_pure[OF get_parent_pure]
+ writes_bind_pure[OF get_disconnected_nodes_pure]
+ split: option.splits)[1]
+ apply(auto intro!: writes_bind)[1]
+ apply (simp add: set_disconnected_nodes_writes writes_union_right_I)
+ apply (simp add: set_disconnected_nodes_writes writes_union_left_I writes_union_right_I)
+ apply(auto intro!: writes_bind)[1]
+ apply (metis (no_types, lifting) remove_child_writes select_result_I2 writes_union_left_I)
+ apply (simp add: set_disconnected_nodes_writes writes_union_right_I)
+ by(auto intro: writes_subset[OF set_disconnected_nodes_writes] writes_subset[OF remove_child_writes])
+
+lemma adopt_node_children_subset:
+ assumes "h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ and "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "set children' \<subseteq> set children"
+proof -
+ obtain old_document parent_opt h2 where
+ old_document: "h \<turnstile> get_owner_document (cast node) \<rightarrow>\<^sub>r old_document" and
+ parent_opt: "h \<turnstile> get_parent node \<rightarrow>\<^sub>r parent_opt" and
+ h2: "h \<turnstile> (case parent_opt of Some parent \<Rightarrow> do { remove_child parent node } |
+None \<Rightarrow> do { return ()}) \<rightarrow>\<^sub>h h2"
+ and
+ h': "h2 \<turnstile> (if owner_document \<noteq> old_document then do {
+ old_disc_nodes \<leftarrow> get_disconnected_nodes old_document;
+ set_disconnected_nodes old_document (remove1 node old_disc_nodes);
+ disc_nodes \<leftarrow> get_disconnected_nodes owner_document;
+ set_disconnected_nodes owner_document (node # disc_nodes)
+ } else do { return () }) \<rightarrow>\<^sub>h h'"
+ using assms(1)
+ by(auto simp add: adopt_node_def
+ elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_parent_pure])
+
+ have "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'"
+ proof (cases "owner_document \<noteq> old_document")
+ case True
+ then obtain h3 old_disc_nodes disc_nodes where
+ old_disc_nodes: "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r old_disc_nodes" and
+ h3: "h2 \<turnstile> set_disconnected_nodes old_document (remove1 node old_disc_nodes) \<rightarrow>\<^sub>h h3" and
+ old_disc_nodes: "h3 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes" and
+ h': "h3 \<turnstile> set_disconnected_nodes owner_document (node # disc_nodes) \<rightarrow>\<^sub>h h'"
+ using h'
+ by(auto elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+ have "h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'"
+ using get_child_nodes_reads set_disconnected_nodes_writes h' assms(3)
+ apply(rule reads_writes_separate_backwards)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ show ?thesis
+ using get_child_nodes_reads set_disconnected_nodes_writes h3 \<open>h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'\<close>
+ apply(rule reads_writes_separate_backwards)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ next
+ case False
+ then show ?thesis
+ using h' assms(3) by(auto)
+ qed
+
+ show ?thesis
+ proof (insert h2, induct parent_opt)
+ case None
+ then show ?case
+ using assms
+ by(auto dest!: returns_result_eq[OF \<open>h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'\<close>])
+ next
+ case (Some option)
+ then show ?case
+ using assms(2) \<open>h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'\<close> remove_child_children_subset known_ptrs
+ type_wf
+ by simp
+ qed
+qed
+
+lemma adopt_node_child_in_heap:
+ assumes "h \<turnstile> ok (adopt_node document_ptr child)"
+ shows "child |\<in>| node_ptr_kinds h"
+ using assms
+ apply(auto simp add: adopt_node_def elim!: bind_is_OK_E)[1]
+ using get_owner_document_pure get_parent_ptr_in_heap pure_returns_heap_eq
+ by fast
+
+lemma adopt_node_pointers_preserved:
+ assumes "w \<in> adopt_node_locs parent owner_document document_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms
+ using set_disconnected_nodes_pointers_preserved
+ using remove_child_pointers_preserved
+ unfolding adopt_node_locs_def
+ by (auto split: if_splits)
+
+lemma adopt_node_types_preserved:
+ assumes "w \<in> adopt_node_locs parent owner_document document_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ using assms
+ using remove_child_types_preserved
+ using set_disconnected_nodes_types_preserved
+ unfolding adopt_node_locs_def
+ by (auto split: if_splits)
+end
+
+locale l_adopt_node = l_type_wf + l_known_ptrs + l_get_parent_defs + l_adopt_node_defs +
+ l_get_child_nodes_defs + l_get_owner_document_defs +
+ assumes adopt_node_writes:
+ "writes (adopt_node_locs |h \<turnstile> get_parent node|\<^sub>r
+ |h \<turnstile> get_owner_document (cast node)|\<^sub>r document_ptr) (adopt_node document_ptr node) h h'"
+ assumes adopt_node_pointers_preserved:
+ "w \<in> adopt_node_locs parent owner_document document_ptr
+ \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> object_ptr_kinds h = object_ptr_kinds h'"
+ assumes adopt_node_types_preserved:
+ "w \<in> adopt_node_locs parent owner_document document_ptr
+ \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ assumes adopt_node_child_in_heap:
+ "h \<turnstile> ok (adopt_node document_ptr child) \<Longrightarrow> child |\<in>| node_ptr_kinds h"
+ assumes adopt_node_children_subset:
+ "h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'
+ \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h \<Longrightarrow> set children' \<subseteq> set children"
+
+interpretation
+ i_adopt_node?: l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_owner_document get_parent get_parent_locs remove_child
+ remove_child_locs get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs adopt_node adopt_node_locs
+ known_ptr type_wf get_child_nodes get_child_nodes_locs known_ptrs set_child_nodes
+ set_child_nodes_locs remove
+ apply(unfold_locales)
+ by(auto simp add: adopt_node_def adopt_node_locs_def)
+declare l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+lemma adopt_node_is_l_adopt_node [instances]:
+ "l_adopt_node type_wf known_ptr known_ptrs get_parent adopt_node adopt_node_locs get_child_nodes
+ get_owner_document"
+ using instances
+ by (simp add: l_adopt_node_axioms_def adopt_node_child_in_heap adopt_node_children_subset
+ adopt_node_pointers_preserved adopt_node_types_preserved adopt_node_writes
+ l_adopt_node_def)
+
+
+
+subsubsection \<open>insert\_before\<close>
+
+locale l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_parent_defs get_parent get_parent_locs
+ + l_get_child_nodes_defs get_child_nodes get_child_nodes_locs
+ + l_set_child_nodes_defs set_child_nodes set_child_nodes_locs
+ + l_get_ancestors_defs get_ancestors get_ancestors_locs
+ + l_adopt_node_defs adopt_node adopt_node_locs
+ + l_set_disconnected_nodes_defs set_disconnected_nodes set_disconnected_nodes_locs
+ + l_get_disconnected_nodes_defs get_disconnected_nodes get_disconnected_nodes_locs
+ + l_get_owner_document_defs get_owner_document
+ for get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_::linorder) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_ancestors :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_ancestors_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and adopt_node :: "(_) document_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and adopt_node_locs :: "(_) object_ptr option \<Rightarrow> (_) document_ptr \<Rightarrow> (_) document_ptr
+ \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_owner_document :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+begin
+
+definition a_next_sibling :: "(_) node_ptr \<Rightarrow> (_, (_) node_ptr option) dom_prog"
+ where
+ "a_next_sibling node_ptr = do {
+ parent_opt \<leftarrow> get_parent node_ptr;
+ (case parent_opt of
+ Some parent \<Rightarrow> do {
+ children \<leftarrow> get_child_nodes parent;
+ (case (dropWhile (\<lambda>ptr. ptr = node_ptr) (dropWhile (\<lambda>ptr. ptr \<noteq> node_ptr) children)) of
+ x#_ \<Rightarrow> return (Some x)
+ | [] \<Rightarrow> return None)}
+ | None \<Rightarrow> return None)
+ }"
+
+fun insert_before_list :: "'xyz \<Rightarrow> 'xyz option \<Rightarrow> 'xyz list \<Rightarrow> 'xyz list"
+ where
+ "insert_before_list v (Some reference) (x#xs) = (if reference = x
+ then v#x#xs else x # insert_before_list v (Some reference) xs)"
+ | "insert_before_list v (Some _) [] = [v]"
+ | "insert_before_list v None xs = xs @ [v]"
+
+definition a_insert_node :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> (_) node_ptr option
+ \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_insert_node ptr new_child reference_child_opt = do {
+ children \<leftarrow> get_child_nodes ptr;
+ set_child_nodes ptr (insert_before_list new_child reference_child_opt children)
+ }"
+
+definition a_ensure_pre_insertion_validity :: "(_) node_ptr \<Rightarrow> (_) object_ptr
+ \<Rightarrow> (_) node_ptr option \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_ensure_pre_insertion_validity node parent child_opt = do {
+ (if is_character_data_ptr_kind parent
+ then error HierarchyRequestError else return ());
+ ancestors \<leftarrow> get_ancestors parent;
+ (if cast node \<in> set ancestors then error HierarchyRequestError else return ());
+ (case child_opt of
+ Some child \<Rightarrow> do {
+ child_parent \<leftarrow> get_parent child;
+ (if child_parent \<noteq> Some parent then error NotFoundError else return ())}
+ | None \<Rightarrow> return ());
+ children \<leftarrow> get_child_nodes parent;
+ (if children \<noteq> [] \<and> is_document_ptr parent
+ then error HierarchyRequestError else return ());
+ (if is_character_data_ptr node \<and> is_document_ptr parent
+ then error HierarchyRequestError else return ())
+ }"
+
+definition a_insert_before :: "(_) object_ptr \<Rightarrow> (_) node_ptr
+ \<Rightarrow> (_) node_ptr option \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_insert_before ptr node child = do {
+ a_ensure_pre_insertion_validity node ptr child;
+ reference_child \<leftarrow> (if Some node = child
+ then a_next_sibling node
+ else return child);
+ owner_document \<leftarrow> get_owner_document ptr;
+ adopt_node owner_document node;
+ disc_nodes \<leftarrow> get_disconnected_nodes owner_document;
+ set_disconnected_nodes owner_document (remove1 node disc_nodes);
+ a_insert_node ptr node reference_child
+ }"
+
+definition a_insert_before_locs :: "(_) object_ptr \<Rightarrow> (_) object_ptr option \<Rightarrow> (_) document_ptr
+ \<Rightarrow> (_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+ where
+ "a_insert_before_locs ptr old_parent child_owner_document ptr_owner_document =
+ adopt_node_locs old_parent child_owner_document ptr_owner_document \<union>
+ set_child_nodes_locs ptr \<union>
+ set_disconnected_nodes_locs ptr_owner_document"
+end
+
+locale l_insert_before_defs =
+ fixes insert_before :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> (_) node_ptr option \<Rightarrow> (_, unit) dom_prog"
+ fixes insert_before_locs :: "(_) object_ptr \<Rightarrow> (_) object_ptr option \<Rightarrow> (_) document_ptr
+ \<Rightarrow> (_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+
+locale l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_insert_before_defs
+begin
+definition "a_append_child ptr child = insert_before ptr child None"
+end
+
+locale l_append_child_defs =
+ fixes append_child :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> (_, unit) dom_prog"
+
+locale l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ get_parent get_parent_locs get_child_nodes get_child_nodes_locs set_child_nodes
+ set_child_nodes_locs get_ancestors get_ancestors_locs adopt_node adopt_node_locs
+ set_disconnected_nodes set_disconnected_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_owner_document
+ + l_insert_before_defs
+ insert_before insert_before_locs
+ + l_append_child_defs
+ append_child
+ + l_set_child_nodes_get_child_nodes
+ type_wf known_ptr get_child_nodes get_child_nodes_locs set_child_nodes set_child_nodes_locs
+ + l_get_ancestors
+ get_ancestors get_ancestors_locs
+ + l_adopt_node
+ type_wf known_ptr known_ptrs get_parent get_parent_locs adopt_node adopt_node_locs
+ get_child_nodes get_child_nodes_locs get_owner_document
+ + l_set_disconnected_nodes
+ type_wf set_disconnected_nodes set_disconnected_nodes_locs
+ + l_get_disconnected_nodes
+ type_wf get_disconnected_nodes get_disconnected_nodes_locs
+ + l_get_owner_document
+ get_owner_document
+ + l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf get_child_nodes get_child_nodes_locs known_ptrs get_parent get_parent_locs
+ + l_set_disconnected_nodes_get_child_nodes
+ set_disconnected_nodes set_disconnected_nodes_locs get_child_nodes get_child_nodes_locs
+ for get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_::linorder) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_ancestors :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_ancestors_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and adopt_node :: "(_) document_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and adopt_node_locs :: "(_) object_ptr option \<Rightarrow> (_) document_ptr \<Rightarrow> (_) document_ptr
+ \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_owner_document :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and insert_before ::
+ "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> (_) node_ptr option \<Rightarrow> ((_) heap, exception, unit) prog"
+ and insert_before_locs :: "(_) object_ptr \<Rightarrow> (_) object_ptr option \<Rightarrow> (_) document_ptr
+ \<Rightarrow> (_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+ and append_child :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool" +
+ assumes insert_before_impl: "insert_before = a_insert_before"
+ assumes insert_before_locs_impl: "insert_before_locs = a_insert_before_locs"
+begin
+lemmas insert_before_def = a_insert_before_def[folded insert_before_impl]
+lemmas insert_before_locs_def = a_insert_before_locs_def[folded insert_before_locs_impl]
+
+lemma next_sibling_pure [simp]:
+ "pure (a_next_sibling new_child) h"
+ by(auto simp add: a_next_sibling_def get_parent_pure intro!: bind_pure_I split: option.splits list.splits)
+
+lemma insert_before_list_in_set: "x \<in> set (insert_before_list v ref xs) \<longleftrightarrow> x = v \<or> x \<in> set xs"
+ apply(induct v ref xs rule: insert_before_list.induct)
+ by(auto)
+
+lemma insert_before_list_distinct: "x \<notin> set xs \<Longrightarrow> distinct xs \<Longrightarrow> distinct (insert_before_list x ref xs)"
+ apply(induct x ref xs rule: insert_before_list.induct)
+ by(auto simp add: insert_before_list_in_set)
+
+lemma insert_before_list_subset: "set xs \<subseteq> set (insert_before_list x ref xs)"
+ apply(induct x ref xs rule: insert_before_list.induct)
+ by(auto)
+
+lemma insert_before_list_node_in_set: "x \<in> set (insert_before_list x ref xs)"
+ apply(induct x ref xs rule: insert_before_list.induct)
+ by(auto)
+
+lemma insert_node_writes:
+ "writes (set_child_nodes_locs ptr) (a_insert_node ptr new_child reference_child_opt) h h'"
+ by(auto simp add: a_insert_node_def set_child_nodes_writes
+ intro!: writes_bind_pure[OF get_child_nodes_pure])
+
+lemma ensure_pre_insertion_validity_pure [simp]:
+ "pure (a_ensure_pre_insertion_validity node ptr child) h"
+ by(auto simp add: a_ensure_pre_insertion_validity_def
+ intro!: bind_pure_I
+ split: option.splits)
+
+lemma insert_before_reference_child_not_in_children:
+ assumes "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some parent"
+ and "ptr \<noteq> parent"
+ and "\<not>is_character_data_ptr_kind ptr"
+ and "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors"
+ and "cast node \<notin> set ancestors"
+ shows "h \<turnstile> insert_before ptr node (Some child) \<rightarrow>\<^sub>e NotFoundError"
+proof -
+ have "h \<turnstile> a_ensure_pre_insertion_validity node ptr (Some child) \<rightarrow>\<^sub>e NotFoundError"
+ using assms unfolding insert_before_def a_ensure_pre_insertion_validity_def
+ by auto (simp | rule bind_returns_error_I2)+
+ then show ?thesis
+ unfolding insert_before_def by auto
+qed
+
+lemma insert_before_ptr_in_heap:
+ assumes "h \<turnstile> ok (insert_before ptr node reference_child)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ apply(auto simp add: insert_before_def elim!: bind_is_OK_E)[1]
+ by (metis (mono_tags, lifting) ensure_pre_insertion_validity_pure is_OK_returns_result_I
+ local.get_owner_document_ptr_in_heap next_sibling_pure pure_returns_heap_eq return_returns_heap)
+
+lemma insert_before_child_in_heap:
+ assumes "h \<turnstile> ok (insert_before ptr node reference_child)"
+ shows "node |\<in>| node_ptr_kinds h"
+ using assms
+ apply(auto simp add: insert_before_def elim!: bind_is_OK_E)[1]
+ by (metis (mono_tags, lifting) ensure_pre_insertion_validity_pure is_OK_returns_heap_I
+ l_get_owner_document.get_owner_document_pure local.adopt_node_child_in_heap
+ local.l_get_owner_document_axioms next_sibling_pure pure_returns_heap_eq return_pure)
+
+lemma insert_node_children_remain_distinct:
+ assumes insert_node: "h \<turnstile> a_insert_node ptr new_child reference_child_opt \<rightarrow>\<^sub>h h2"
+ and "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ and "new_child \<notin> set children"
+ and "\<And>ptr children. h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> distinct children"
+ and known_ptr: "known_ptr ptr"
+ and type_wf: "type_wf h"
+ shows "\<And>ptr children. h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> distinct children"
+proof -
+ fix ptr' children'
+ assume a1: "h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children'"
+ then show "distinct children'"
+ proof (cases "ptr = ptr'")
+ case True
+ have "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r (insert_before_list new_child reference_child_opt children)"
+ using assms(1) assms(2) apply(auto simp add: a_insert_node_def elim!: bind_returns_heap_E)[1]
+ using returns_result_eq set_child_nodes_get_child_nodes known_ptr type_wf
+ using pure_returns_heap_eq by fastforce
+ then show ?thesis
+ using True a1 assms(2) assms(3) assms(4) insert_before_list_distinct returns_result_eq
+ by fastforce
+ next
+ case False
+ have "h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children'"
+ using get_child_nodes_reads insert_node_writes insert_node a1
+ apply(rule reads_writes_separate_backwards)
+ by (meson False set_child_nodes_get_child_nodes_different_pointers)
+ then show ?thesis
+ using assms(4) by blast
+ qed
+qed
+
+lemma insert_before_writes:
+ "writes (insert_before_locs ptr |h \<turnstile> get_parent child|\<^sub>r
+ |h \<turnstile> get_owner_document (cast child)|\<^sub>r |h \<turnstile> get_owner_document ptr|\<^sub>r) (insert_before ptr child ref) h h'"
+ apply(auto simp add: insert_before_def insert_before_locs_def a_insert_node_def
+ intro!: writes_bind)[1]
+ apply (metis (no_types, hide_lams) ensure_pre_insertion_validity_pure local.adopt_node_writes
+ local.get_owner_document_pure next_sibling_pure pure_returns_heap_eq
+ select_result_I2 sup_commute writes_union_right_I)
+ apply (metis (no_types, hide_lams) ensure_pre_insertion_validity_pure next_sibling_pure
+ pure_returns_heap_eq select_result_I2 set_disconnected_nodes_writes
+ writes_union_right_I)
+ apply (simp add: set_child_nodes_writes writes_union_left_I writes_union_right_I)
+ apply (metis (no_types, hide_lams) adopt_node_writes ensure_pre_insertion_validity_pure
+ get_owner_document_pure pure_returns_heap_eq select_result_I2 writes_union_left_I)
+ apply (metis (no_types, hide_lams) ensure_pre_insertion_validity_pure pure_returns_heap_eq
+ select_result_I2 set_disconnected_nodes_writes writes_union_right_I)
+ by (simp add: set_child_nodes_writes writes_union_left_I writes_union_right_I)
+end
+
+
+locale l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_append_child_defs +
+ l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ assumes append_child_impl: "append_child = a_append_child"
+begin
+
+lemmas append_child_def = a_append_child_def[folded append_child_impl]
+end
+
+locale l_insert_before = l_insert_before_defs
+
+locale l_append_child = l_append_child_defs
+
+global_interpretation l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_parent get_parent_locs get_child_nodes
+ get_child_nodes_locs set_child_nodes set_child_nodes_locs get_ancestors get_ancestors_locs
+ adopt_node adopt_node_locs set_disconnected_nodes set_disconnected_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_owner_document
+ defines
+ next_sibling = "l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_next_sibling get_parent get_child_nodes" and
+ insert_node = "l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_insert_node get_child_nodes set_child_nodes" and
+ ensure_pre_insertion_validity = "l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_ensure_pre_insertion_validity
+ get_parent get_child_nodes get_ancestors" and
+ insert_before = "l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_insert_before get_parent get_child_nodes
+ set_child_nodes get_ancestors adopt_node set_disconnected_nodes
+ get_disconnected_nodes get_owner_document" and
+ insert_before_locs = "l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_insert_before_locs set_child_nodes_locs
+ adopt_node_locs set_disconnected_nodes_locs"
+ .
+
+global_interpretation l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs insert_before
+ defines append_child = "l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_append_child insert_before"
+ .
+
+interpretation
+ i_insert_before?: l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_parent get_parent_locs get_child_nodes
+ get_child_nodes_locs set_child_nodes set_child_nodes_locs get_ancestors get_ancestors_locs
+ adopt_node adopt_node_locs set_disconnected_nodes set_disconnected_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_owner_document insert_before insert_before_locs append_child
+ type_wf known_ptr known_ptrs
+ apply(simp add: l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+ by (simp add: insert_before_def insert_before_locs_def)
+declare l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+interpretation i_append_child?: l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M append_child insert_before insert_before_locs
+ apply(simp add: l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances append_child_def)
+ done
+declare l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+
+
+subsubsection \<open>create\_element\<close>
+
+locale l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_disconnected_nodes_defs get_disconnected_nodes get_disconnected_nodes_locs +
+ l_set_disconnected_nodes_defs set_disconnected_nodes set_disconnected_nodes_locs +
+ l_set_tag_name_defs set_tag_name set_tag_name_locs
+ for get_disconnected_nodes ::
+ "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs ::
+ "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes ::
+ "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs ::
+ "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_tag_name ::
+ "(_) element_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_tag_name_locs ::
+ "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+begin
+definition a_create_element :: "(_) document_ptr \<Rightarrow> tag_name \<Rightarrow> (_, (_) element_ptr) dom_prog"
+ where
+ "a_create_element document_ptr tag = do {
+ new_element_ptr \<leftarrow> new_element;
+ set_tag_name new_element_ptr tag;
+ disc_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ set_disconnected_nodes document_ptr (cast new_element_ptr # disc_nodes);
+ return new_element_ptr
+ }"
+end
+
+locale l_create_element_defs =
+ fixes create_element :: "(_) document_ptr \<Rightarrow> tag_name \<Rightarrow> (_, (_) element_ptr) dom_prog"
+
+global_interpretation l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs
+ set_tag_name set_tag_name_locs
+ defines
+ create_element = "l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_create_element get_disconnected_nodes
+ set_disconnected_nodes set_tag_name"
+ .
+
+locale l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs set_tag_name set_tag_name_locs +
+ l_get_disconnected_nodes type_wf get_disconnected_nodes get_disconnected_nodes_locs +
+ l_set_tag_name type_wf set_tag_name set_tag_name_locs +
+ l_create_element_defs create_element +
+ l_known_ptr known_ptr
+ for get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_tag_name :: "(_) element_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and create_element :: "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool" +
+ assumes known_ptr_impl: "known_ptr = a_known_ptr"
+ assumes create_element_impl: "create_element = a_create_element"
+begin
+lemmas create_element_def = a_create_element_def[folded create_element_impl]
+
+lemma create_element_document_in_heap:
+ assumes "h \<turnstile> ok (create_element document_ptr tag)"
+ shows "document_ptr |\<in>| document_ptr_kinds h"
+proof -
+ obtain h' where "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>h h'"
+ using assms(1)
+ by auto
+ then
+ obtain new_element_ptr h2 h3 disc_nodes_h3 where
+ new_element_ptr: "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr" and
+ h2: "h \<turnstile> new_element \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile> set_tag_name new_element_ptr tag \<rightarrow>\<^sub>h h3" and
+ disc_nodes_h3: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_element_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'"
+ by(auto simp add: create_element_def
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+
+ have object_ptr_kinds_eq_h: "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ using new_element_new_ptr h2 new_element_ptr by blast
+
+ moreover have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_tag_name_writes h3])
+ using set_tag_name_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ moreover have "document_ptr |\<in>| document_ptr_kinds h3"
+ by (meson disc_nodes_h3 is_OK_returns_result_I local.get_disconnected_nodes_ptr_in_heap)
+
+ ultimately show ?thesis
+ by (auto simp add: document_ptr_kinds_def)
+qed
+
+lemma create_element_known_ptr:
+ assumes "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr"
+ shows "known_ptr (cast new_element_ptr)"
+proof -
+ have "is_element_ptr new_element_ptr"
+ using assms
+ apply(auto simp add: create_element_def elim!: bind_returns_result_E)[1]
+ using new_element_is_element_ptr
+ by blast
+ then show ?thesis
+ by(auto simp add: known_ptr_impl DocumentClass.known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs)
+qed
+end
+
+locale l_create_element = l_create_element_defs
+
+interpretation
+ i_create_element?: l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs set_tag_name set_tag_name_locs type_wf
+ create_element known_ptr
+ by(auto simp add: l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def create_element_def instances)
+declare l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+subsubsection \<open>create\_character\_data\<close>
+
+locale l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_set_val_defs set_val set_val_locs +
+ l_get_disconnected_nodes_defs get_disconnected_nodes get_disconnected_nodes_locs +
+ l_set_disconnected_nodes_defs set_disconnected_nodes set_disconnected_nodes_locs
+ for set_val :: "(_) character_data_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_val_locs :: "(_) character_data_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+begin
+definition a_create_character_data :: "(_) document_ptr \<Rightarrow> string \<Rightarrow> (_, (_) character_data_ptr) dom_prog"
+ where
+ "a_create_character_data document_ptr text = do {
+ new_character_data_ptr \<leftarrow> new_character_data;
+ set_val new_character_data_ptr text;
+ disc_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ set_disconnected_nodes document_ptr (cast new_character_data_ptr # disc_nodes);
+ return new_character_data_ptr
+ }"
+end
+
+locale l_create_character_data_defs =
+ fixes create_character_data :: "(_) document_ptr \<Rightarrow> string \<Rightarrow> (_, (_) character_data_ptr) dom_prog"
+
+global_interpretation l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs set_val set_val_locs get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs
+ defines create_character_data = "l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_create_character_data
+ set_val get_disconnected_nodes set_disconnected_nodes"
+ .
+
+locale l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs set_val set_val_locs get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs +
+ l_get_disconnected_nodes type_wf get_disconnected_nodes get_disconnected_nodes_locs +
+ l_set_val type_wf set_val set_val_locs +
+ l_create_character_data_defs create_character_data +
+ l_known_ptr known_ptr
+ for get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_val :: "(_) character_data_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_val_locs :: "(_) character_data_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and create_character_data :: "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) character_data_ptr) prog"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool" +
+ assumes known_ptr_impl: "known_ptr = a_known_ptr"
+ assumes create_character_data_impl: "create_character_data = a_create_character_data"
+begin
+lemmas create_character_data_def = a_create_character_data_def[folded create_character_data_impl]
+
+lemma create_character_data_document_in_heap:
+ assumes "h \<turnstile> ok (create_character_data document_ptr text)"
+ shows "document_ptr |\<in>| document_ptr_kinds h"
+proof -
+ obtain h' where "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>h h'"
+ using assms(1)
+ by auto
+ then
+ obtain new_character_data_ptr h2 h3 disc_nodes_h3 where
+ new_character_data_ptr: "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr" and
+ h2: "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile> set_val new_character_data_ptr text \<rightarrow>\<^sub>h h3" and
+ disc_nodes_h3: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_character_data_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'"
+ by(auto simp add: create_character_data_def
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+
+ have object_ptr_kinds_eq_h: "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using new_character_data_new_ptr h2 new_character_data_ptr by blast
+
+ moreover have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_val_writes h3])
+ using set_val_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ moreover have "document_ptr |\<in>| document_ptr_kinds h3"
+ by (meson disc_nodes_h3 is_OK_returns_result_I local.get_disconnected_nodes_ptr_in_heap)
+
+ ultimately show ?thesis
+ by (auto simp add: document_ptr_kinds_def)
+qed
+
+lemma create_character_data_known_ptr:
+ assumes "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr"
+ shows "known_ptr (cast new_character_data_ptr)"
+proof -
+ have "is_character_data_ptr new_character_data_ptr"
+ using assms
+ apply(auto simp add: create_character_data_def elim!: bind_returns_result_E)[1]
+ using new_character_data_is_character_data_ptr
+ by blast
+ then show ?thesis
+ by(auto simp add: known_ptr_impl DocumentClass.known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs)
+qed
+end
+
+locale l_create_character_data = l_create_character_data_defs
+
+interpretation
+ i_create_character_data?: l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs set_val set_val_locs
+ type_wf create_character_data known_ptr
+ by(auto simp add: l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ create_character_data_def instances)
+declare l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+
+subsubsection \<open>create\_character\_data\<close>
+
+locale l_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+definition a_create_document :: "(_, (_) document_ptr) dom_prog"
+ where
+ "a_create_document = new_document"
+end
+
+locale l_create_document_defs =
+ fixes create_document :: "(_, (_) document_ptr) dom_prog"
+
+global_interpretation l_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ defines create_document = "l_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_create_document"
+ .
+
+locale l_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_create_document_defs +
+ assumes create_document_impl: "create_document = a_create_document"
+begin
+lemmas
+ create_document_def = create_document_impl[unfolded create_document_def, unfolded a_create_document_def]
+end
+
+locale l_create_document = l_create_document_defs
+
+interpretation
+ i_create_document?: l_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M create_document
+ by(simp add: l_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>tree\_order\<close>
+
+locale l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_child_nodes_defs get_child_nodes get_child_nodes_locs
+ for get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+partial_function (dom_prog) a_to_tree_order :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ where
+ "a_to_tree_order ptr = (do {
+ children \<leftarrow> get_child_nodes ptr;
+ treeorders \<leftarrow> map_M a_to_tree_order (map (cast) children);
+ return (ptr # concat treeorders)
+ })"
+end
+
+locale l_to_tree_order_defs =
+ fixes to_tree_order :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+
+global_interpretation l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs defines
+ to_tree_order = "l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_to_tree_order get_child_nodes" .
+declare a_to_tree_order.simps [code]
+
+locale l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs +
+ l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs +
+ l_to_tree_order_defs to_tree_order
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and to_tree_order :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog" +
+ assumes to_tree_order_impl: "to_tree_order = a_to_tree_order"
+begin
+lemmas to_tree_order_def = a_to_tree_order.simps[folded to_tree_order_impl]
+
+lemma to_tree_order_pure [simp]: "pure (to_tree_order ptr) h"
+proof -
+ have "\<forall>ptr h h' x. h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r x \<longrightarrow> h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>h h' \<longrightarrow> h = h'"
+ proof (induct rule: a_to_tree_order.fixp_induct[folded to_tree_order_impl])
+ case 1
+ then show ?case
+ by (rule admissible_dom_prog)
+ next
+ case 2
+ then show ?case
+ by simp
+ next
+ case (3 f)
+ then have "\<And>x h. pure (f x) h"
+ by (metis is_OK_returns_heap_E is_OK_returns_result_E pure_def)
+ then have "\<And>xs h. pure (map_M f xs) h"
+ by(rule map_M_pure_I)
+ then show ?case
+ by(auto elim!: bind_returns_heap_E2)
+ qed
+ then show ?thesis
+ unfolding pure_def
+ by (metis is_OK_returns_heap_E is_OK_returns_result_E)
+qed
+end
+
+locale l_to_tree_order =
+ fixes to_tree_order :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ assumes to_tree_order_pure [simp]: "pure (to_tree_order ptr) h"
+
+interpretation
+ i_to_tree_order?: l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes get_child_nodes_locs
+ to_tree_order
+ apply(unfold_locales)
+ by (simp add: to_tree_order_def)
+declare l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma to_tree_order_is_l_to_tree_order [instances]: "l_to_tree_order to_tree_order"
+ using to_tree_order_pure l_to_tree_order_def by blast
+
+
+
+subsubsection \<open>first\_in\_tree\_order\<close>
+
+locale l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_to_tree_order_defs to_tree_order
+ for to_tree_order :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+begin
+definition a_first_in_tree_order :: "(_) object_ptr \<Rightarrow> ((_) object_ptr
+ \<Rightarrow> (_, 'result option) dom_prog) \<Rightarrow> (_, 'result option) dom_prog"
+ where
+ "a_first_in_tree_order ptr f = (do {
+ tree_order \<leftarrow> to_tree_order ptr;
+ results \<leftarrow> map_filter_M f tree_order;
+ (case results of
+ [] \<Rightarrow> return None
+ | x#_\<Rightarrow> return (Some x))
+ })"
+end
+
+locale l_first_in_tree_order_defs =
+ fixes first_in_tree_order :: "(_) object_ptr \<Rightarrow> ((_) object_ptr \<Rightarrow> (_, 'result option) dom_prog)
+ \<Rightarrow> (_, 'result option) dom_prog"
+
+global_interpretation l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs to_tree_order defines
+ first_in_tree_order = "l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_first_in_tree_order to_tree_order" .
+
+locale l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs to_tree_order +
+ l_first_in_tree_order_defs first_in_tree_order
+ for to_tree_order :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and first_in_tree_order :: "(_) object_ptr \<Rightarrow> ((_) object_ptr \<Rightarrow> ((_) heap, exception, 'result option) prog)
+ \<Rightarrow> ((_) heap, exception, 'result option) prog" +
+assumes first_in_tree_order_impl: "first_in_tree_order = a_first_in_tree_order"
+begin
+lemmas first_in_tree_order_def = first_in_tree_order_impl[unfolded a_first_in_tree_order_def]
+end
+
+locale l_first_in_tree_order
+
+interpretation i_first_in_tree_order?:
+ l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M to_tree_order first_in_tree_order
+ by unfold_locales (simp add: first_in_tree_order_def)
+declare l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+
+subsubsection \<open>get\_element\_by\<close>
+
+locale l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_first_in_tree_order_defs first_in_tree_order +
+ l_to_tree_order_defs to_tree_order +
+ l_get_attribute_defs get_attribute get_attribute_locs
+ for to_tree_order :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and first_in_tree_order :: "(_) object_ptr \<Rightarrow> ((_) object_ptr
+ \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog)
+ \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog"
+ and get_attribute :: "(_) element_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, char list option) prog"
+ and get_attribute_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+definition a_get_element_by_id :: "(_) object_ptr \<Rightarrow> attr_value \<Rightarrow> (_, (_) element_ptr option) dom_prog"
+ where
+ "a_get_element_by_id ptr iden = first_in_tree_order ptr (\<lambda>ptr. (case cast ptr of
+ Some element_ptr \<Rightarrow> do {
+ id_opt \<leftarrow> get_attribute element_ptr ''id'';
+ (if id_opt = Some iden then return (Some element_ptr) else return None)
+ }
+ | _ \<Rightarrow> return None
+ ))"
+
+definition a_get_elements_by_class_name :: "(_) object_ptr \<Rightarrow> attr_value \<Rightarrow> (_, (_) element_ptr list) dom_prog"
+ where
+ "a_get_elements_by_class_name ptr class_name = to_tree_order ptr \<bind>
+ map_filter_M (\<lambda>ptr. (case cast ptr of
+ Some element_ptr \<Rightarrow> do {
+ class_name_opt \<leftarrow> get_attribute element_ptr ''class'';
+ (if class_name_opt = Some class_name then return (Some element_ptr) else return None)
+ }
+ | _ \<Rightarrow> return None))"
+
+definition a_get_elements_by_tag_name :: "(_) object_ptr \<Rightarrow> attr_value \<Rightarrow> (_, (_) element_ptr list) dom_prog"
+ where
+ "a_get_elements_by_tag_name ptr tag = to_tree_order ptr \<bind>
+ map_filter_M (\<lambda>ptr. (case cast ptr of
+ Some element_ptr \<Rightarrow> do {
+ this_tag_name \<leftarrow> get_M element_ptr tag_name;
+ (if this_tag_name = tag then return (Some element_ptr) else return None)
+ }
+ | _ \<Rightarrow> return None))"
+end
+
+locale l_get_element_by_defs =
+ fixes get_element_by_id :: "(_) object_ptr \<Rightarrow> attr_value \<Rightarrow> (_, (_) element_ptr option) dom_prog"
+ fixes get_elements_by_class_name :: "(_) object_ptr \<Rightarrow> attr_value \<Rightarrow> (_, (_) element_ptr list) dom_prog"
+ fixes get_elements_by_tag_name :: "(_) object_ptr \<Rightarrow> attr_value \<Rightarrow> (_, (_) element_ptr list) dom_prog"
+
+global_interpretation
+l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs to_tree_order first_in_tree_order get_attribute get_attribute_locs
+defines
+ get_element_by_id = "l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_element_by_id first_in_tree_order get_attribute"
+and
+ get_elements_by_class_name = "l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_elements_by_class_name
+to_tree_order get_attribute"
+and
+ get_elements_by_tag_name = "l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_elements_by_tag_name to_tree_order" .
+
+locale l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs to_tree_order first_in_tree_order get_attribute get_attribute_locs +
+ l_get_element_by_defs get_element_by_id get_elements_by_class_name get_elements_by_tag_name +
+ l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M to_tree_order first_in_tree_order +
+ l_to_tree_order to_tree_order +
+ l_get_attribute type_wf get_attribute get_attribute_locs
+ for to_tree_order :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and first_in_tree_order ::
+ "(_) object_ptr \<Rightarrow> ((_) object_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog)
+ \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog"
+ and get_attribute :: "(_) element_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, char list option) prog"
+ and get_attribute_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_element_by_id ::
+ "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog"
+ and get_elements_by_class_name ::
+ "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr list) prog"
+ and get_elements_by_tag_name ::
+ "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr list) prog"
+ and type_wf :: "(_) heap \<Rightarrow> bool" +
+ assumes get_element_by_id_impl: "get_element_by_id = a_get_element_by_id"
+ assumes get_elements_by_class_name_impl: "get_elements_by_class_name = a_get_elements_by_class_name"
+ assumes get_elements_by_tag_name_impl: "get_elements_by_tag_name = a_get_elements_by_tag_name"
+begin
+lemmas
+ get_element_by_id_def = get_element_by_id_impl[unfolded a_get_element_by_id_def]
+lemmas
+ get_elements_by_class_name_def = get_elements_by_class_name_impl[unfolded a_get_elements_by_class_name_def]
+lemmas
+ get_elements_by_tag_name_def = get_elements_by_tag_name_impl[unfolded a_get_elements_by_tag_name_def]
+
+lemma get_element_by_id_result_in_tree_order:
+ assumes "h \<turnstile> get_element_by_id ptr iden \<rightarrow>\<^sub>r Some element_ptr"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ shows "cast element_ptr \<in> set to"
+ using assms
+ by(auto simp add: get_element_by_id_def first_in_tree_order_def
+ elim!: map_filter_M_pure_E[where y=element_ptr] bind_returns_result_E2
+ dest!: bind_returns_result_E3[rotated, OF assms(2), rotated]
+ intro!: map_filter_M_pure map_M_pure_I bind_pure_I
+ split: option.splits list.splits if_splits)
+
+lemma get_elements_by_class_name_result_in_tree_order:
+ assumes "h \<turnstile> get_elements_by_class_name ptr name \<rightarrow>\<^sub>r results"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ assumes "element_ptr \<in> set results"
+ shows "cast element_ptr \<in> set to"
+ using assms
+ by(auto simp add: get_elements_by_class_name_def first_in_tree_order_def
+ elim!: map_filter_M_pure_E[where y=element_ptr] bind_returns_result_E2
+ dest!: bind_returns_result_E3[rotated, OF assms(2), rotated]
+ intro!: map_filter_M_pure map_M_pure_I bind_pure_I
+ split: option.splits list.splits if_splits)
+
+lemma get_elements_by_tag_name_result_in_tree_order:
+ assumes "h \<turnstile> get_elements_by_tag_name ptr name \<rightarrow>\<^sub>r results"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ assumes "element_ptr \<in> set results"
+ shows "cast element_ptr \<in> set to"
+ using assms
+ by(auto simp add: get_elements_by_tag_name_def first_in_tree_order_def
+ elim!: map_filter_M_pure_E[where y=element_ptr] bind_returns_result_E2
+ dest!: bind_returns_result_E3[rotated, OF assms(2), rotated]
+ intro!: map_filter_M_pure map_M_pure_I bind_pure_I
+ split: option.splits list.splits if_splits)
+
+lemma get_elements_by_tag_name_pure [simp]: "pure (get_elements_by_tag_name ptr tag) h"
+ by(auto simp add: get_elements_by_tag_name_def
+ intro!: bind_pure_I map_filter_M_pure
+ split: option.splits)
+end
+
+locale l_get_element_by = l_get_element_by_defs + l_to_tree_order_defs +
+ assumes get_element_by_id_result_in_tree_order:
+ "h \<turnstile> get_element_by_id ptr iden \<rightarrow>\<^sub>r Some element_ptr \<Longrightarrow> h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to
+ \<Longrightarrow> cast element_ptr \<in> set to"
+ assumes get_elements_by_tag_name_pure [simp]: "pure (get_elements_by_tag_name ptr tag) h"
+
+interpretation
+ i_get_element_by?: l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M to_tree_order first_in_tree_order get_attribute
+ get_attribute_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name type_wf
+ using instances
+ apply(simp add: l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def)
+ by(simp add: get_element_by_id_def get_elements_by_class_name_def get_elements_by_tag_name_def)
+declare l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_element_by_is_l_get_element_by [instances]:
+ "l_get_element_by get_element_by_id get_elements_by_tag_name to_tree_order"
+ apply(unfold_locales)
+ using get_element_by_id_result_in_tree_order get_elements_by_tag_name_pure
+ by fast+
+end
diff --git a/thys/Core_SC_DOM/common/Core_DOM_Tests.thy b/thys/Core_SC_DOM/common/Core_DOM_Tests.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/Core_DOM_Tests.thy
@@ -0,0 +1,40 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Core DOM Test Cases\<close>
+text\<open>This theory aggregates the individual test cases for the core DOM.\<close>
+
+theory Core_DOM_Tests
+ imports
+ "tests/Document_adoptNode"
+ "tests/Document_getElementById"
+ "tests/Node_insertBefore"
+ "tests/Node_removeChild"
+begin
+end
diff --git a/thys/Core_SC_DOM/common/classes/BaseClass.thy b/thys/Core_SC_DOM/common/classes/BaseClass.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/classes/BaseClass.thy
@@ -0,0 +1,74 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>The Class Infrastructure\<close>
+text\<open>In this theory, we introduce the basic infrastructure for our encoding
+of classes.\<close>
+theory BaseClass
+ imports
+ "HOL-Library.Finite_Map"
+ "../pointers/Ref"
+ "../Core_DOM_Basic_Datatypes"
+begin
+
+named_theorems instances
+
+consts get :: 'a
+consts put :: 'a
+consts delete :: 'a
+
+text \<open>Overall, the definition of the class types follows closely the one of the pointer
+ types. Instead of datatypes, we use records for our classes. This allows us to, first,
+ make use of record inheritance, which is, in addition to the type synonyms of
+ previous class types, the second place where the inheritance relationship of
+ our types manifest. Second, we get a convenient notation to define classes, in
+ addition to automatically generated getter and setter functions.\<close>
+
+text \<open>Along with our class types, we also develop our heap type, which is a finite
+ map at its core. It is important to note that while the map stores a mapping
+ from @{term "object_ptr"} to @{term "Object"}, we restrict the type variables
+ of the record extension slot of @{term "Object"} in such a way that allows
+ down-casting, but requires a bit of taking-apart and re-assembling of our records
+ before they are stored in the heap.\<close>
+
+text \<open>Throughout the theory files, we will use underscore case to reference pointer
+ types, and camel case for class types.\<close>
+
+text \<open>Every class type contains at least one attribute; nothing. This is used for
+ two purposes: first, the record package does not allow records without any
+ attributes. Second, we will use the getter of nothing later to check whether a
+ class of the correct type could be retrieved, for which we will be able to use
+ our infrastructure regarding the behaviour of getters across different heaps.\<close>
+
+
+locale l_type_wf = fixes type_wf :: "'heap \<Rightarrow> bool"
+
+locale l_known_ptr = fixes known_ptr :: "'ptr \<Rightarrow> bool"
+
+end
diff --git a/thys/Core_SC_DOM/common/classes/CharacterDataClass.thy b/thys/Core_SC_DOM/common/classes/CharacterDataClass.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/classes/CharacterDataClass.thy
@@ -0,0 +1,355 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>CharacterData\<close>
+text\<open>In this theory, we introduce the types for the CharacterData class.\<close>
+theory CharacterDataClass
+ imports
+ ElementClass
+begin
+
+subsubsection\<open>CharacterData\<close>
+
+text\<open>The type @{type "DOMString"} is a type synonym for @{type "string"}, defined
+ \autoref{sec:Core_DOM_Basic_Datatypes}.\<close>
+
+record RCharacterData = RNode +
+ nothing :: unit
+ val :: DOMString
+register_default_tvars "'CharacterData RCharacterData_ext"
+type_synonym 'CharacterData CharacterData = "'CharacterData option RCharacterData_scheme"
+register_default_tvars "'CharacterData CharacterData"
+type_synonym ('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Node,
+ 'Element, 'CharacterData) Node
+ = "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr,
+ 'CharacterData option RCharacterData_ext + 'Node, 'Element) Node"
+register_default_tvars "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Node,
+ 'Element, 'CharacterData) Node"
+type_synonym ('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Object, 'Node,
+ 'Element, 'CharacterData) Object
+ = "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Object,
+ 'CharacterData option RCharacterData_ext + 'Node,
+ 'Element) Object"
+register_default_tvars "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Object,
+ 'Node, 'Element, 'CharacterData) Object"
+
+type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+ 'shadow_root_ptr, 'Object, 'Node, 'Element, 'CharacterData) heap
+ = "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr, 'shadow_root_ptr,
+ 'Object, 'CharacterData option RCharacterData_ext + 'Node, 'Element) heap"
+register_default_tvars "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+ 'shadow_root_ptr, 'Object, 'Node, 'Element, 'CharacterData) heap"
+type_synonym heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l = "(unit, unit, unit, unit, unit, unit, unit, unit, unit, unit) heap"
+
+
+definition character_data_ptr_kinds :: "(_) heap \<Rightarrow> (_) character_data_ptr fset"
+ where
+ "character_data_ptr_kinds heap = the |`| (cast |`| (ffilter is_character_data_ptr_kind
+ (node_ptr_kinds heap)))"
+
+lemma character_data_ptr_kinds_simp [simp]:
+ "character_data_ptr_kinds (Heap (fmupd (cast character_data_ptr) character_data (the_heap h)))
+ = {|character_data_ptr|} |\<union>| character_data_ptr_kinds h"
+ apply(auto simp add: character_data_ptr_kinds_def)[1]
+ by force
+
+definition character_data_ptrs :: "(_) heap \<Rightarrow> _ character_data_ptr fset"
+ where
+ "character_data_ptrs heap = ffilter is_character_data_ptr (character_data_ptr_kinds heap)"
+
+abbreviation "character_data_ptr_exts heap \<equiv> character_data_ptr_kinds heap - character_data_ptrs heap"
+
+definition cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a :: "(_) Node \<Rightarrow> (_) CharacterData option"
+ where
+ "cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a node = (case RNode.more node of
+ Inr (Inl character_data) \<Rightarrow> Some (RNode.extend (RNode.truncate node) character_data)
+ | _ \<Rightarrow> None)"
+adhoc_overloading cast cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+
+abbreviation cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a :: "(_) Object \<Rightarrow> (_) CharacterData option"
+ where
+ "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a obj \<equiv> (case cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e obj of Some node \<Rightarrow> cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a node
+ | None \<Rightarrow> None)"
+adhoc_overloading cast cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+
+definition cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e :: "(_) CharacterData \<Rightarrow> (_) Node"
+ where
+ "cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e character_data = RNode.extend (RNode.truncate character_data)
+ (Inr (Inl (RNode.more character_data)))"
+adhoc_overloading cast cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+
+abbreviation cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t :: "(_) CharacterData \<Rightarrow> (_) Object"
+ where
+ "cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr \<equiv> cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr)"
+adhoc_overloading cast cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+consts is_character_data_kind :: 'a
+definition is_character_data_kind\<^sub>N\<^sub>o\<^sub>d\<^sub>e :: "(_) Node \<Rightarrow> bool"
+ where
+ "is_character_data_kind\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr \<longleftrightarrow> cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr \<noteq> None"
+
+adhoc_overloading is_character_data_kind is_character_data_kind\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+lemmas is_character_data_kind_def = is_character_data_kind\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+
+abbreviation is_character_data_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t :: "(_) Object \<Rightarrow> bool"
+ where
+ "is_character_data_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr \<equiv> cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr \<noteq> None"
+adhoc_overloading is_character_data_kind is_character_data_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+lemma character_data_ptr_kinds_commutes [simp]:
+ "cast character_data_ptr |\<in>| node_ptr_kinds h
+ \<longleftrightarrow> character_data_ptr |\<in>| character_data_ptr_kinds h"
+ apply(auto simp add: character_data_ptr_kinds_def)[1]
+ by (metis character_data_ptr_casts_commute2 comp_eq_dest_lhs ffmember_filter fimage_eqI
+ is_character_data_ptr_kind_none
+ option.distinct(1) option.sel)
+
+definition get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a :: "(_) character_data_ptr \<Rightarrow> (_) heap \<Rightarrow> (_) CharacterData option"
+ where
+ "get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h = Option.bind (get\<^sub>N\<^sub>o\<^sub>d\<^sub>e (cast character_data_ptr) h) cast"
+adhoc_overloading get get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+
+locale l_type_wf_def\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+begin
+definition a_type_wf :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_type_wf h = (ElementClass.type_wf h
+ \<and> (\<forall>character_data_ptr \<in> fset (character_data_ptr_kinds h).
+ get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h \<noteq> None))"
+end
+global_interpretation l_type_wf_def\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a defines type_wf = a_type_wf .
+lemmas type_wf_defs = a_type_wf_def
+
+locale l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a = l_type_wf type_wf for type_wf :: "((_) heap \<Rightarrow> bool)" +
+ assumes type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a: "type_wf h \<Longrightarrow> CharacterDataClass.type_wf h"
+
+sublocale l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a \<subseteq> l_type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ apply(unfold_locales)
+ using ElementClass.a_type_wf_def
+ by (meson CharacterDataClass.a_type_wf_def l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_axioms l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def)
+
+locale l_get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas = l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+begin
+sublocale l_get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas by unfold_locales
+
+lemma get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_type_wf:
+ assumes "type_wf h"
+ shows "character_data_ptr |\<in>| character_data_ptr_kinds h
+ \<longleftrightarrow> get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h \<noteq> None"
+ using l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_axioms assms
+ apply(simp add: type_wf_defs get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def)
+ by (metis assms bind.bind_lzero character_data_ptr_kinds_commutes fmember.rep_eq
+ local.get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_type_wf option.exhaust option.simps(3))
+end
+
+global_interpretation l_get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas type_wf
+ by unfold_locales
+
+definition put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a :: "(_) character_data_ptr \<Rightarrow> (_) CharacterData \<Rightarrow> (_) heap \<Rightarrow> (_) heap"
+ where
+ "put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr character_data = put\<^sub>N\<^sub>o\<^sub>d\<^sub>e (cast character_data_ptr)
+ (cast character_data)"
+adhoc_overloading put put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+
+lemma put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ptr_in_heap:
+ assumes "put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr character_data h = h'"
+ shows "character_data_ptr |\<in>| character_data_ptr_kinds h'"
+ using assms put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_ptr_in_heap
+ unfolding put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def character_data_ptr_kinds_def
+ by (metis character_data_ptr_kinds_commutes character_data_ptr_kinds_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_ptr_in_heap)
+
+lemma put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_put_ptrs:
+ assumes "put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr character_data h = h'"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast character_data_ptr|}"
+ using assms
+ by (simp add: put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_put_ptrs)
+
+
+lemma cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_inject [simp]: "cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e x = cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e y \<longleftrightarrow> x = y"
+ apply(simp add: cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def RObject.extend_def RNode.extend_def)
+ by (metis (full_types) RNode.surjective old.unit.exhaust)
+
+lemma cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_none [simp]:
+ "cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a node = None \<longleftrightarrow> \<not> (\<exists>character_data. cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e character_data = node)"
+ apply(auto simp add: cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def RObject.extend_def RNode.extend_def
+ split: sum.splits)[1]
+ by (metis (full_types) RNode.select_convs(2) RNode.surjective old.unit.exhaust)
+
+lemma cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_some [simp]:
+ "cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a node = Some character_data \<longleftrightarrow> cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e character_data = node"
+ by(auto simp add: cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def RObject.extend_def RNode.extend_def
+ split: sum.splits)
+
+lemma cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_inv [simp]:
+ "cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a (cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e character_data) = Some character_data"
+ by simp
+
+lemma cast_element_not_character_data [simp]:
+ "(cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e element \<noteq> cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e character_data)"
+ "(cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e character_data \<noteq> cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e element)"
+ by(auto simp add: cast\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def RNode.extend_def)
+
+lemma get_CharacterData_simp1 [simp]:
+ "get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr (put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr character_data h)
+ = Some character_data"
+ by(auto simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def)
+lemma get_CharacterData_simp2 [simp]:
+ "character_data_ptr \<noteq> character_data_ptr' \<Longrightarrow> get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr
+ (put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr' character_data h) = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h"
+ by(auto simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def)
+
+lemma get_CharacterData_simp3 [simp]:
+ "get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr (put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr f h) = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h"
+ by(auto simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def)
+lemma get_CharacterData_simp4 [simp]:
+ "get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a element_ptr (put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t character_data_ptr f h) = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a element_ptr h"
+ by(auto simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+
+lemma new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a [simp]:
+ assumes "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_element_ptr, h')"
+ shows "get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr h = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
+
+
+
+abbreviation "create_character_data_obj val_arg
+ \<equiv> \<lparr> RObject.nothing = (), RNode.nothing = (), RCharacterData.nothing = (), val = val_arg, \<dots> = None \<rparr>"
+
+definition new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a :: "(_) heap \<Rightarrow> ((_) character_data_ptr \<times> (_) heap)"
+ where
+ "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h =
+ (let new_character_data_ptr = character_data_ptr.Ref (Suc (fMax (character_data_ptr.the_ref
+ |`| (character_data_ptrs h)))) in
+ (new_character_data_ptr, put new_character_data_ptr (create_character_data_obj '''') h))"
+
+lemma new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ptr_in_heap:
+ assumes "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h = (new_character_data_ptr, h')"
+ shows "new_character_data_ptr |\<in>| character_data_ptr_kinds h'"
+ using assms
+ unfolding new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def
+ using put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ptr_in_heap by blast
+
+lemma new_character_data_ptr_new:
+ "character_data_ptr.Ref (Suc (fMax (finsert 0 (character_data_ptr.the_ref |`| character_data_ptrs h))))
+ |\<notin>| character_data_ptrs h"
+ by (metis Suc_n_not_le_n character_data_ptr.sel(1) fMax_ge fimage_finsert finsertI1
+ finsertI2 set_finsert)
+
+lemma new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ptr_not_in_heap:
+ assumes "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h = (new_character_data_ptr, h')"
+ shows "new_character_data_ptr |\<notin>| character_data_ptr_kinds h"
+ using assms
+ unfolding new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def
+ by (metis Pair_inject character_data_ptrs_def fMax_finsert fempty_iff ffmember_filter
+ fimage_is_fempty is_character_data_ptr_ref max_0L new_character_data_ptr_new)
+
+lemma new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_new_ptr:
+ assumes "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h = (new_character_data_ptr, h')"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using assms
+ by (metis Pair_inject new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_put_ptrs)
+
+lemma new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_is_character_data_ptr:
+ assumes "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h = (new_character_data_ptr, h')"
+ shows "is_character_data_ptr new_character_data_ptr"
+ using assms
+ by(auto simp add: new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def)
+
+lemma new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t [simp]:
+ assumes "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h = (new_character_data_ptr, h')"
+ assumes "ptr \<noteq> cast new_character_data_ptr"
+ shows "get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h = get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+
+lemma new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_get\<^sub>N\<^sub>o\<^sub>d\<^sub>e [simp]:
+ assumes "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h = (new_character_data_ptr, h')"
+ assumes "ptr \<noteq> cast new_character_data_ptr"
+ shows "get\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr h = get\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def)
+
+lemma new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t [simp]:
+ assumes "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h = (new_character_data_ptr, h')"
+ shows "get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def)
+
+lemma new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a [simp]:
+ assumes "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h = (new_character_data_ptr, h')"
+ assumes "ptr \<noteq> new_character_data_ptr"
+ shows "get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr h = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def)
+
+
+locale l_known_ptr\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+begin
+definition a_known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "a_known_ptr ptr = (known_ptr ptr \<or> is_character_data_ptr ptr)"
+
+lemma known_ptr_not_character_data_ptr:
+ "\<not>is_character_data_ptr ptr \<Longrightarrow> a_known_ptr ptr \<Longrightarrow> known_ptr ptr"
+ by(simp add: a_known_ptr_def)
+end
+global_interpretation l_known_ptr\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a defines known_ptr = a_known_ptr .
+lemmas known_ptr_defs = a_known_ptr_def
+
+
+locale l_known_ptrs\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a = l_known_ptr known_ptr for known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+begin
+definition a_known_ptrs :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_known_ptrs h = (\<forall>ptr \<in> fset (object_ptr_kinds h). known_ptr ptr)"
+
+lemma known_ptrs_known_ptr: "a_known_ptrs h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h \<Longrightarrow> known_ptr ptr"
+ apply(simp add: a_known_ptrs_def)
+ using notin_fset by fastforce
+
+lemma known_ptrs_preserved:
+ "object_ptr_kinds h = object_ptr_kinds h' \<Longrightarrow> a_known_ptrs h = a_known_ptrs h'"
+ by(auto simp add: a_known_ptrs_def)
+lemma known_ptrs_subset:
+ "object_ptr_kinds h' |\<subseteq>| object_ptr_kinds h \<Longrightarrow> a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def less_eq_fset.rep_eq subsetD)
+lemma known_ptrs_new_ptr:
+ "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|new_ptr|} \<Longrightarrow> known_ptr new_ptr \<Longrightarrow>
+a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def)
+end
+global_interpretation l_known_ptrs\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a known_ptr defines known_ptrs = a_known_ptrs .
+lemmas known_ptrs_defs = a_known_ptrs_def
+
+lemma known_ptrs_is_l_known_ptrs: "l_known_ptrs known_ptr known_ptrs"
+ using known_ptrs_known_ptr known_ptrs_preserved known_ptrs_subset known_ptrs_new_ptr l_known_ptrs_def
+ by blast
+
+end
diff --git a/thys/Core_SC_DOM/common/classes/DocumentClass.thy b/thys/Core_SC_DOM/common/classes/DocumentClass.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/classes/DocumentClass.thy
@@ -0,0 +1,345 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Document\<close>
+text\<open>In this theory, we introduce the types for the Document class.\<close>
+theory DocumentClass
+ imports
+ CharacterDataClass
+begin
+
+text\<open>The type @{type "doctype"} is a type synonym for @{type "string"}, defined
+ in \autoref{sec:Core_DOM_Basic_Datatypes}.\<close>
+
+record ('node_ptr, 'element_ptr, 'character_data_ptr) RDocument = RObject +
+ nothing :: unit
+ doctype :: doctype
+ document_element :: "(_) element_ptr option"
+ disconnected_nodes :: "('node_ptr, 'element_ptr, 'character_data_ptr) node_ptr list"
+type_synonym
+ ('node_ptr, 'element_ptr, 'character_data_ptr, 'Document) Document
+ = "('node_ptr, 'element_ptr, 'character_data_ptr, 'Document option) RDocument_scheme"
+register_default_tvars
+ "('node_ptr, 'element_ptr, 'character_data_ptr, 'Document) Document"
+type_synonym
+ ('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Object, 'Node,
+ 'Element, 'CharacterData, 'Document) Object
+ = "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr,
+ ('node_ptr, 'element_ptr, 'character_data_ptr, 'Document option)
+ RDocument_ext + 'Object, 'Node, 'Element, 'CharacterData) Object"
+register_default_tvars "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr,
+ 'Object, 'Node, 'Element, 'CharacterData, 'Document) Object"
+
+type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+ 'shadow_root_ptr, 'Object, 'Node, 'Element, 'CharacterData, 'Document) heap
+ = "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+ 'shadow_root_ptr,
+ ('node_ptr, 'element_ptr, 'character_data_ptr, 'Document option) RDocument_ext + 'Object, 'Node,
+ 'Element, 'CharacterData) heap"
+register_default_tvars
+ "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+ 'shadow_root_ptr, 'Object, 'Node, 'Element, 'CharacterData, 'Document) heap"
+type_synonym heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l = "(unit, unit, unit, unit, unit, unit, unit, unit, unit, unit, unit) heap"
+
+
+definition document_ptr_kinds :: "(_) heap \<Rightarrow> (_) document_ptr fset"
+ where
+ "document_ptr_kinds heap = the |`| (cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r |`|
+ (ffilter is_document_ptr_kind (object_ptr_kinds heap)))"
+
+definition document_ptrs :: "(_) heap \<Rightarrow> (_) document_ptr fset"
+ where
+ "document_ptrs heap = ffilter is_document_ptr (document_ptr_kinds heap)"
+
+definition cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) Object \<Rightarrow> (_) Document option"
+ where
+ "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t obj = (case RObject.more obj of
+ Inr (Inl document) \<Rightarrow> Some (RObject.extend (RObject.truncate obj) document)
+ | _ \<Rightarrow> None)"
+adhoc_overloading cast cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+definition cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t:: "(_) Document \<Rightarrow> (_) Object"
+ where
+ "cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t document = (RObject.extend (RObject.truncate document)
+ (Inr (Inl (RObject.more document))))"
+adhoc_overloading cast cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+definition is_document_kind :: "(_) Object \<Rightarrow> bool"
+ where
+ "is_document_kind ptr \<longleftrightarrow> cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr \<noteq> None"
+
+lemma document_ptr_kinds_simp [simp]:
+ "document_ptr_kinds (Heap (fmupd (cast document_ptr) document (the_heap h)))
+ = {|document_ptr|} |\<union>| document_ptr_kinds h"
+ apply(auto simp add: document_ptr_kinds_def)[1]
+ by force
+
+lemma document_ptr_kinds_commutes [simp]:
+ "cast document_ptr |\<in>| object_ptr_kinds h \<longleftrightarrow> document_ptr |\<in>| document_ptr_kinds h"
+ apply(auto simp add: object_ptr_kinds_def document_ptr_kinds_def)[1]
+ by (metis (no_types, lifting) document_ptr_casts_commute2 document_ptr_document_ptr_cast
+ ffmember_filter fimage_eqI fset.map_comp option.sel)
+
+definition get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) document_ptr \<Rightarrow> (_) heap \<Rightarrow> (_) Document option"
+ where
+ "get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h = Option.bind (get (cast document_ptr) h) cast"
+adhoc_overloading get get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+locale l_type_wf_def\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+begin
+definition a_type_wf :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_type_wf h = (CharacterDataClass.type_wf h \<and>
+ (\<forall>document_ptr \<in> fset (document_ptr_kinds h). get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h \<noteq> None))"
+end
+global_interpretation l_type_wf_def\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t defines type_wf = a_type_wf .
+lemmas type_wf_defs = a_type_wf_def
+
+locale l_type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t = l_type_wf type_wf for type_wf :: "((_) heap \<Rightarrow> bool)" +
+ assumes type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t: "type_wf h \<Longrightarrow> DocumentClass.type_wf h"
+
+sublocale l_type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t \<subseteq> l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+ apply(unfold_locales)
+ by (metis (full_types) type_wf_defs l_type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_axioms l_type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+
+locale l_get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas = l_type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+begin
+sublocale l_get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas by unfold_locales
+lemma get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_type_wf:
+ assumes "type_wf h"
+ shows "document_ptr |\<in>| document_ptr_kinds h \<longleftrightarrow> get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h \<noteq> None"
+ using l_type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_axioms assms
+ apply(simp add: type_wf_defs get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def l_type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+ by (metis document_ptr_kinds_commutes fmember.rep_eq is_none_bind is_none_simps(1)
+ is_none_simps(2) local.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf)
+end
+
+global_interpretation l_get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas type_wf by unfold_locales
+
+definition put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) document_ptr \<Rightarrow> (_) Document \<Rightarrow> (_) heap \<Rightarrow> (_) heap"
+ where
+ "put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr document = put (cast document_ptr) (cast document)"
+adhoc_overloading put put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+lemma put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap:
+ assumes "put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr document h = h'"
+ shows "document_ptr |\<in>| document_ptr_kinds h'"
+ using assms
+ unfolding put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ by (metis document_ptr_kinds_commutes put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ptr_in_heap)
+
+lemma put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_put_ptrs:
+ assumes "put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr document h = h'"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast document_ptr|}"
+ using assms
+ by (simp add: put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_put_ptrs)
+
+
+lemma cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_inject [simp]: "cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x = cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t y \<longleftrightarrow> x = y"
+ apply(simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def RObject.extend_def)
+ by (metis (full_types) RObject.surjective old.unit.exhaust)
+
+lemma cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_none [simp]:
+ "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t obj = None \<longleftrightarrow> \<not> (\<exists>document. cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t document = obj)"
+ apply(auto simp add: cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def RObject.extend_def
+ split: sum.splits)[1]
+ by (metis (full_types) RObject.select_convs(2) RObject.surjective old.unit.exhaust)
+
+lemma cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_some [simp]:
+ "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t obj = Some document \<longleftrightarrow> cast document = obj"
+ by(auto simp add: cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def RObject.extend_def
+ split: sum.splits)
+
+lemma cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_inv [simp]: "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t (cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t document) = Some document"
+ by simp
+
+lemma cast_document_not_node [simp]:
+ "cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t document \<noteq> cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t node"
+ "cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t node \<noteq> cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t document"
+ by(auto simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def RObject.extend_def)
+
+lemma get_document_ptr_simp1 [simp]:
+ "get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr (put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr document h) = Some document"
+ by(auto simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+lemma get_document_ptr_simp2 [simp]:
+ "document_ptr \<noteq> document_ptr'
+ \<Longrightarrow> get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr (put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr' document h) = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h"
+ by(auto simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+
+
+lemma get_document_ptr_simp3 [simp]:
+ "get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr (put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr f h) = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h"
+ by(auto simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+lemma get_document_ptr_simp4 [simp]:
+ "get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr (put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr f h) = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h"
+ by(auto simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+lemma get_document_ptr_simp5 [simp]:
+ "get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr (put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr f h) = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h"
+ by(auto simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+lemma get_document_ptr_simp6 [simp]:
+ "get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr (put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr f h) = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h"
+ by(auto simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+
+lemma new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t [simp]:
+ assumes "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_element_ptr, h')"
+ shows "get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
+
+lemma new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t [simp]:
+ assumes "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h = (new_character_data_ptr, h')"
+ shows "get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def)
+
+
+
+abbreviation
+ create_document_obj :: "char list \<Rightarrow> (_) element_ptr option \<Rightarrow> (_) node_ptr list \<Rightarrow> (_) Document"
+ where
+ "create_document_obj doctype_arg document_element_arg disconnected_nodes_arg
+ \<equiv> \<lparr> RObject.nothing = (), RDocument.nothing = (), doctype = doctype_arg,
+ document_element = document_element_arg,
+ disconnected_nodes = disconnected_nodes_arg, \<dots> = None \<rparr>"
+
+definition new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_)heap \<Rightarrow> ((_) document_ptr \<times> (_) heap)"
+ where
+ "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h =
+ (let new_document_ptr = document_ptr.Ref (Suc (fMax (finsert 0 (document_ptr.the_ref |`| (document_ptrs h)))))
+ in
+ (new_document_ptr, put new_document_ptr (create_document_obj '''' None []) h))"
+
+lemma new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap:
+ assumes "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_document_ptr, h')"
+ shows "new_document_ptr |\<in>| document_ptr_kinds h'"
+ using assms
+ unfolding new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def
+ using put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap by blast
+
+lemma new_document_ptr_new:
+ "document_ptr.Ref (Suc (fMax (finsert 0 (document_ptr.the_ref |`| document_ptrs h))))
+ |\<notin>| document_ptrs h"
+ by (metis Suc_n_not_le_n document_ptr.sel(1) fMax_ge fimage_finsert finsertI1 finsertI2 set_finsert)
+
+lemma new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_not_in_heap:
+ assumes "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_document_ptr, h')"
+ shows "new_document_ptr |\<notin>| document_ptr_kinds h"
+ using assms
+ unfolding new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ by (metis Pair_inject document_ptrs_def fMax_finsert fempty_iff ffmember_filter
+ fimage_is_fempty is_document_ptr_ref max_0L new_document_ptr_new)
+
+lemma new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_new_ptr:
+ assumes "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_document_ptr, h')"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_document_ptr|}"
+ using assms
+ by (metis Pair_inject new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_put_ptrs)
+
+lemma new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_is_document_ptr:
+ assumes "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_document_ptr, h')"
+ shows "is_document_ptr new_document_ptr"
+ using assms
+ by(auto simp add: new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
+
+lemma new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t [simp]:
+ assumes "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_document_ptr, h')"
+ assumes "ptr \<noteq> cast new_document_ptr"
+ shows "get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h = get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+
+lemma new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>N\<^sub>o\<^sub>d\<^sub>e [simp]:
+ assumes "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_document_ptr, h')"
+ shows "get\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr h = get\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr h'"
+ using assms
+ apply(simp add: new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+ by(auto simp add: get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+
+lemma new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t [simp]:
+ assumes "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_document_ptr, h')"
+ shows "get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
+
+lemma new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a [simp]:
+ assumes "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_document_ptr, h')"
+ shows "get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr h = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
+
+lemma new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t [simp]:
+ assumes "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_document_ptr, h')"
+ assumes "ptr \<noteq> new_document_ptr"
+ shows "get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
+
+
+locale l_known_ptr\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+begin
+definition a_known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "a_known_ptr ptr = (known_ptr ptr \<or> is_document_ptr ptr)"
+
+lemma known_ptr_not_document_ptr: "\<not>is_document_ptr ptr \<Longrightarrow> a_known_ptr ptr \<Longrightarrow> known_ptr ptr"
+ by(simp add: a_known_ptr_def)
+end
+global_interpretation l_known_ptr\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t defines known_ptr = a_known_ptr .
+lemmas known_ptr_defs = a_known_ptr_def
+
+
+locale l_known_ptrs\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t = l_known_ptr known_ptr for known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+begin
+definition a_known_ptrs :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_known_ptrs h = (\<forall>ptr \<in> fset (object_ptr_kinds h). known_ptr ptr)"
+
+lemma known_ptrs_known_ptr: "a_known_ptrs h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h \<Longrightarrow> known_ptr ptr"
+ apply(simp add: a_known_ptrs_def)
+ using notin_fset by fastforce
+
+lemma known_ptrs_preserved:
+ "object_ptr_kinds h = object_ptr_kinds h' \<Longrightarrow> a_known_ptrs h = a_known_ptrs h'"
+ by(auto simp add: a_known_ptrs_def)
+lemma known_ptrs_subset:
+ "object_ptr_kinds h' |\<subseteq>| object_ptr_kinds h \<Longrightarrow> a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def less_eq_fset.rep_eq subsetD)
+lemma known_ptrs_new_ptr:
+ "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|new_ptr|} \<Longrightarrow> known_ptr new_ptr \<Longrightarrow>
+a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def)
+end
+global_interpretation l_known_ptrs\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t known_ptr defines known_ptrs = a_known_ptrs .
+lemmas known_ptrs_defs = a_known_ptrs_def
+
+lemma known_ptrs_is_l_known_ptrs [instances]: "l_known_ptrs known_ptr known_ptrs"
+ using known_ptrs_known_ptr known_ptrs_preserved l_known_ptrs_def known_ptrs_subset known_ptrs_new_ptr
+ by blast
+
+end
diff --git a/thys/Core_SC_DOM/common/classes/NodeClass.thy b/thys/Core_SC_DOM/common/classes/NodeClass.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/classes/NodeClass.thy
@@ -0,0 +1,209 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+
+section\<open>Node\<close>
+text\<open>In this theory, we introduce the types for the Node class.\<close>
+
+theory NodeClass
+ imports
+ ObjectClass
+ "../pointers/NodePointer"
+begin
+
+subsubsection\<open>Node\<close>
+
+record RNode = RObject
+ + nothing :: unit
+register_default_tvars "'Node RNode_ext"
+type_synonym 'Node Node = "'Node RNode_scheme"
+register_default_tvars "'Node Node"
+type_synonym ('Object, 'Node) Object = "('Node RNode_ext + 'Object) Object"
+register_default_tvars "('Object, 'Node) Object"
+
+type_synonym ('object_ptr, 'node_ptr, 'Object, 'Node) heap
+ = "('node_ptr node_ptr + 'object_ptr, 'Node RNode_ext + 'Object) heap"
+register_default_tvars
+ "('object_ptr, 'node_ptr, 'Object, 'Node) heap"
+type_synonym heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l = "(unit, unit, unit, unit) heap"
+
+
+definition node_ptr_kinds :: "(_) heap \<Rightarrow> (_) node_ptr fset"
+ where
+ "node_ptr_kinds heap =
+ (the |`| (cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r |`| (ffilter is_node_ptr_kind (object_ptr_kinds heap))))"
+
+lemma node_ptr_kinds_simp [simp]:
+ "node_ptr_kinds (Heap (fmupd (cast node_ptr) node (the_heap h)))
+ = {|node_ptr|} |\<union>| node_ptr_kinds h"
+ apply(auto simp add: node_ptr_kinds_def)[1]
+ by force
+
+definition cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e :: "(_) Object \<Rightarrow> (_) Node option"
+ where
+ "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e obj = (case RObject.more obj of Inl node
+ \<Rightarrow> Some (RObject.extend (RObject.truncate obj) node) | _ \<Rightarrow> None)"
+adhoc_overloading cast cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+
+definition cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t:: "(_) Node \<Rightarrow> (_) Object"
+ where
+ "cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t node = (RObject.extend (RObject.truncate node) (Inl (RObject.more node)))"
+adhoc_overloading cast cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+definition is_node_kind :: "(_) Object \<Rightarrow> bool"
+ where
+ "is_node_kind ptr \<longleftrightarrow> cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr \<noteq> None"
+
+definition get\<^sub>N\<^sub>o\<^sub>d\<^sub>e :: "(_) node_ptr \<Rightarrow> (_) heap \<Rightarrow> (_) Node option"
+ where
+ "get\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr h = Option.bind (get (cast node_ptr) h) cast"
+adhoc_overloading get get\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+
+locale l_type_wf_def\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+begin
+definition a_type_wf :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_type_wf h = (ObjectClass.type_wf h
+ \<and> (\<forall>node_ptr \<in> fset( node_ptr_kinds h). get\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr h \<noteq> None))"
+end
+global_interpretation l_type_wf_def\<^sub>N\<^sub>o\<^sub>d\<^sub>e defines type_wf = a_type_wf .
+lemmas type_wf_defs = a_type_wf_def
+
+locale l_type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e = l_type_wf type_wf for type_wf :: "((_) heap \<Rightarrow> bool)" +
+ assumes type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e: "type_wf h \<Longrightarrow> NodeClass.type_wf h"
+
+sublocale l_type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e \<subseteq> l_type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ apply(unfold_locales)
+ using ObjectClass.a_type_wf_def by auto
+
+locale l_get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_lemmas = l_type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+begin
+sublocale l_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas by unfold_locales
+lemma get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_type_wf:
+ assumes "type_wf h"
+ shows "node_ptr |\<in>| node_ptr_kinds h \<longleftrightarrow> get\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr h \<noteq> None"
+ using l_type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e_axioms assms
+ apply(simp add: type_wf_defs get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def l_type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+ by (metis bind_eq_None_conv ffmember_filter fimage_eqI fmember.rep_eq is_node_ptr_kind_cast
+ get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf node_ptr_casts_commute2 node_ptr_kinds_def option.sel option.simps(3))
+end
+
+global_interpretation l_get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_lemmas type_wf
+ by unfold_locales
+
+definition put\<^sub>N\<^sub>o\<^sub>d\<^sub>e :: "(_) node_ptr \<Rightarrow> (_) Node \<Rightarrow> (_) heap \<Rightarrow> (_) heap"
+ where
+ "put\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr node = put (cast node_ptr) (cast node)"
+adhoc_overloading put put\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+
+lemma put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_ptr_in_heap:
+ assumes "put\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr node h = h'"
+ shows "node_ptr |\<in>| node_ptr_kinds h'"
+ using assms
+ unfolding put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def node_ptr_kinds_def
+ by (metis ffmember_filter fimage_eqI is_node_ptr_kind_cast node_ptr_casts_commute2
+ option.sel put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ptr_in_heap)
+
+lemma put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_put_ptrs:
+ assumes "put\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr node h = h'"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast node_ptr|}"
+ using assms
+ by (simp add: put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_put_ptrs)
+
+lemma node_ptr_kinds_commutes [simp]:
+ "cast node_ptr |\<in>| object_ptr_kinds h \<longleftrightarrow> node_ptr |\<in>| node_ptr_kinds h"
+ apply(auto simp add: node_ptr_kinds_def split: option.splits)[1]
+ by (metis (no_types, lifting) ffmember_filter fimage_eqI fset.map_comp
+ is_node_ptr_kind_none node_ptr_casts_commute2
+ option.distinct(1) option.sel)
+
+lemma node_empty [simp]:
+ "\<lparr>RObject.nothing = (), RNode.nothing = (), \<dots> = RNode.more node\<rparr> = node"
+ by simp
+
+lemma cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_inject [simp]: "cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t x = cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t y \<longleftrightarrow> x = y"
+ apply(simp add: cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def RObject.extend_def)
+ by (metis (full_types) RObject.surjective old.unit.exhaust)
+
+lemma cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_none [simp]:
+ "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e obj = None \<longleftrightarrow> \<not> (\<exists>node. cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t node = obj)"
+ apply(auto simp add: cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def RObject.extend_def split: sum.splits)[1]
+ by (metis (full_types) RObject.select_convs(2) RObject.surjective old.unit.exhaust)
+
+lemma cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_some [simp]: "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e obj = Some node \<longleftrightarrow> cast node = obj"
+ by(auto simp add: cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def RObject.extend_def split: sum.splits)
+
+lemma cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_inv [simp]: "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e (cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t node) = Some node"
+ by simp
+
+locale l_known_ptr\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+begin
+definition a_known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "a_known_ptr ptr = False"
+end
+global_interpretation l_known_ptr\<^sub>N\<^sub>o\<^sub>d\<^sub>e defines known_ptr = a_known_ptr .
+lemmas known_ptr_defs = a_known_ptr_def
+
+
+locale l_known_ptrs\<^sub>N\<^sub>o\<^sub>d\<^sub>e = l_known_ptr known_ptr for known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+begin
+definition a_known_ptrs :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_known_ptrs h = (\<forall>ptr \<in> fset (object_ptr_kinds h). known_ptr ptr)"
+
+lemma known_ptrs_known_ptr: "a_known_ptrs h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h \<Longrightarrow> known_ptr ptr"
+ apply(simp add: a_known_ptrs_def)
+ using notin_fset by fastforce
+lemma known_ptrs_preserved:
+ "object_ptr_kinds h = object_ptr_kinds h' \<Longrightarrow> a_known_ptrs h = a_known_ptrs h'"
+ by(auto simp add: a_known_ptrs_def)
+lemma known_ptrs_subset:
+ "object_ptr_kinds h' |\<subseteq>| object_ptr_kinds h \<Longrightarrow> a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def less_eq_fset.rep_eq subsetD)
+lemma known_ptrs_new_ptr:
+ "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|new_ptr|} \<Longrightarrow> known_ptr new_ptr \<Longrightarrow>
+a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def)
+end
+global_interpretation l_known_ptrs\<^sub>N\<^sub>o\<^sub>d\<^sub>e known_ptr defines known_ptrs = a_known_ptrs .
+lemmas known_ptrs_defs = a_known_ptrs_def
+
+lemma known_ptrs_is_l_known_ptrs: "l_known_ptrs known_ptr known_ptrs"
+ using known_ptrs_known_ptr known_ptrs_preserved l_known_ptrs_def known_ptrs_subset
+ known_ptrs_new_ptr
+ by blast
+
+lemma get_node_ptr_simp1 [simp]: "get\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr (put\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr node h) = Some node"
+ by(auto simp add: get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+lemma get_node_ptr_simp2 [simp]:
+ "node_ptr \<noteq> node_ptr' \<Longrightarrow> get\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr (put\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr' node h) = get\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr h"
+ by(auto simp add: get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+
+end
diff --git a/thys/Core_SC_DOM/common/classes/ObjectClass.thy b/thys/Core_SC_DOM/common/classes/ObjectClass.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/classes/ObjectClass.thy
@@ -0,0 +1,225 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Object\<close>
+text\<open>In this theory, we introduce the definition of the class Object. This class is the
+common superclass of our class model.\<close>
+
+theory ObjectClass
+ imports
+ BaseClass
+ "../pointers/ObjectPointer"
+begin
+
+record RObject =
+ nothing :: unit
+register_default_tvars "'Object RObject_ext"
+type_synonym 'Object Object = "'Object RObject_scheme"
+register_default_tvars "'Object Object"
+
+datatype ('object_ptr, 'Object) heap = Heap (the_heap: "((_) object_ptr, (_) Object) fmap")
+register_default_tvars "('object_ptr, 'Object) heap"
+type_synonym heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l = "(unit, unit) heap"
+
+definition object_ptr_kinds :: "(_) heap \<Rightarrow> (_) object_ptr fset"
+ where
+ "object_ptr_kinds = fmdom \<circ> the_heap"
+
+lemma object_ptr_kinds_simp [simp]:
+ "object_ptr_kinds (Heap (fmupd object_ptr object (the_heap h)))
+ = {|object_ptr|} |\<union>| object_ptr_kinds h"
+ by(auto simp add: object_ptr_kinds_def)
+
+definition get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t :: "(_) object_ptr \<Rightarrow> (_) heap \<Rightarrow> (_) Object option"
+ where
+ "get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h = fmlookup (the_heap h) ptr"
+adhoc_overloading get get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+locale l_type_wf_def\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+begin
+definition a_type_wf :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_type_wf h = True"
+end
+global_interpretation l_type_wf_def\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t defines type_wf = a_type_wf .
+lemmas type_wf_defs = a_type_wf_def
+
+locale l_type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t = l_type_wf type_wf for type_wf :: "((_) heap \<Rightarrow> bool)" +
+ assumes type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t: "type_wf h \<Longrightarrow> ObjectClass.type_wf h"
+
+locale l_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas = l_type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+begin
+lemma get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf:
+ assumes "type_wf h"
+ shows "object_ptr |\<in>| object_ptr_kinds h \<longleftrightarrow> get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr h \<noteq> None"
+ using l_type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_axioms assms
+ apply(simp add: type_wf_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def)
+ by (simp add: fmlookup_dom_iff object_ptr_kinds_def)
+end
+
+global_interpretation l_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas type_wf
+ by (simp add: l_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas.intro l_type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t.intro)
+
+definition put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t :: "(_) object_ptr \<Rightarrow> (_) Object \<Rightarrow> (_) heap \<Rightarrow> (_) heap"
+ where
+ "put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h = Heap (fmupd ptr obj (the_heap h))"
+adhoc_overloading put put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+lemma put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ptr_in_heap:
+ assumes "put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr object h = h'"
+ shows "object_ptr |\<in>| object_ptr_kinds h'"
+ using assms
+ unfolding put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ by auto
+
+lemma put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_put_ptrs:
+ assumes "put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr object h = h'"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|object_ptr|}"
+ using assms
+ by (metis comp_apply fmdom_fmupd funion_finsert_right heap.sel object_ptr_kinds_def
+ sup_bot.right_neutral put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def)
+
+lemma object_more_extend_id [simp]: "more (extend x y) = y"
+ by(simp add: extend_def)
+
+lemma object_empty [simp]: "\<lparr>nothing = (), \<dots> = more x\<rparr> = x"
+ by simp
+
+locale l_known_ptr\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+begin
+definition a_known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "a_known_ptr ptr = False"
+
+lemma known_ptr_not_object_ptr:
+ "a_known_ptr ptr \<Longrightarrow> \<not>is_object_ptr ptr \<Longrightarrow> known_ptr ptr"
+ by(simp add: a_known_ptr_def)
+end
+global_interpretation l_known_ptr\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t defines known_ptr = a_known_ptr .
+lemmas known_ptr_defs = a_known_ptr_def
+
+locale l_known_ptrs = l_known_ptr known_ptr for known_ptr :: "(_) object_ptr \<Rightarrow> bool" +
+ fixes known_ptrs :: "(_) heap \<Rightarrow> bool"
+ assumes known_ptrs_known_ptr: "known_ptrs h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h \<Longrightarrow> known_ptr ptr"
+ assumes known_ptrs_preserved:
+ "object_ptr_kinds h = object_ptr_kinds h' \<Longrightarrow> known_ptrs h = known_ptrs h'"
+ assumes known_ptrs_subset:
+ "object_ptr_kinds h' |\<subseteq>| object_ptr_kinds h \<Longrightarrow> known_ptrs h \<Longrightarrow> known_ptrs h'"
+ assumes known_ptrs_new_ptr:
+ "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|new_ptr|} \<Longrightarrow> known_ptr new_ptr \<Longrightarrow>
+known_ptrs h \<Longrightarrow> known_ptrs h'"
+
+locale l_known_ptrs\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t = l_known_ptr known_ptr for known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+begin
+definition a_known_ptrs :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_known_ptrs h = (\<forall>ptr \<in> fset (object_ptr_kinds h). known_ptr ptr)"
+
+lemma known_ptrs_known_ptr:
+ "a_known_ptrs h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h \<Longrightarrow> known_ptr ptr"
+ apply(simp add: a_known_ptrs_def)
+ using notin_fset by fastforce
+
+lemma known_ptrs_preserved:
+ "object_ptr_kinds h = object_ptr_kinds h' \<Longrightarrow> a_known_ptrs h = a_known_ptrs h'"
+ by(auto simp add: a_known_ptrs_def)
+lemma known_ptrs_subset:
+ "object_ptr_kinds h' |\<subseteq>| object_ptr_kinds h \<Longrightarrow> a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def less_eq_fset.rep_eq subsetD)
+lemma known_ptrs_new_ptr:
+ "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|new_ptr|} \<Longrightarrow> known_ptr new_ptr \<Longrightarrow>
+a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def)
+end
+global_interpretation l_known_ptrs\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t known_ptr defines known_ptrs = a_known_ptrs .
+lemmas known_ptrs_defs = a_known_ptrs_def
+
+lemma known_ptrs_is_l_known_ptrs: "l_known_ptrs known_ptr known_ptrs"
+ using known_ptrs_known_ptr known_ptrs_preserved l_known_ptrs_def known_ptrs_subset known_ptrs_new_ptr
+ by blast
+
+
+lemma get_object_ptr_simp1 [simp]: "get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr object h) = Some object"
+ by(simp add: get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def)
+lemma get_object_ptr_simp2 [simp]:
+ "object_ptr \<noteq> object_ptr'
+ \<Longrightarrow> get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr' object h) = get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr h"
+ by(simp add: get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def)
+
+
+subsection\<open>Limited Heap Modifications\<close>
+
+definition heap_unchanged_except :: "(_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ where
+ "heap_unchanged_except S h h' = (\<forall>ptr \<in> (fset (object_ptr_kinds h)
+ \<union> (fset (object_ptr_kinds h'))) - S. get ptr h = get ptr h')"
+
+definition delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t :: "(_) object_ptr \<Rightarrow> (_) heap \<Rightarrow> (_) heap option" where
+ "delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h = (if ptr |\<in>| object_ptr_kinds h then Some (Heap (fmdrop ptr (the_heap h)))
+ else None)"
+
+lemma delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_pointer_removed:
+ assumes "delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h = Some h'"
+ shows "ptr |\<notin>| object_ptr_kinds h'"
+ using assms
+ by(auto simp add: delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def object_ptr_kinds_def split: if_splits)
+
+lemma delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_pointer_ptr_in_heap:
+ assumes "delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h = Some h'"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ by(auto simp add: delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def object_ptr_kinds_def split: if_splits)
+
+lemma delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ok:
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ shows "delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h \<noteq> None"
+ using assms
+ by(auto simp add: delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def object_ptr_kinds_def split: if_splits)
+
+
+subsection \<open>Code Generator Setup\<close>
+
+definition "create_heap xs = Heap (fmap_of_list xs)"
+
+code_datatype ObjectClass.heap.Heap create_heap
+
+lemma object_ptr_kinds_code3 [code]:
+ "fmlookup (the_heap (create_heap xs)) x = map_of xs x"
+ by(auto simp add: create_heap_def fmlookup_of_list)
+
+lemma object_ptr_kinds_code4 [code]:
+ "the_heap (create_heap xs) = fmap_of_list xs"
+ by(simp add: create_heap_def)
+
+lemma object_ptr_kinds_code5 [code]:
+ "the_heap (Heap x) = x"
+ by simp
+
+
+end
diff --git a/thys/Core_SC_DOM/common/monads/BaseMonad.thy b/thys/Core_SC_DOM/common/monads/BaseMonad.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/monads/BaseMonad.thy
@@ -0,0 +1,384 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>The Monad Infrastructure\<close>
+text\<open>In this theory, we introduce the basic infrastructure for our monadic class encoding.\<close>
+theory BaseMonad
+ imports
+ "../classes/BaseClass"
+ "../preliminaries/Heap_Error_Monad"
+begin
+subsection\<open>Datatypes\<close>
+
+datatype exception = NotFoundError | HierarchyRequestError | NotSupportedError | SegmentationFault
+ | AssertException | NonTerminationException | InvokeError | TypeError
+
+lemma finite_set_in [simp]: "x \<in> fset FS \<longleftrightarrow> x |\<in>| FS"
+ by (meson notin_fset)
+
+consts put_M :: 'a
+consts get_M :: 'a
+consts delete_M :: 'a
+
+lemma sorted_list_of_set_eq [dest]:
+ "sorted_list_of_set (fset x) = sorted_list_of_set (fset y) \<Longrightarrow> x = y"
+ by (metis finite_fset fset_inject sorted_list_of_set(1))
+
+
+locale l_ptr_kinds_M =
+ fixes ptr_kinds :: "'heap \<Rightarrow> 'ptr::linorder fset"
+begin
+definition a_ptr_kinds_M :: "('heap, exception, 'ptr list) prog"
+ where
+ "a_ptr_kinds_M = do {
+ h \<leftarrow> get_heap;
+ return (sorted_list_of_set (fset (ptr_kinds h)))
+ }"
+
+lemma ptr_kinds_M_ok [simp]: "h \<turnstile> ok a_ptr_kinds_M"
+ by(simp add: a_ptr_kinds_M_def)
+
+lemma ptr_kinds_M_pure [simp]: "pure a_ptr_kinds_M h"
+ by (auto simp add: a_ptr_kinds_M_def intro: bind_pure_I)
+
+lemma ptr_kinds_ptr_kinds_M [simp]: "ptr \<in> set |h \<turnstile> a_ptr_kinds_M|\<^sub>r \<longleftrightarrow> ptr |\<in>| ptr_kinds h"
+ by(simp add: a_ptr_kinds_M_def)
+
+lemma ptr_kinds_M_ptr_kinds [simp]:
+ "h \<turnstile> a_ptr_kinds_M \<rightarrow>\<^sub>r xa \<longleftrightarrow> xa = sorted_list_of_set (fset (ptr_kinds h))"
+ by(auto simp add: a_ptr_kinds_M_def)
+lemma ptr_kinds_M_ptr_kinds_returns_result [simp]:
+ "h \<turnstile> a_ptr_kinds_M \<bind> f \<rightarrow>\<^sub>r x \<longleftrightarrow> h \<turnstile> f (sorted_list_of_set (fset (ptr_kinds h))) \<rightarrow>\<^sub>r x"
+ by(auto simp add: a_ptr_kinds_M_def)
+lemma ptr_kinds_M_ptr_kinds_returns_heap [simp]:
+ "h \<turnstile> a_ptr_kinds_M \<bind> f \<rightarrow>\<^sub>h h' \<longleftrightarrow> h \<turnstile> f (sorted_list_of_set (fset (ptr_kinds h))) \<rightarrow>\<^sub>h h'"
+ by(auto simp add: a_ptr_kinds_M_def)
+end
+
+locale l_get_M =
+ fixes get :: "'ptr \<Rightarrow> 'heap \<Rightarrow> 'obj option"
+ fixes type_wf :: "'heap \<Rightarrow> bool"
+ fixes ptr_kinds :: "'heap \<Rightarrow> 'ptr fset"
+ assumes "type_wf h \<Longrightarrow> ptr |\<in>| ptr_kinds h \<Longrightarrow> get ptr h \<noteq> None"
+ assumes "get ptr h \<noteq> None \<Longrightarrow> ptr |\<in>| ptr_kinds h"
+begin
+
+definition a_get_M :: "'ptr \<Rightarrow> ('obj \<Rightarrow> 'result) \<Rightarrow> ('heap, exception, 'result) prog"
+ where
+ "a_get_M ptr getter = (do {
+ h \<leftarrow> get_heap;
+ (case get ptr h of
+ Some res \<Rightarrow> return (getter res)
+ | None \<Rightarrow> error SegmentationFault)
+ })"
+
+lemma get_M_pure [simp]: "pure (a_get_M ptr getter) h"
+ by(auto simp add: a_get_M_def bind_pure_I split: option.splits)
+
+lemma get_M_ok:
+ "type_wf h \<Longrightarrow> ptr |\<in>| ptr_kinds h \<Longrightarrow> h \<turnstile> ok (a_get_M ptr getter)"
+ apply(simp add: a_get_M_def)
+ by (metis l_get_M_axioms l_get_M_def option.case_eq_if return_ok)
+lemma get_M_ptr_in_heap:
+ "h \<turnstile> ok (a_get_M ptr getter) \<Longrightarrow> ptr |\<in>| ptr_kinds h"
+ apply(simp add: a_get_M_def)
+ by (metis error_returns_result is_OK_returns_result_E l_get_M_axioms l_get_M_def option.simps(4))
+
+end
+
+locale l_put_M = l_get_M get for get :: "'ptr \<Rightarrow> 'heap \<Rightarrow> 'obj option" +
+ fixes put :: "'ptr \<Rightarrow> 'obj \<Rightarrow> 'heap \<Rightarrow> 'heap"
+begin
+definition a_put_M :: "'ptr \<Rightarrow> (('v \<Rightarrow> 'v) \<Rightarrow> 'obj \<Rightarrow> 'obj) \<Rightarrow> 'v \<Rightarrow> ('heap, exception, unit) prog"
+ where
+ "a_put_M ptr setter v = (do {
+ obj \<leftarrow> a_get_M ptr id;
+ h \<leftarrow> get_heap;
+ return_heap (put ptr (setter (\<lambda>_. v) obj) h)
+ })"
+
+lemma put_M_ok:
+ "type_wf h \<Longrightarrow> ptr |\<in>| ptr_kinds h \<Longrightarrow> h \<turnstile> ok (a_put_M ptr setter v)"
+ by(auto simp add: a_put_M_def intro!: bind_is_OK_I2 dest: get_M_ok elim!: bind_is_OK_E)
+
+lemma put_M_ptr_in_heap:
+ "h \<turnstile> ok (a_put_M ptr setter v) \<Longrightarrow> ptr |\<in>| ptr_kinds h"
+ by(auto simp add: a_put_M_def intro!: bind_is_OK_I2 elim: get_M_ptr_in_heap
+ dest: is_OK_returns_result_I elim!: bind_is_OK_E)
+
+end
+
+subsection \<open>Setup for Defining Partial Functions\<close>
+
+lemma execute_admissible:
+ "ccpo.admissible (fun_lub (flat_lub (Inl (e::'e)))) (fun_ord (flat_ord (Inl e)))
+ ((\<lambda>a. \<forall>(h::'heap) h2 (r::'result). h \<turnstile> a = Inr (r, h2) \<longrightarrow> P h h2 r) \<circ> Prog)"
+proof (unfold comp_def, rule ccpo.admissibleI, clarify)
+ fix A :: "('heap \<Rightarrow> 'e + 'result \<times> 'heap) set"
+ let ?lub = "Prog (fun_lub (flat_lub (Inl e)) A)"
+ fix h h2 r
+ assume 1: "Complete_Partial_Order.chain (fun_ord (flat_ord (Inl e))) A"
+ and 2: "\<forall>xa\<in>A. \<forall>h h2 r. h \<turnstile> Prog xa = Inr (r, h2) \<longrightarrow> P h h2 r"
+ and 4: "h \<turnstile> Prog (fun_lub (flat_lub (Inl e)) A) = Inr (r, h2)"
+ have h1:"\<And>a. Complete_Partial_Order.chain (flat_ord (Inl e)) {y. \<exists>f\<in>A. y = f a}"
+ by (rule chain_fun[OF 1])
+ show "P h h2 r"
+ using CollectD Inl_Inr_False prog.sel chain_fun[OF 1] flat_lub_in_chain[OF chain_fun[OF 1]] 2 4
+ unfolding execute_def fun_lub_def
+ proof -
+ assume a1: "the_prog (Prog (\<lambda>x. flat_lub (Inl e) {y. \<exists>f\<in>A. y = f x})) h = Inr (r, h2)"
+ assume a2: "\<forall>xa\<in>A. \<forall>h h2 r. the_prog (Prog xa) h = Inr (r, h2) \<longrightarrow> P h h2 r"
+ have "Inr (r, h2) \<in> {s. \<exists>f. f \<in> A \<and> s = f h} \<or> Inr (r, h2) = Inl e"
+ using a1 by (metis (lifting) \<open>\<And>aa a. flat_lub (Inl e) {y. \<exists>f\<in>A. y = f aa} = a \<Longrightarrow> a = Inl e \<or> a \<in> {y. \<exists>f\<in>A. y = f aa}\<close> prog.sel)
+ then show ?thesis
+ using a2 by fastforce
+ qed
+qed
+
+lemma execute_admissible2:
+ "ccpo.admissible (fun_lub (flat_lub (Inl (e::'e)))) (fun_ord (flat_ord (Inl e)))
+ ((\<lambda>a. \<forall>(h::'heap) h' h2 h2' (r::'result) r'.
+ h \<turnstile> a = Inr (r, h2) \<longrightarrow> h' \<turnstile> a = Inr (r', h2') \<longrightarrow> P h h' h2 h2' r r') \<circ> Prog)"
+proof (unfold comp_def, rule ccpo.admissibleI, clarify)
+ fix A :: "('heap \<Rightarrow> 'e + 'result \<times> 'heap) set"
+ let ?lub = "Prog (fun_lub (flat_lub (Inl e)) A)"
+ fix h h' h2 h2' r r'
+ assume 1: "Complete_Partial_Order.chain (fun_ord (flat_ord (Inl e))) A"
+ and 2 [rule_format]: "\<forall>xa\<in>A. \<forall>h h' h2 h2' r r'. h \<turnstile> Prog xa = Inr (r, h2)
+ \<longrightarrow> h' \<turnstile> Prog xa = Inr (r', h2') \<longrightarrow> P h h' h2 h2' r r'"
+ and 4: "h \<turnstile> Prog (fun_lub (flat_lub (Inl e)) A) = Inr (r, h2)"
+ and 5: "h' \<turnstile> Prog (fun_lub (flat_lub (Inl e)) A) = Inr (r', h2')"
+ have h1:"\<And>a. Complete_Partial_Order.chain (flat_ord (Inl e)) {y. \<exists>f\<in>A. y = f a}"
+ by (rule chain_fun[OF 1])
+ have "h \<turnstile> ?lub \<in> {y. \<exists>f\<in>A. y = f h}"
+ using flat_lub_in_chain[OF h1] 4
+ unfolding execute_def fun_lub_def
+ by (metis (mono_tags, lifting) Collect_cong Inl_Inr_False prog.sel)
+ moreover have "h' \<turnstile> ?lub \<in> {y. \<exists>f\<in>A. y = f h'}"
+ using flat_lub_in_chain[OF h1] 5
+ unfolding execute_def fun_lub_def
+ by (metis (no_types, lifting) Collect_cong Inl_Inr_False prog.sel)
+ ultimately obtain f where
+ "f \<in> A" and
+ "h \<turnstile> Prog f = Inr (r, h2)" and
+ "h' \<turnstile> Prog f = Inr (r', h2')"
+ using 1 4 5
+ apply(auto simp add: chain_def fun_ord_def flat_ord_def execute_def)[1]
+ by (metis Inl_Inr_False)
+ then show "P h h' h2 h2' r r'"
+ by(fact 2)
+qed
+
+definition dom_prog_ord ::
+ "('heap, exception, 'result) prog \<Rightarrow> ('heap, exception, 'result) prog \<Rightarrow> bool" where
+ "dom_prog_ord = img_ord (\<lambda>a b. execute b a) (fun_ord (flat_ord (Inl NonTerminationException)))"
+
+definition dom_prog_lub ::
+ "('heap, exception, 'result) prog set \<Rightarrow> ('heap, exception, 'result) prog" where
+ "dom_prog_lub = img_lub (\<lambda>a b. execute b a) Prog (fun_lub (flat_lub (Inl NonTerminationException)))"
+
+lemma dom_prog_lub_empty: "dom_prog_lub {} = error NonTerminationException"
+ by(simp add: dom_prog_lub_def img_lub_def fun_lub_def flat_lub_def error_def)
+
+lemma dom_prog_interpretation: "partial_function_definitions dom_prog_ord dom_prog_lub"
+proof -
+ have "partial_function_definitions (fun_ord (flat_ord (Inl NonTerminationException)))
+ (fun_lub (flat_lub (Inl NonTerminationException)))"
+ by (rule partial_function_lift) (rule flat_interpretation)
+ then show ?thesis
+ apply (simp add: dom_prog_lub_def dom_prog_ord_def flat_interpretation execute_def)
+ using partial_function_image prog.expand prog.sel by blast
+qed
+
+interpretation dom_prog: partial_function_definitions dom_prog_ord dom_prog_lub
+ rewrites "dom_prog_lub {} \<equiv> error NonTerminationException"
+ by (fact dom_prog_interpretation)(simp add: dom_prog_lub_empty)
+
+lemma admissible_dom_prog:
+ "dom_prog.admissible (\<lambda>f. \<forall>x h h' r. h \<turnstile> f x \<rightarrow>\<^sub>r r \<longrightarrow> h \<turnstile> f x \<rightarrow>\<^sub>h h' \<longrightarrow> P x h h' r)"
+proof (rule admissible_fun[OF dom_prog_interpretation])
+ fix x
+ show "ccpo.admissible dom_prog_lub dom_prog_ord (\<lambda>a. \<forall>h h' r. h \<turnstile> a \<rightarrow>\<^sub>r r \<longrightarrow> h \<turnstile> a \<rightarrow>\<^sub>h h'
+ \<longrightarrow> P x h h' r)"
+ unfolding dom_prog_ord_def dom_prog_lub_def
+ proof (intro admissible_image partial_function_lift flat_interpretation)
+ show "ccpo.admissible (fun_lub (flat_lub (Inl NonTerminationException)))
+ (fun_ord (flat_ord (Inl NonTerminationException)))
+ ((\<lambda>a. \<forall>h h' r. h \<turnstile> a \<rightarrow>\<^sub>r r \<longrightarrow> h \<turnstile> a \<rightarrow>\<^sub>h h' \<longrightarrow> P x h h' r) \<circ> Prog)"
+ by(auto simp add: execute_admissible returns_result_def returns_heap_def split: sum.splits)
+ next
+ show "\<And>x y. (\<lambda>b. b \<turnstile> x) = (\<lambda>b. b \<turnstile> y) \<Longrightarrow> x = y"
+ by(simp add: execute_def prog.expand)
+ next
+ show "\<And>x. (\<lambda>b. b \<turnstile> Prog x) = x"
+ by(simp add: execute_def)
+ qed
+qed
+
+lemma admissible_dom_prog2:
+ "dom_prog.admissible (\<lambda>f. \<forall>x h h2 h' h2' r r2. h \<turnstile> f x \<rightarrow>\<^sub>r r \<longrightarrow> h \<turnstile> f x \<rightarrow>\<^sub>h h'
+ \<longrightarrow> h2 \<turnstile> f x \<rightarrow>\<^sub>r r2 \<longrightarrow> h2 \<turnstile> f x \<rightarrow>\<^sub>h h2' \<longrightarrow> P x h h2 h' h2' r r2)"
+proof (rule admissible_fun[OF dom_prog_interpretation])
+ fix x
+ show "ccpo.admissible dom_prog_lub dom_prog_ord (\<lambda>a. \<forall>h h2 h' h2' r r2. h \<turnstile> a \<rightarrow>\<^sub>r r
+ \<longrightarrow> h \<turnstile> a \<rightarrow>\<^sub>h h' \<longrightarrow> h2 \<turnstile> a \<rightarrow>\<^sub>r r2 \<longrightarrow> h2 \<turnstile> a \<rightarrow>\<^sub>h h2' \<longrightarrow> P x h h2 h' h2' r r2)"
+ unfolding dom_prog_ord_def dom_prog_lub_def
+ proof (intro admissible_image partial_function_lift flat_interpretation)
+ show "ccpo.admissible (fun_lub (flat_lub (Inl NonTerminationException)))
+ (fun_ord (flat_ord (Inl NonTerminationException)))
+ ((\<lambda>a. \<forall>h h2 h' h2' r r2. h \<turnstile> a \<rightarrow>\<^sub>r r \<longrightarrow> h \<turnstile> a \<rightarrow>\<^sub>h h' \<longrightarrow> h2 \<turnstile> a \<rightarrow>\<^sub>r r2 \<longrightarrow> h2 \<turnstile> a \<rightarrow>\<^sub>h h2'
+ \<longrightarrow> P x h h2 h' h2' r r2) \<circ> Prog)"
+ by(auto simp add: returns_result_def returns_heap_def intro!: ccpo.admissibleI
+ dest!: ccpo.admissibleD[OF execute_admissible2[where P="P x"]]
+ split: sum.splits)
+ next
+ show "\<And>x y. (\<lambda>b. b \<turnstile> x) = (\<lambda>b. b \<turnstile> y) \<Longrightarrow> x = y"
+ by(simp add: execute_def prog.expand)
+ next
+ show "\<And>x. (\<lambda>b. b \<turnstile> Prog x) = x"
+ by(simp add: execute_def)
+ qed
+qed
+
+lemma fixp_induct_dom_prog:
+ fixes F :: "'c \<Rightarrow> 'c" and
+ U :: "'c \<Rightarrow> 'b \<Rightarrow> ('heap, exception, 'result) prog" and
+ C :: "('b \<Rightarrow> ('heap, exception, 'result) prog) \<Rightarrow> 'c" and
+ P :: "'b \<Rightarrow> 'heap \<Rightarrow> 'heap \<Rightarrow> 'result \<Rightarrow> bool"
+ assumes mono: "\<And>x. monotone (fun_ord dom_prog_ord) dom_prog_ord (\<lambda>f. U (F (C f)) x)"
+ assumes eq: "f \<equiv> C (ccpo.fixp (fun_lub dom_prog_lub) (fun_ord dom_prog_ord) (\<lambda>f. U (F (C f))))"
+ assumes inverse2: "\<And>f. U (C f) = f"
+ assumes step: "\<And>f x h h' r. (\<And>x h h' r. h \<turnstile> (U f x) \<rightarrow>\<^sub>r r \<Longrightarrow> h \<turnstile> (U f x) \<rightarrow>\<^sub>h h' \<Longrightarrow> P x h h' r)
+ \<Longrightarrow> h \<turnstile> (U (F f) x) \<rightarrow>\<^sub>r r \<Longrightarrow> h \<turnstile> (U (F f) x) \<rightarrow>\<^sub>h h' \<Longrightarrow> P x h h' r"
+ assumes defined: "h \<turnstile> (U f x) \<rightarrow>\<^sub>r r" and "h \<turnstile> (U f x) \<rightarrow>\<^sub>h h'"
+ shows "P x h h' r"
+ using step defined dom_prog.fixp_induct_uc[of U F C, OF mono eq inverse2 admissible_dom_prog, of P]
+ by (metis assms(6) error_returns_heap)
+
+declaration \<open>Partial_Function.init "dom_prog" @{term dom_prog.fixp_fun}
+ @{term dom_prog.mono_body} @{thm dom_prog.fixp_rule_uc} @{thm dom_prog.fixp_induct_uc}
+ (SOME @{thm fixp_induct_dom_prog})\<close>
+
+
+abbreviation "mono_dom_prog \<equiv> monotone (fun_ord dom_prog_ord) dom_prog_ord"
+
+lemma dom_prog_ordI:
+ assumes "\<And>h. h \<turnstile> f \<rightarrow>\<^sub>e NonTerminationException \<or> h \<turnstile> f = h \<turnstile> g"
+ shows "dom_prog_ord f g"
+proof(auto simp add: dom_prog_ord_def img_ord_def fun_ord_def flat_ord_def)[1]
+ fix x
+ assume "x \<turnstile> f \<noteq> x \<turnstile> g"
+ then show "x \<turnstile> f = Inl NonTerminationException"
+ using assms[where h=x]
+ by(auto simp add: returns_error_def split: sum.splits)
+qed
+
+lemma dom_prog_ordE:
+ assumes "dom_prog_ord x y"
+ obtains "h \<turnstile> x \<rightarrow>\<^sub>e NonTerminationException" | " h \<turnstile> x = h \<turnstile> y"
+ using assms unfolding dom_prog_ord_def img_ord_def fun_ord_def flat_ord_def
+ using returns_error_def by force
+
+
+lemma bind_mono [partial_function_mono]:
+ fixes B :: "('a \<Rightarrow> ('heap, exception, 'result) prog) \<Rightarrow> ('heap, exception, 'result2) prog"
+ assumes mf: "mono_dom_prog B" and mg: "\<And>y. mono_dom_prog (\<lambda>f. C y f)"
+ shows "mono_dom_prog (\<lambda>f. B f \<bind> (\<lambda>y. C y f))"
+proof (rule monotoneI)
+ fix f g :: "'a \<Rightarrow> ('heap, exception, 'result) prog"
+ assume fg: "dom_prog.le_fun f g"
+ from mf
+ have 1: "dom_prog_ord (B f) (B g)" by (rule monotoneD) (rule fg)
+ from mg
+ have 2: "\<And>y'. dom_prog_ord (C y' f) (C y' g)" by (rule monotoneD) (rule fg)
+
+ have "dom_prog_ord (B f \<bind> (\<lambda>y. C y f)) (B g \<bind> (\<lambda>y. C y f))"
+ (is "dom_prog_ord ?L ?R")
+ proof (rule dom_prog_ordI)
+ fix h
+ from 1 show "h \<turnstile> ?L \<rightarrow>\<^sub>e NonTerminationException \<or> h \<turnstile> ?L = h \<turnstile> ?R"
+ apply(rule dom_prog_ordE)
+ apply(auto)[1]
+ using bind_cong by fastforce
+ qed
+ also
+ have h1: "dom_prog_ord (B g \<bind> (\<lambda>y'. C y' f)) (B g \<bind> (\<lambda>y'. C y' g))"
+ (is "dom_prog_ord ?L ?R")
+ proof (rule dom_prog_ordI)
+ (* { *)
+ fix h
+ show "h \<turnstile> ?L \<rightarrow>\<^sub>e NonTerminationException \<or> h \<turnstile> ?L = h \<turnstile> ?R"
+ proof (cases "h \<turnstile> ok (B g)")
+ case True
+ then obtain x h' where x: "h \<turnstile> B g \<rightarrow>\<^sub>r x" and h': "h \<turnstile> B g \<rightarrow>\<^sub>h h'"
+ by blast
+ then have "dom_prog_ord (C x f) (C x g)"
+ using 2 by simp
+ then show ?thesis
+ using x h'
+ apply(auto intro!: bind_returns_error_I3 dest: returns_result_eq dest!: dom_prog_ordE)[1]
+ apply(auto simp add: execute_bind_simp)[1]
+ using "2" dom_prog_ordE by metis
+ next
+ case False
+ then obtain e where e: "h \<turnstile> B g \<rightarrow>\<^sub>e e"
+ by(simp add: is_OK_def returns_error_def split: sum.splits)
+ have "h \<turnstile> B g \<bind> (\<lambda>y'. C y' f) \<rightarrow>\<^sub>e e"
+ using e by(auto)
+ moreover have "h \<turnstile> B g \<bind> (\<lambda>y'. C y' g) \<rightarrow>\<^sub>e e"
+ using e by auto
+ ultimately show ?thesis
+ using bind_returns_error_eq by metis
+ qed
+ qed
+ finally (dom_prog.leq_trans)
+ show "dom_prog_ord (B f \<bind> (\<lambda>y. C y f)) (B g \<bind> (\<lambda>y'. C y' g))" .
+qed
+
+lemma mono_dom_prog1 [partial_function_mono]:
+ fixes g :: "('a \<Rightarrow> ('heap, exception, 'result) prog) \<Rightarrow> 'b \<Rightarrow> ('heap, exception, 'result) prog"
+ assumes "\<And>x. (mono_dom_prog (\<lambda>f. g f x))"
+ shows "mono_dom_prog (\<lambda>f. map_M (g f) xs)"
+ using assms
+ apply (induct xs)
+ by(auto simp add: call_mono dom_prog.const_mono intro!: bind_mono)
+
+lemma mono_dom_prog2 [partial_function_mono]:
+ fixes g :: "('a \<Rightarrow> ('heap, exception, 'result) prog) \<Rightarrow> 'b \<Rightarrow> ('heap, exception, 'result) prog"
+ assumes "\<And>x. (mono_dom_prog (\<lambda>f. g f x))"
+ shows "mono_dom_prog (\<lambda>f. forall_M (g f) xs)"
+ using assms
+ apply (induct xs)
+ by(auto simp add: call_mono dom_prog.const_mono intro!: bind_mono)
+
+lemma sorted_list_set_cong [simp]:
+ "sorted_list_of_set (fset FS) = sorted_list_of_set (fset FS') \<longleftrightarrow> FS = FS'"
+ by auto
+
+end
diff --git a/thys/Core_SC_DOM/common/monads/CharacterDataMonad.thy b/thys/Core_SC_DOM/common/monads/CharacterDataMonad.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/monads/CharacterDataMonad.thy
@@ -0,0 +1,534 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>CharacterData\<close>
+text\<open>In this theory, we introduce the monadic method setup for the CharacterData class.\<close>
+theory CharacterDataMonad
+ imports
+ ElementMonad
+ "../classes/CharacterDataClass"
+begin
+
+type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+ 'shadow_root_ptr, 'Object, 'Node, 'Element, 'CharacterData, 'result) dom_prog
+ = "((_) heap, exception, 'result) prog"
+register_default_tvars
+ "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr, 'shadow_root_ptr,
+ 'Object, 'Node, 'Element, 'CharacterData, 'result) dom_prog"
+
+
+global_interpretation l_ptr_kinds_M character_data_ptr_kinds
+ defines character_data_ptr_kinds_M = a_ptr_kinds_M .
+lemmas character_data_ptr_kinds_M_defs = a_ptr_kinds_M_def
+
+lemma character_data_ptr_kinds_M_eq:
+ assumes "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ shows "|h \<turnstile> character_data_ptr_kinds_M|\<^sub>r = |h' \<turnstile> character_data_ptr_kinds_M|\<^sub>r"
+ using assms
+ by(auto simp add: character_data_ptr_kinds_M_defs node_ptr_kinds_M_defs
+ character_data_ptr_kinds_def)
+
+lemma character_data_ptr_kinds_M_reads:
+ "reads (\<Union>node_ptr. {preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t node_ptr RObject.nothing)}) character_data_ptr_kinds_M h h'"
+ using node_ptr_kinds_M_reads
+ apply (simp add: reads_def node_ptr_kinds_M_defs character_data_ptr_kinds_M_defs
+ character_data_ptr_kinds_def preserved_def)
+ by (smt node_ptr_kinds_small preserved_def unit_all_impI)
+
+global_interpretation l_dummy defines get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a = "l_get_M.a_get_M get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a" .
+lemma get_M_is_l_get_M: "l_get_M get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a type_wf character_data_ptr_kinds"
+ apply(simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_type_wf l_get_M_def)
+ by (metis (no_types, hide_lams) NodeMonad.get_M_is_l_get_M bind_eq_Some_conv
+ character_data_ptr_kinds_commutes get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def l_get_M_def option.distinct(1))
+lemmas get_M_defs = get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def[unfolded l_get_M.a_get_M_def[OF get_M_is_l_get_M]]
+
+adhoc_overloading get_M get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+
+locale l_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas = l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+begin
+sublocale l_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas by unfold_locales
+
+interpretation l_get_M get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a type_wf character_data_ptr_kinds
+ apply(unfold_locales)
+ apply (simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_type_wf local.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a)
+ by (meson CharacterDataMonad.get_M_is_l_get_M l_get_M_def)
+lemmas get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ok = get_M_ok[folded get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def]
+end
+
+global_interpretation l_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas type_wf by unfold_locales
+
+
+global_interpretation l_put_M type_wf character_data_ptr_kinds get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+ rewrites "a_get_M = get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a" defines put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a = a_put_M
+ apply (simp add: get_M_is_l_get_M l_put_M_def)
+ by (simp add: get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def)
+
+lemmas put_M_defs = a_put_M_def
+adhoc_overloading put_M put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+
+
+locale l_put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas = l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+begin
+sublocale l_put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas by unfold_locales
+
+interpretation l_put_M type_wf character_data_ptr_kinds get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+ apply(unfold_locales)
+ using get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_type_wf l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a local.l_type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_axioms
+ apply blast
+ by (meson CharacterDataMonad.get_M_is_l_get_M l_get_M_def)
+lemmas put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ok = put_M_ok[folded put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def]
+end
+
+global_interpretation l_put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas type_wf by unfold_locales
+
+
+
+lemma CharacterData_simp1 [simp]:
+ "(\<And>x. getter (setter (\<lambda>_. v) x) = v) \<Longrightarrow> h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr getter \<rightarrow>\<^sub>r v"
+ by(auto simp add: put_M_defs get_M_defs split: option.splits)
+lemma CharacterData_simp2 [simp]:
+ "character_data_ptr \<noteq> character_data_ptr'
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr' getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs preserved_def split: option.splits dest: get_heap_E)
+lemma CharacterData_simp3 [simp]: "
+ (\<And>x. getter (setter (\<lambda>_. v) x) = getter x)
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr' getter) h h'"
+ apply(cases "character_data_ptr = character_data_ptr'")
+ by(auto simp add: put_M_defs get_M_defs preserved_def split: option.splits dest: get_heap_E)
+lemma CharacterData_simp4 [simp]:
+ "h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr getter) h h'"
+ by(auto simp add: put_M_defs ElementMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma CharacterData_simp5 [simp]:
+ "h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr getter) h h'"
+ by(auto simp add: ElementMonad.put_M_defs get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma CharacterData_simp6 [simp]:
+ "(\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ apply (cases "cast character_data_ptr = object_ptr")
+ by(auto simp add: put_M_defs get_M_defs ObjectMonad.get_M_defs NodeMonad.get_M_defs
+ get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def preserved_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ bind_eq_Some_conv split: option.splits)
+lemma CharacterData_simp7 [simp]:
+ "(\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr getter) h h'"
+ apply(cases "cast character_data_ptr = node_ptr")
+ by(auto simp add: put_M_defs get_M_defs ObjectMonad.get_M_defs NodeMonad.get_M_defs
+ get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def preserved_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ bind_eq_Some_conv split: option.splits)
+
+lemma CharacterData_simp8 [simp]:
+ "cast character_data_ptr \<noteq> node_ptr
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def NodeMonad.get_M_defs
+ preserved_def split: option.splits dest: get_heap_E)
+lemma CharacterData_simp9 [simp]:
+ "h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr getter) h h'"
+ apply(cases "cast character_data_ptr \<noteq> node_ptr")
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def
+ NodeMonad.get_M_defs preserved_def split: option.splits bind_splits
+ dest: get_heap_E)
+lemma CharacterData_simp10 [simp]:
+ "cast character_data_ptr \<noteq> node_ptr
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr getter) h h'"
+ by(auto simp add: NodeMonad.put_M_defs get_M_defs get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def NodeMonad.get_M_defs
+ preserved_def split: option.splits dest: get_heap_E)
+
+lemma CharacterData_simp11 [simp]:
+ "cast character_data_ptr \<noteq> object_ptr
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def
+ ObjectMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+
+lemma CharacterData_simp12 [simp]:
+ "h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ apply(cases "cast character_data_ptr \<noteq> object_ptr")
+ apply(auto simp add: put_M_defs get_M_defs get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def
+ get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def ObjectMonad.get_M_defs preserved_def
+ split: option.splits bind_splits dest: get_heap_E)[1]
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def
+ get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def ObjectMonad.get_M_defs preserved_def
+ split: option.splits bind_splits dest: get_heap_E)[1]
+
+lemma CharacterData_simp13 [simp]:
+ "cast character_data_ptr \<noteq> object_ptr \<Longrightarrow> h \<turnstile> put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr getter) h h'"
+ by(auto simp add: ObjectMonad.put_M_defs get_M_defs get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ ObjectMonad.get_M_defs preserved_def split: option.splits dest: get_heap_E)
+
+lemma new_element_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr getter) h h'"
+ by(auto simp add: new_element_def get_M_defs preserved_def split: prod.splits option.splits
+ elim!: bind_returns_result_E bind_returns_heap_E)
+
+
+subsection\<open>Creating CharacterData\<close>
+
+definition new_character_data :: "(_, (_) character_data_ptr) dom_prog"
+ where
+ "new_character_data = do {
+ h \<leftarrow> get_heap;
+ (new_ptr, h') \<leftarrow> return (new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h);
+ return_heap h';
+ return new_ptr
+ }"
+
+lemma new_character_data_ok [simp]:
+ "h \<turnstile> ok new_character_data"
+ by(auto simp add: new_character_data_def split: prod.splits)
+
+lemma new_character_data_ptr_in_heap:
+ assumes "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr"
+ shows "new_character_data_ptr |\<in>| character_data_ptr_kinds h'"
+ using assms
+ unfolding new_character_data_def
+ by(auto simp add: new_character_data_def new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ptr_in_heap
+ is_OK_returns_result_I
+ elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_character_data_ptr_not_in_heap:
+ assumes "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr"
+ shows "new_character_data_ptr |\<notin>| character_data_ptr_kinds h"
+ using assms new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ptr_not_in_heap
+ by(auto simp add: new_character_data_def split: prod.splits
+ elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_character_data_new_ptr:
+ assumes "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using assms new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_new_ptr
+ by(auto simp add: new_character_data_def split: prod.splits
+ elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_character_data_is_character_data_ptr:
+ assumes "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr"
+ shows "is_character_data_ptr new_character_data_ptr"
+ using assms new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_is_character_data_ptr
+ by(auto simp add: new_character_data_def elim!: bind_returns_result_E split: prod.splits)
+
+lemma new_character_data_child_nodes:
+ assumes "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr"
+ shows "h' \<turnstile> get_M new_character_data_ptr val \<rightarrow>\<^sub>r ''''"
+ using assms
+ by(auto simp add: get_M_defs new_character_data_def new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def
+ split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_character_data_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr
+ \<Longrightarrow> ptr \<noteq> cast new_character_data_ptr \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_character_data_def ObjectMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_character_data_get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr
+ \<Longrightarrow> ptr \<noteq> cast new_character_data_ptr \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr getter) h h'"
+ by(auto simp add: new_character_data_def NodeMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_character_data_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_character_data_def ElementMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_character_data_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr
+ \<Longrightarrow> ptr \<noteq> new_character_data_ptr \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr getter) h h'"
+ by(auto simp add: new_character_data_def get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+
+
+subsection\<open>Modified Heaps\<close>
+
+lemma get_CharacterData_ptr_simp [simp]:
+ "get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)
+ = (if ptr = cast character_data_ptr then cast obj else get character_data_ptr h)"
+ by(auto simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def split: option.splits Option.bind_splits)
+
+lemma Character_data_ptr_kinds_simp [simp]:
+ "character_data_ptr_kinds (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h) = character_data_ptr_kinds h |\<union>|
+ (if is_character_data_ptr_kind ptr then {|the (cast ptr)|} else {||})"
+ by(auto simp add: character_data_ptr_kinds_def is_node_ptr_kind_def split: option.splits)
+
+lemma type_wf_put_I:
+ assumes "type_wf h"
+ assumes "ElementClass.type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "is_character_data_ptr_kind ptr \<Longrightarrow> is_character_data_kind obj"
+ shows "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ using assms
+ by(auto simp add: type_wf_defs split: option.splits)
+
+lemma type_wf_put_ptr_not_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<notin>| object_ptr_kinds h"
+ shows "type_wf h"
+ using assms
+ apply(auto simp add: type_wf_defs elim!: ElementMonad.type_wf_put_ptr_not_in_heap_E
+ split: option.splits if_splits)[1]
+ using assms(2) node_ptr_kinds_commutes by blast
+
+lemma type_wf_put_ptr_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ assumes "ElementClass.type_wf h"
+ assumes "is_character_data_ptr_kind ptr \<Longrightarrow> is_character_data_kind (the (get ptr h))"
+ shows "type_wf h"
+ using assms
+ apply(auto simp add: type_wf_defs split: option.splits if_splits)[1]
+ by (metis (no_types, lifting) ElementClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf assms(2) bind.bind_lunit
+ cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_inv cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_inv get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def notin_fset option.collapse)
+
+subsection\<open>Preserving Types\<close>
+
+lemma new_element_type_wf_preserved [simp]:
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ using assms
+ apply(auto simp add: new_element_def new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ elim!: bind_returns_heap_E type_wf_put_ptr_not_in_heap_E
+ intro!: type_wf_put_I split: if_splits)[1]
+ using CharacterDataClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t assms new_element_type_wf_preserved apply blast
+ using element_ptrs_def apply fastforce
+ using CharacterDataClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t assms new_element_type_wf_preserved apply blast
+ by (metis Suc_n_not_le_n element_ptr.sel(1) element_ptrs_def fMax_ge ffmember_filter
+ fimage_eqI is_element_ptr_ref)
+
+lemma new_element_is_l_new_element: "l_new_element type_wf"
+ using l_new_element.intro new_element_type_wf_preserved
+ by blast
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_tag_name_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr tag_name_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: ElementMonad.put_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I
+ ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs split: option.splits)[1]
+ using ObjectMonad.type_wf_put_ptr_in_heap_E ObjectMonad.type_wf_put_ptr_not_in_heap_E apply blast
+ apply (metis (no_types, lifting) bind_eq_Some_conv finite_set_in get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+ apply (metis finite_set_in)
+ done
+
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_child_nodes_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr child_nodes_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: ElementMonad.put_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ dest!: get_heap_E elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I ElementMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs
+ split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs
+ split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs
+ split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs
+ split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs
+ split: option.splits)[1]
+ using ObjectMonad.type_wf_put_ptr_in_heap_E ObjectMonad.type_wf_put_ptr_not_in_heap_E apply blast
+ apply (metis (no_types, lifting) bind_eq_Some_conv finite_set_in get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+ apply (metis finite_set_in)
+ done
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_attrs_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr attrs_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: ElementMonad.put_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I
+ ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs
+ ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs
+ ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs
+ ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs
+ ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs
+ ElementMonad.get_M_defs split: option.splits)[1]
+ using ObjectMonad.type_wf_put_ptr_in_heap_E ObjectMonad.type_wf_put_ptr_not_in_heap_E apply blast
+ apply (metis (no_types, lifting) bind_eq_Some_conv finite_set_in get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+ apply (metis finite_set_in)
+ done
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_shadow_root_opt_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr shadow_root_opt_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: ElementMonad.put_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I
+ ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs
+ ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs
+ ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs
+ ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs
+ ElementMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs
+ ElementMonad.get_M_defs split: option.splits)[1]
+ using ObjectMonad.type_wf_put_ptr_in_heap_E ObjectMonad.type_wf_put_ptr_not_in_heap_E apply blast
+ apply (metis (no_types, lifting) bind_eq_Some_conv finite_set_in get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+ apply (metis finite_set_in)
+ done
+
+
+lemma new_character_data_type_wf_preserved [simp]:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: new_character_data_def new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ elim!: bind_returns_heap_E type_wf_put_ptr_not_in_heap_E
+ intro!: type_wf_put_I ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I
+ split: if_splits)[1]
+ apply(simp_all add: type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs is_node_kind_def)
+ by (meson new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ptr_not_in_heap)
+
+locale l_new_character_data = l_type_wf +
+ assumes new_character_data_types_preserved: "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+
+lemma new_character_data_is_l_new_character_data: "l_new_character_data type_wf"
+ using l_new_character_data.intro new_character_data_type_wf_preserved
+ by blast
+
+lemma put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_val_type_wf_preserved [simp]:
+ "h \<turnstile> put_M character_data_ptr val_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: CharacterDataMonad.put_M_defs put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ CharacterDataClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e CharacterDataClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ is_node_kind_def
+ dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I
+ ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs CharacterDataMonad.get_M_defs
+ split: option.splits)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs CharacterDataMonad.get_M_defs
+ ObjectClass.a_type_wf_def
+ split: option.splits)[1]
+ apply (metis (no_types, lifting) bind_eq_Some_conv finite_set_in get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def)
+ apply (metis finite_set_in)
+ done
+
+lemma character_data_ptr_kinds_small:
+ assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ shows "character_data_ptr_kinds h = character_data_ptr_kinds h'"
+ by(simp add: character_data_ptr_kinds_def node_ptr_kinds_def preserved_def
+ object_ptr_kinds_preserved_small[OF assms])
+
+lemma character_data_ptr_kinds_preserved:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h'. \<forall>w \<in> SW. h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<longrightarrow> (\<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h')"
+ shows "character_data_ptr_kinds h = character_data_ptr_kinds h'"
+ using writes_small_big[OF assms]
+ apply(simp add: reflp_def transp_def preserved_def character_data_ptr_kinds_def)
+ by (metis assms node_ptr_kinds_preserved)
+
+
+lemma type_wf_preserved_small:
+ assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ assumes "\<And>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
+ assumes "\<And>element_ptr. preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr RElement.nothing) h h'"
+ assumes "\<And>character_data_ptr. preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr
+ RCharacterData.nothing) h h'"
+ shows "type_wf h = type_wf h'"
+ using type_wf_preserved_small[OF assms(1) assms(2) assms(3)]
+ allI[OF assms(4), of id, simplified] character_data_ptr_kinds_small[OF assms(1)]
+ apply(auto simp add: type_wf_defs preserved_def get_M_defs character_data_ptr_kinds_small[OF assms(1)]
+ split: option.splits)[1]
+ apply(force)
+ by force
+
+lemma type_wf_preserved:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>element_ptr. preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr RElement.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>character_data_ptr. preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr
+ RCharacterData.nothing) h h'"
+ shows "type_wf h = type_wf h'"
+proof -
+ have "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ using assms type_wf_preserved_small by fast
+ with assms(1) assms(2) show ?thesis
+ apply(rule writes_small_big)
+ by(auto simp add: reflp_def transp_def)
+qed
+
+lemma type_wf_drop: "type_wf h \<Longrightarrow> type_wf (Heap (fmdrop ptr (the_heap h)))"
+ apply(auto simp add: type_wf_def ElementMonad.type_wf_drop
+ l_type_wf_def\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a.a_type_wf_def)[1]
+ using type_wf_drop
+ by (metis (no_types, lifting) ElementClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ObjectClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf
+ character_data_ptr_kinds_commutes finite_set_in fmlookup_drop get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def node_ptr_kinds_commutes object_ptr_kinds_code5)
+
+end
diff --git a/thys/Core_SC_DOM/common/monads/DocumentMonad.thy b/thys/Core_SC_DOM/common/monads/DocumentMonad.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/monads/DocumentMonad.thy
@@ -0,0 +1,614 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Document\<close>
+text\<open>In this theory, we introduce the monadic method setup for the Document class.\<close>
+
+theory DocumentMonad
+ imports
+ CharacterDataMonad
+ "../classes/DocumentClass"
+begin
+
+type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+ 'shadow_root_ptr, 'Object, 'Node, 'Element, 'CharacterData, 'Document, 'result) dom_prog
+ = "((_) heap, exception, 'result) prog"
+register_default_tvars "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+ 'shadow_root_ptr, 'Object, 'Node, 'Element, 'CharacterData, 'Document, 'result) dom_prog"
+
+
+global_interpretation l_ptr_kinds_M document_ptr_kinds defines document_ptr_kinds_M = a_ptr_kinds_M .
+lemmas document_ptr_kinds_M_defs = a_ptr_kinds_M_def
+
+lemma document_ptr_kinds_M_eq:
+ assumes "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ shows "|h \<turnstile> document_ptr_kinds_M|\<^sub>r = |h' \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using assms
+ by(auto simp add: document_ptr_kinds_M_defs object_ptr_kinds_M_defs document_ptr_kinds_def)
+
+lemma document_ptr_kinds_M_reads:
+ "reads (\<Union>object_ptr. {preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing)}) document_ptr_kinds_M h h'"
+ using object_ptr_kinds_M_reads
+ apply (simp add: reads_def object_ptr_kinds_M_defs document_ptr_kinds_M_defs
+ document_ptr_kinds_def preserved_def cong del: image_cong_simp)
+ apply (metis (mono_tags, hide_lams) object_ptr_kinds_preserved_small old.unit.exhaust preserved_def)
+ done
+
+global_interpretation l_dummy defines get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t = "l_get_M.a_get_M get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t" .
+lemma get_M_is_l_get_M: "l_get_M get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t type_wf document_ptr_kinds"
+ apply(simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_type_wf l_get_M_def)
+ by (metis ObjectClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf ObjectClass.type_wf_defs bind_eq_None_conv
+ document_ptr_kinds_commutes get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def option.simps(3))
+lemmas get_M_defs = get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def[unfolded l_get_M.a_get_M_def[OF get_M_is_l_get_M]]
+
+adhoc_overloading get_M get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+locale l_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas = l_type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+begin
+sublocale l_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas by unfold_locales
+
+interpretation l_get_M get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t type_wf document_ptr_kinds
+ apply(unfold_locales)
+ apply (simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_type_wf local.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+ by (meson DocumentMonad.get_M_is_l_get_M l_get_M_def)
+lemmas get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok = get_M_ok[folded get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def]
+end
+
+global_interpretation l_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas type_wf by unfold_locales
+
+
+global_interpretation l_put_M type_wf document_ptr_kinds get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ rewrites "a_get_M = get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t" defines put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t = a_put_M
+ apply (simp add: get_M_is_l_get_M l_put_M_def)
+ by (simp add: get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+
+lemmas put_M_defs = a_put_M_def
+adhoc_overloading put_M put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+
+locale l_put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas = l_type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+begin
+sublocale l_put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas by unfold_locales
+
+interpretation l_put_M type_wf document_ptr_kinds get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ apply(unfold_locales)
+ apply (simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_type_wf local.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+ by (meson DocumentMonad.get_M_is_l_get_M l_get_M_def)
+lemmas put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok = put_M_ok[folded put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def]
+end
+
+global_interpretation l_put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas type_wf by unfold_locales
+
+
+lemma document_put_get [simp]:
+ "h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. getter (setter (\<lambda>_. v) x) = v)
+ \<Longrightarrow> h' \<turnstile> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr getter \<rightarrow>\<^sub>r v"
+ by(auto simp add: put_M_defs get_M_defs split: option.splits)
+lemma get_M_Mdocument_preserved1 [simp]:
+ "document_ptr \<noteq> document_ptr'
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr' getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs preserved_def split: option.splits dest: get_heap_E)
+lemma document_put_get_preserved [simp]:
+ "h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. getter (setter (\<lambda>_. v) x) = getter x)
+ \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr' getter) h h'"
+ apply(cases "document_ptr = document_ptr'")
+ by(auto simp add: put_M_defs get_M_defs preserved_def split: option.splits dest: get_heap_E)
+
+lemma get_M_Mdocument_preserved2 [simp]:
+ "h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs NodeMonad.get_M_defs get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def preserved_def split: option.splits dest: get_heap_E)
+
+lemma get_M_Mdocument_preserved3 [simp]:
+ "cast document_ptr \<noteq> object_ptr
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def ObjectMonad.get_M_defs
+ preserved_def split: option.splits dest: get_heap_E)
+lemma get_M_Mdocument_preserved4 [simp]:
+ "h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ apply(cases "cast document_ptr \<noteq> object_ptr")[1]
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ ObjectMonad.get_M_defs preserved_def
+ split: option.splits bind_splits dest: get_heap_E)
+
+lemma get_M_Mdocument_preserved5 [simp]:
+ "cast document_ptr \<noteq> object_ptr
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr getter) h h'"
+ by(auto simp add: ObjectMonad.put_M_defs get_M_defs get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def ObjectMonad.get_M_defs
+ preserved_def split: option.splits dest: get_heap_E)
+
+lemma get_M_Mdocument_preserved6 [simp]:
+ "h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr getter) h h'"
+ by(auto simp add: put_M_defs ElementMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_Mdocument_preserved7 [simp]:
+ "h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr getter) h h'"
+ by(auto simp add: ElementMonad.put_M_defs get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_Mdocument_preserved8 [simp]:
+ "h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr getter) h h'"
+ by(auto simp add: put_M_defs CharacterDataMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_Mdocument_preserved9 [simp]:
+ "h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr getter) h h'"
+ by(auto simp add: CharacterDataMonad.put_M_defs get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_Mdocument_preserved10 [simp]:
+ "(\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ apply(cases "cast document_ptr = object_ptr")
+ by(auto simp add: put_M_defs get_M_defs ObjectMonad.get_M_defs NodeMonad.get_M_defs get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def preserved_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def bind_eq_Some_conv
+ split: option.splits)
+
+lemma new_element_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_element_def get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_character_data_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_character_data_def get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+
+subsection \<open>Creating Documents\<close>
+
+definition new_document :: "(_, (_) document_ptr) dom_prog"
+ where
+ "new_document = do {
+ h \<leftarrow> get_heap;
+ (new_ptr, h') \<leftarrow> return (new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h);
+ return_heap h';
+ return new_ptr
+ }"
+
+lemma new_document_ok [simp]:
+ "h \<turnstile> ok new_document"
+ by(auto simp add: new_document_def split: prod.splits)
+
+lemma new_document_ptr_in_heap:
+ assumes "h \<turnstile> new_document \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr"
+ shows "new_document_ptr |\<in>| document_ptr_kinds h'"
+ using assms
+ unfolding new_document_def
+ by(auto simp add: new_document_def new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap is_OK_returns_result_I
+ elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_document_ptr_not_in_heap:
+ assumes "h \<turnstile> new_document \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr"
+ shows "new_document_ptr |\<notin>| document_ptr_kinds h"
+ using assms new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_not_in_heap
+ by(auto simp add: new_document_def split: prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_document_new_ptr:
+ assumes "h \<turnstile> new_document \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_document_ptr|}"
+ using assms new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_new_ptr
+ by(auto simp add: new_document_def split: prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_document_is_document_ptr:
+ assumes "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr"
+ shows "is_document_ptr new_document_ptr"
+ using assms new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_is_document_ptr
+ by(auto simp add: new_document_def elim!: bind_returns_result_E split: prod.splits)
+
+lemma new_document_doctype:
+ assumes "h \<turnstile> new_document \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr"
+ shows "h' \<turnstile> get_M new_document_ptr doctype \<rightarrow>\<^sub>r ''''"
+ using assms
+ by(auto simp add: get_M_defs new_document_def new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def
+ split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_document_document_element:
+ assumes "h \<turnstile> new_document \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr"
+ shows "h' \<turnstile> get_M new_document_ptr document_element \<rightarrow>\<^sub>r None"
+ using assms
+ by(auto simp add: get_M_defs new_document_def new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def
+ split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_document_disconnected_nodes:
+ assumes "h \<turnstile> new_document \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr"
+ shows "h' \<turnstile> get_M new_document_ptr disconnected_nodes \<rightarrow>\<^sub>r []"
+ using assms
+ by(auto simp add: get_M_defs new_document_def new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def
+ split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+
+lemma new_document_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr
+ \<Longrightarrow> ptr \<noteq> cast new_document_ptr \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_document_def ObjectMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_document_get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr getter) h h'"
+ by(auto simp add: new_document_def NodeMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_document_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_document_def ElementMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_document_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr getter) h h'"
+ by(auto simp add: new_document_def CharacterDataMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_document_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> ptr \<noteq> new_document_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_document_def get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+
+
+subsection \<open>Modified Heaps\<close>
+
+lemma get_document_ptr_simp [simp]:
+ "get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)
+ = (if ptr = cast document_ptr then cast obj else get document_ptr h)"
+ by(auto simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def split: option.splits Option.bind_splits)
+
+lemma document_ptr_kidns_simp [simp]:
+ "document_ptr_kinds (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)
+ = document_ptr_kinds h |\<union>| (if is_document_ptr_kind ptr then {|the (cast ptr)|} else {||})"
+ by(auto simp add: document_ptr_kinds_def split: option.splits)
+
+lemma type_wf_put_I:
+ assumes "type_wf h"
+ assumes "CharacterDataClass.type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "is_document_ptr_kind ptr \<Longrightarrow> is_document_kind obj"
+ shows "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ using assms
+ by(auto simp add: type_wf_defs is_document_kind_def split: option.splits)
+
+lemma type_wf_put_ptr_not_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<notin>| object_ptr_kinds h"
+ shows "type_wf h"
+ using assms
+ by(auto simp add: type_wf_defs elim!: CharacterDataMonad.type_wf_put_ptr_not_in_heap_E
+ split: option.splits if_splits)
+
+lemma type_wf_put_ptr_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ assumes "CharacterDataClass.type_wf h"
+ assumes "is_document_ptr_kind ptr \<Longrightarrow> is_document_kind (the (get ptr h))"
+ shows "type_wf h"
+ using assms
+ apply(auto simp add: type_wf_defs elim!: CharacterDataMonad.type_wf_put_ptr_in_heap_E
+ split: option.splits if_splits)[1]
+ by (metis (no_types, lifting) CharacterDataClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf bind.bind_lunit get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ is_document_kind_def notin_fset option.exhaust_sel)
+
+
+
+subsection \<open>Preserving Types\<close>
+
+lemma new_element_type_wf_preserved [simp]:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: new_element_def new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ DocumentClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ DocumentClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e DocumentClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ is_node_kind_def element_ptrs_def
+ elim!: bind_returns_heap_E type_wf_put_ptr_not_in_heap_E
+ intro!: type_wf_put_I CharacterDataMonad.type_wf_put_I ElementMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I
+ split: if_splits)[1]
+ apply fastforce
+ by (metis Suc_n_not_le_n element_ptr.sel(1) element_ptrs_def fMax_ge ffmember_filter
+ fimage_eqI is_element_ptr_ref)
+
+lemma new_element_is_l_new_element [instances]:
+ "l_new_element type_wf"
+ using l_new_element.intro new_element_type_wf_preserved
+ by blast
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_tag_name_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr tag_name_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: ElementMonad.put_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ DocumentClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ DocumentClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e DocumentClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ is_node_kind_def
+ dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I CharacterDataMonad.type_wf_put_I ElementMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs NodeClass.type_wf_defs
+ ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply (metis NodeClass.a_type_wf_def NodeClass.get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_type_wf ObjectClass.a_type_wf_def
+ bind.bind_lzero finite_set_in get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def l_type_wf_def\<^sub>N\<^sub>o\<^sub>d\<^sub>e.a_type_wf_def option.collapse
+ option.distinct(1) option.simps(3))
+ by (metis fmember.rep_eq)
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_child_nodes_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr child_nodes_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: ElementMonad.put_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ DocumentClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ DocumentClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e DocumentClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ is_node_kind_def
+ dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I CharacterDataMonad.type_wf_put_I ElementMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply (metis NodeClass.a_type_wf_def NodeClass.get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_type_wf ObjectClass.a_type_wf_def
+ bind.bind_lzero finite_set_in get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def l_type_wf_def\<^sub>N\<^sub>o\<^sub>d\<^sub>e.a_type_wf_def option.collapse
+ option.distinct(1) option.simps(3))
+ by (metis fmember.rep_eq)
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_attrs_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr attrs_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: ElementMonad.put_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ DocumentClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ DocumentClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e DocumentClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ is_node_kind_def
+ dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I CharacterDataMonad.type_wf_put_I ElementMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply (metis NodeClass.a_type_wf_def NodeClass.get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_type_wf ObjectClass.a_type_wf_def
+ bind.bind_lzero finite_set_in get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def l_type_wf_def\<^sub>N\<^sub>o\<^sub>d\<^sub>e.a_type_wf_def option.collapse
+ option.distinct(1) option.simps(3))
+ by (metis fmember.rep_eq)
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_shadow_root_opt_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr shadow_root_opt_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: ElementMonad.put_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ DocumentClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ DocumentClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e DocumentClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ is_node_kind_def
+ dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I CharacterDataMonad.type_wf_put_I ElementMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply (metis NodeClass.a_type_wf_def NodeClass.get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_type_wf ObjectClass.a_type_wf_def
+ bind.bind_lzero finite_set_in get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def l_type_wf_def\<^sub>N\<^sub>o\<^sub>d\<^sub>e.a_type_wf_def option.collapse
+ option.distinct(1) option.simps(3))
+ by (metis fmember.rep_eq)
+
+lemma new_character_data_type_wf_preserved [simp]:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: ElementMonad.put_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ DocumentClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ DocumentClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e DocumentClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ is_node_kind_def
+ new_character_data_def new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ dest!: get_heap_E
+ elim!: bind_returns_heap_E2 bind_returns_heap_E type_wf_put_ptr_not_in_heap_E
+ intro!: type_wf_put_I CharacterDataMonad.type_wf_put_I ElementMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I)[1]
+ by (meson new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_ptr_not_in_heap)
+
+lemma new_character_data_is_l_new_character_data [instances]:
+ "l_new_character_data type_wf"
+ using l_new_character_data.intro new_character_data_type_wf_preserved
+ by blast
+
+lemma put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_val_type_wf_preserved [simp]:
+ "h \<turnstile> put_M character_data_ptr val_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: CharacterDataMonad.put_M_defs put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ DocumentClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ DocumentClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e DocumentClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t is_node_kind_def
+ dest!: get_heap_E elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I CharacterDataMonad.type_wf_put_I ElementMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_node_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs CharacterDataMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply (metis bind.bind_lzero finite_set_in get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def option.distinct(1) option.exhaust_sel)
+ by (metis finite_set_in)
+
+
+lemma new_document_type_wf_preserved [simp]: "h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: new_document_def new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ DocumentClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ DocumentClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e DocumentClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ is_node_ptr_kind_none
+ elim!: bind_returns_heap_E type_wf_put_ptr_not_in_heap_E
+ intro!: type_wf_put_I ElementMonad.type_wf_put_I CharacterDataMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I
+ split: if_splits)[1]
+ apply(auto simp add: type_wf_defs ElementClass.type_wf_defs CharacterDataClass.type_wf_defs
+ NodeClass.type_wf_defs ObjectClass.type_wf_defs is_document_kind_def
+ split: option.splits)[1]
+ using document_ptrs_def apply fastforce
+ apply (simp add: is_document_kind_def)
+ apply (metis Suc_n_not_le_n document_ptr.sel(1) document_ptrs_def fMax_ge ffmember_filter
+ fimage_eqI is_document_ptr_ref)
+ done
+
+locale l_new_document = l_type_wf +
+ assumes new_document_types_preserved: "h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+
+lemma new_document_is_l_new_document [instances]: "l_new_document type_wf"
+ using l_new_document.intro new_document_type_wf_preserved
+ by blast
+
+lemma put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_doctype_type_wf_preserved [simp]:
+ "h \<turnstile> put_M document_ptr doctype_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: put_M_defs put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I CharacterDataMonad.type_wf_put_I
+ ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: get_M_defs)[1]
+ by (metis (mono_tags) error_returns_result finite_set_in option.exhaust_sel option.simps(4))
+
+lemma put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_document_element_type_wf_preserved [simp]:
+ "h \<turnstile> put_M document_ptr document_element_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: put_M_defs put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ DocumentClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+ DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ DocumentClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+ DocumentClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t is_node_ptr_kind_none
+ cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_none is_document_kind_def
+ dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I CharacterDataMonad.type_wf_put_I
+ ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I
+ ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: get_M_defs is_document_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs
+ split: option.splits)[1]
+ by (metis finite_set_in)
+
+lemma put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_disconnected_nodes_type_wf_preserved [simp]:
+ "h \<turnstile> put_M document_ptr disconnected_nodes_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: put_M_defs put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ DocumentClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a
+ DocumentClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ DocumentClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+ DocumentClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ is_node_ptr_kind_none
+ cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_none is_document_kind_def
+ dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I CharacterDataMonad.type_wf_put_I
+ ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I
+ ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_document_kind_def get_M_defs type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ by (metis finite_set_in)
+
+lemma document_ptr_kinds_small:
+ assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ shows "document_ptr_kinds h = document_ptr_kinds h'"
+ by(simp add: document_ptr_kinds_def preserved_def object_ptr_kinds_preserved_small[OF assms])
+
+lemma document_ptr_kinds_preserved:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h'. \<forall>w \<in> SW. h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<longrightarrow> (\<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h')"
+ shows "document_ptr_kinds h = document_ptr_kinds h'"
+ using writes_small_big[OF assms]
+ apply(simp add: reflp_def transp_def preserved_def document_ptr_kinds_def)
+ by (metis assms object_ptr_kinds_preserved)
+
+lemma type_wf_preserved_small:
+ assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ assumes "\<And>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
+ assumes "\<And>element_ptr. preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr RElement.nothing) h h'"
+ assumes "\<And>character_data_ptr. preserved
+ (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr RCharacterData.nothing) h h'"
+ assumes "\<And>document_ptr. preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr RDocument.nothing) h h'"
+ shows "DocumentClass.type_wf h = DocumentClass.type_wf h'"
+ using type_wf_preserved_small[OF assms(1) assms(2) assms(3) assms(4)]
+ allI[OF assms(5), of id, simplified] document_ptr_kinds_small[OF assms(1)]
+ apply(auto simp add: type_wf_defs )[1]
+ apply(auto simp add: type_wf_defs preserved_def get_M_defs document_ptr_kinds_small[OF assms(1)]
+ split: option.splits)[1]
+ apply force
+ apply(auto simp add: type_wf_defs preserved_def get_M_defs document_ptr_kinds_small[OF assms(1)]
+ split: option.splits)[1]
+ by force
+
+lemma type_wf_preserved:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>element_ptr. preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr RElement.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>character_data_ptr. preserved
+ (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr RCharacterData.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>document_ptr. preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr RDocument.nothing) h h'"
+ shows "DocumentClass.type_wf h = DocumentClass.type_wf h'"
+proof -
+ have "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> DocumentClass.type_wf h = DocumentClass.type_wf h'"
+ using assms type_wf_preserved_small by fast
+ with assms(1) assms(2) show ?thesis
+ apply(rule writes_small_big)
+ by(auto simp add: reflp_def transp_def)
+qed
+
+lemma type_wf_drop: "type_wf h \<Longrightarrow> type_wf (Heap (fmdrop ptr (the_heap h)))"
+ apply(auto simp add: type_wf_defs)[1]
+ using type_wf_drop
+ apply blast
+ by (metis (no_types, lifting) CharacterDataClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf CharacterDataMonad.type_wf_drop
+ document_ptr_kinds_commutes finite_set_in fmlookup_drop get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def heap.sel)
+end
diff --git a/thys/Core_SC_DOM/common/monads/ElementMonad.thy b/thys/Core_SC_DOM/common/monads/ElementMonad.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/monads/ElementMonad.thy
@@ -0,0 +1,445 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Element\<close>
+text\<open>In this theory, we introduce the monadic method setup for the Element class.\<close>
+theory ElementMonad
+ imports
+ NodeMonad
+ "ElementClass"
+begin
+
+type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+ 'shadow_root_ptr, 'Object, 'Node, 'Element,'result) dom_prog
+ = "((_) heap, exception, 'result) prog"
+register_default_tvars "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr,
+ 'document_ptr, 'shadow_root_ptr, 'Object, 'Node, 'Element,'result) dom_prog"
+
+
+global_interpretation l_ptr_kinds_M element_ptr_kinds defines element_ptr_kinds_M = a_ptr_kinds_M .
+lemmas element_ptr_kinds_M_defs = a_ptr_kinds_M_def
+
+
+lemma element_ptr_kinds_M_eq:
+ assumes "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ shows "|h \<turnstile> element_ptr_kinds_M|\<^sub>r = |h' \<turnstile> element_ptr_kinds_M|\<^sub>r"
+ using assms
+ by(auto simp add: element_ptr_kinds_M_defs node_ptr_kinds_M_defs element_ptr_kinds_def)
+
+lemma element_ptr_kinds_M_reads:
+ "reads (\<Union>element_ptr. {preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t element_ptr RObject.nothing)}) element_ptr_kinds_M h h'"
+ apply (simp add: reads_def node_ptr_kinds_M_defs element_ptr_kinds_M_defs element_ptr_kinds_def
+ node_ptr_kinds_M_reads preserved_def cong del: image_cong_simp)
+ apply (metis (mono_tags, hide_lams) node_ptr_kinds_small old.unit.exhaust preserved_def)
+ done
+
+global_interpretation l_dummy defines get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t = "l_get_M.a_get_M get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t" .
+lemma get_M_is_l_get_M: "l_get_M get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t type_wf element_ptr_kinds"
+ apply(simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_type_wf l_get_M_def)
+ by (metis (no_types, lifting) ObjectClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf ObjectClass.type_wf_defs
+ bind_eq_Some_conv bind_eq_Some_conv element_ptr_kinds_commutes get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def node_ptr_kinds_commutes option.simps(3))
+lemmas get_M_defs = get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def[unfolded l_get_M.a_get_M_def[OF get_M_is_l_get_M]]
+
+adhoc_overloading get_M get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+locale l_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas = l_type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+begin
+sublocale l_get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_lemmas by unfold_locales
+
+interpretation l_get_M get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t type_wf element_ptr_kinds
+ apply(unfold_locales)
+ apply (simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_type_wf local.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+ by (meson ElementMonad.get_M_is_l_get_M l_get_M_def)
+lemmas get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok = get_M_ok[folded get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def]
+lemmas get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap = get_M_ptr_in_heap[folded get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def]
+end
+
+global_interpretation l_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas type_wf by unfold_locales
+
+
+global_interpretation l_put_M type_wf element_ptr_kinds get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ rewrites "a_get_M = get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t"
+ defines put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t = a_put_M
+ apply (simp add: get_M_is_l_get_M l_put_M_def)
+ by (simp add: get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+
+lemmas put_M_defs = a_put_M_def
+adhoc_overloading put_M put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+
+locale l_put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas = l_type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+begin
+sublocale l_put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_lemmas by unfold_locales
+
+interpretation l_put_M type_wf element_ptr_kinds get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ apply(unfold_locales)
+ apply (simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_type_wf local.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+ by (meson ElementMonad.get_M_is_l_get_M l_get_M_def)
+
+lemmas put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok = put_M_ok[folded put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def]
+end
+
+global_interpretation l_put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas type_wf by unfold_locales
+
+
+lemma element_put_get [simp]:
+ "h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> (\<And>x. getter (setter (\<lambda>_. v) x) = v)
+ \<Longrightarrow> h' \<turnstile> get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr getter \<rightarrow>\<^sub>r v"
+ by(auto simp add: put_M_defs get_M_defs split: option.splits)
+lemma get_M_Element_preserved1 [simp]:
+ "element_ptr \<noteq> element_ptr' \<Longrightarrow> h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr' getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs preserved_def split: option.splits dest: get_heap_E)
+lemma element_put_get_preserved [simp]:
+ "(\<And>x. getter (setter (\<lambda>_. v) x) = getter x) \<Longrightarrow> h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr' getter) h h'"
+ apply(cases "element_ptr = element_ptr'")
+ by(auto simp add: put_M_defs get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_Element_preserved3 [simp]:
+ "(\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ apply(cases "cast element_ptr = object_ptr")
+ by (auto simp add: put_M_defs get_M_defs ObjectMonad.get_M_defs NodeMonad.get_M_defs get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def preserved_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def bind_eq_Some_conv
+ split: option.splits)
+lemma get_M_Element_preserved4 [simp]:
+ "(\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr getter) h h'"
+ apply(cases "cast element_ptr = node_ptr")
+ by(auto simp add: put_M_defs get_M_defs ObjectMonad.get_M_defs NodeMonad.get_M_defs get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def preserved_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def bind_eq_Some_conv
+ split: option.splits)
+
+lemma get_M_Element_preserved5 [simp]:
+ "cast element_ptr \<noteq> node_ptr \<Longrightarrow> h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def NodeMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_Element_preserved6 [simp]:
+ "h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr getter) h h'"
+ apply(cases "cast element_ptr \<noteq> node_ptr")
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def NodeMonad.get_M_defs preserved_def
+ split: option.splits bind_splits dest: get_heap_E)
+
+lemma get_M_Element_preserved7 [simp]:
+ "cast element_ptr \<noteq> node_ptr \<Longrightarrow> h \<turnstile> put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr getter) h h'"
+ by(auto simp add: NodeMonad.put_M_defs get_M_defs get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def NodeMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+
+lemma get_M_Element_preserved8 [simp]:
+ "cast element_ptr \<noteq> object_ptr \<Longrightarrow> h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ ObjectMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_Element_preserved9 [simp]:
+ "h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ apply(cases "cast element_ptr \<noteq> object_ptr")
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ ObjectMonad.get_M_defs preserved_def
+ split: option.splits bind_splits dest: get_heap_E)
+
+lemma get_M_Element_preserved10 [simp]:
+ "cast element_ptr \<noteq> object_ptr \<Longrightarrow> h \<turnstile> put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr getter) h h'"
+ by(auto simp add: ObjectMonad.put_M_defs get_M_defs get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ ObjectMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+
+subsection\<open>Creating Elements\<close>
+
+definition new_element :: "(_, (_) element_ptr) dom_prog"
+ where
+ "new_element = do {
+ h \<leftarrow> get_heap;
+ (new_ptr, h') \<leftarrow> return (new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h);
+ return_heap h';
+ return new_ptr
+ }"
+
+lemma new_element_ok [simp]:
+ "h \<turnstile> ok new_element"
+ by(auto simp add: new_element_def split: prod.splits)
+
+lemma new_element_ptr_in_heap:
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr"
+ shows "new_element_ptr |\<in>| element_ptr_kinds h'"
+ using assms
+ unfolding new_element_def
+ by(auto simp add: new_element_def new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap is_OK_returns_result_I
+ elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_element_ptr_not_in_heap:
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr"
+ shows "new_element_ptr |\<notin>| element_ptr_kinds h"
+ using assms new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_not_in_heap
+ by(auto simp add: new_element_def split: prod.splits elim!: bind_returns_result_E
+ bind_returns_heap_E)
+
+lemma new_element_new_ptr:
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ using assms new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_new_ptr
+ by(auto simp add: new_element_def split: prod.splits elim!: bind_returns_result_E
+ bind_returns_heap_E)
+
+lemma new_element_is_element_ptr:
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr"
+ shows "is_element_ptr new_element_ptr"
+ using assms new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_is_element_ptr
+ by(auto simp add: new_element_def elim!: bind_returns_result_E split: prod.splits)
+
+lemma new_element_child_nodes:
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr"
+ shows "h' \<turnstile> get_M new_element_ptr child_nodes \<rightarrow>\<^sub>r []"
+ using assms
+ by(auto simp add: get_M_defs new_element_def new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def
+ split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_element_tag_name:
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr"
+ shows "h' \<turnstile> get_M new_element_ptr tag_name \<rightarrow>\<^sub>r ''''"
+ using assms
+ by(auto simp add: get_M_defs new_element_def new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def
+ split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_element_attrs:
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr"
+ shows "h' \<turnstile> get_M new_element_ptr attrs \<rightarrow>\<^sub>r fmempty"
+ using assms
+ by(auto simp add: get_M_defs new_element_def new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def
+ split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_element_shadow_root_opt:
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr"
+ shows "h' \<turnstile> get_M new_element_ptr shadow_root_opt \<rightarrow>\<^sub>r None"
+ using assms
+ by(auto simp add: get_M_defs new_element_def new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def
+ split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_element_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> ptr \<noteq> cast new_element_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_element_def ObjectMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_element_get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> ptr \<noteq> cast new_element_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr getter) h h'"
+ by(auto simp add: new_element_def NodeMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_element_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> ptr \<noteq> new_element_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_element_def get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+subsection\<open>Modified Heaps\<close>
+
+lemma get_Element_ptr_simp [simp]:
+ "get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)
+ = (if ptr = cast element_ptr then cast obj else get element_ptr h)"
+ by(auto simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def split: option.splits Option.bind_splits)
+
+
+lemma element_ptr_kinds_simp [simp]:
+ "element_ptr_kinds (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)
+ = element_ptr_kinds h |\<union>| (if is_element_ptr_kind ptr then {|the (cast ptr)|} else {||})"
+ by(auto simp add: element_ptr_kinds_def is_node_ptr_kind_def split: option.splits)
+
+lemma type_wf_put_I:
+ assumes "type_wf h"
+ assumes "NodeClass.type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "is_element_ptr_kind ptr \<Longrightarrow> is_element_kind obj"
+ shows "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ using assms
+ by(auto simp add: type_wf_defs split: option.splits)
+
+lemma type_wf_put_ptr_not_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<notin>| object_ptr_kinds h"
+ shows "type_wf h"
+ using assms
+ apply(auto simp add: type_wf_defs elim!: NodeMonad.type_wf_put_ptr_not_in_heap_E
+ split: option.splits if_splits)[1]
+ using assms(2) node_ptr_kinds_commutes by blast
+
+lemma type_wf_put_ptr_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ assumes "NodeClass.type_wf h"
+ assumes "is_element_ptr_kind ptr \<Longrightarrow> is_element_kind (the (get ptr h))"
+ shows "type_wf h"
+ using assms
+ apply(auto simp add: type_wf_defs split: option.splits if_splits)[1]
+ by (metis (no_types, lifting) NodeClass.l_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas_axioms assms(2) bind.bind_lunit
+ cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_inv cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_inv finite_set_in get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ l_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf option.collapse)
+
+subsection\<open>Preserving Types\<close>
+
+lemma new_element_type_wf_preserved [simp]: "h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: type_wf_defs NodeClass.type_wf_defs ObjectClass.type_wf_defs new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ new_element_def Let_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ split: prod.splits if_splits elim!: bind_returns_heap_E)[1]
+ apply (metis element_ptr_kinds_commutes element_ptrs_def fempty_iff ffmember_filter finite_set_in
+ is_element_ptr_ref)
+ apply (metis element_ptrs_def fempty_iff ffmember_filter finite_set_in is_element_ptr_ref)
+ apply (metis (no_types, lifting) Suc_n_not_le_n element_ptr.sel(1) element_ptr_kinds_commutes
+ element_ptrs_def fMax_ge ffmember_filter fimage_eqI is_element_ptr_ref notin_fset)
+ apply (metis (no_types, lifting) Suc_n_not_le_n element_ptr.sel(1) element_ptrs_def
+ fMax_ge ffmember_filter fimage_eqI finite_set_in is_element_ptr_ref)
+ done
+
+locale l_new_element = l_type_wf +
+ assumes new_element_types_preserved: "h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+
+lemma new_element_is_l_new_element: "l_new_element type_wf"
+ using l_new_element.intro new_element_type_wf_preserved
+ by blast
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_tag_name_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr tag_name_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: type_wf_defs NodeClass.type_wf_defs ObjectClass.type_wf_defs
+ Let_def put_M_defs get_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ split: prod.splits option.splits Option.bind_splits elim!: bind_returns_heap_E)[1]
+ apply (metis finite_set_in option.inject)
+ apply (metis cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_inv finite_set_in option.sel)
+ done
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_child_nodes_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr child_nodes_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: type_wf_defs NodeClass.type_wf_defs ObjectClass.type_wf_defs
+ Let_def put_M_defs get_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ split: prod.splits option.splits Option.bind_splits elim!: bind_returns_heap_E)[1]
+ apply (metis finite_set_in option.inject)
+ apply (metis cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_inv finite_set_in option.sel)
+ done
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_attrs_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr attrs_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: type_wf_defs NodeClass.type_wf_defs ObjectClass.type_wf_defs Let_def
+ put_M_defs get_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ split: prod.splits option.splits Option.bind_splits elim!: bind_returns_heap_E)[1]
+ apply (metis finite_set_in option.inject)
+ apply (metis cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_inv finite_set_in option.sel)
+ done
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_shadow_root_opt_type_wf_preserved [simp]:
+ "h \<turnstile> put_M element_ptr shadow_root_opt_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: type_wf_defs NodeClass.type_wf_defs ObjectClass.type_wf_defs
+ Let_def put_M_defs get_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ split: prod.splits option.splits Option.bind_splits elim!: bind_returns_heap_E)[1]
+ apply (metis finite_set_in option.inject)
+ apply (metis cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_inv finite_set_in option.sel)
+ done
+
+lemma put_M_pointers_preserved:
+ assumes "h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms
+ apply(auto simp add: put_M_defs put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ elim!: bind_returns_heap_E2 dest!: get_heap_E)[1]
+ by (meson get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap is_OK_returns_result_I)
+
+lemma element_ptr_kinds_preserved:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h'. \<forall>w \<in> SW. h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<longrightarrow> (\<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h')"
+ shows "element_ptr_kinds h = element_ptr_kinds h'"
+ using writes_small_big[OF assms]
+ apply(simp add: reflp_def transp_def preserved_def element_ptr_kinds_def)
+ by (metis assms node_ptr_kinds_preserved)
+
+
+lemma element_ptr_kinds_small:
+ assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ shows "element_ptr_kinds h = element_ptr_kinds h'"
+ by(simp add: element_ptr_kinds_def node_ptr_kinds_def preserved_def
+ object_ptr_kinds_preserved_small[OF assms])
+
+lemma type_wf_preserved_small:
+ assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ assumes "\<And>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
+ assumes "\<And>element_ptr. preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr RElement.nothing) h h'"
+ shows "type_wf h = type_wf h'"
+ using type_wf_preserved_small[OF assms(1) assms(2)] allI[OF assms(3), of id, simplified]
+ apply(auto simp add: type_wf_defs )[1]
+ apply(auto simp add: preserved_def get_M_defs element_ptr_kinds_small[OF assms(1)]
+ split: option.splits,force)[1]
+ by(auto simp add: preserved_def get_M_defs element_ptr_kinds_small[OF assms(1)]
+ split: option.splits,force)
+
+lemma type_wf_preserved:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>element_ptr. preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr RElement.nothing) h h'"
+ shows "type_wf h = type_wf h'"
+proof -
+ have "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ using assms type_wf_preserved_small by fast
+ with assms(1) assms(2) show ?thesis
+ apply(rule writes_small_big)
+ by(auto simp add: reflp_def transp_def)
+qed
+
+lemma type_wf_drop: "type_wf h \<Longrightarrow> type_wf (Heap (fmdrop ptr (the_heap h)))"
+ apply(auto simp add: type_wf_defs NodeClass.type_wf_defs ObjectClass.type_wf_defs
+ node_ptr_kinds_def object_ptr_kinds_def is_node_ptr_kind_def
+ get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def)[1]
+ apply (metis (no_types, lifting) element_ptr_kinds_commutes finite_set_in fmdom_notD fmdom_notI
+ fmlookup_drop heap.sel node_ptr_kinds_commutes o_apply object_ptr_kinds_def)
+ by (metis element_ptr_kinds_commutes fmdom_notI fmdrop_lookup heap.sel node_ptr_kinds_commutes
+ o_apply object_ptr_kinds_def)
+
+end
diff --git a/thys/Core_SC_DOM/common/monads/NodeMonad.thy b/thys/Core_SC_DOM/common/monads/NodeMonad.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/monads/NodeMonad.thy
@@ -0,0 +1,218 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Node\<close>
+text\<open>In this theory, we introduce the monadic method setup for the Node class.\<close>
+theory NodeMonad
+ imports
+ ObjectMonad
+ "../classes/NodeClass"
+begin
+
+type_synonym ('object_ptr, 'node_ptr, 'Object, 'Node, 'result) dom_prog
+ = "((_) heap, exception, 'result) prog"
+register_default_tvars "('object_ptr, 'node_ptr, 'Object, 'Node, 'result) dom_prog"
+
+
+global_interpretation l_ptr_kinds_M node_ptr_kinds defines node_ptr_kinds_M = a_ptr_kinds_M .
+lemmas node_ptr_kinds_M_defs = a_ptr_kinds_M_def
+
+lemma node_ptr_kinds_M_eq:
+ assumes "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ shows "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using assms
+ by(auto simp add: node_ptr_kinds_M_defs object_ptr_kinds_M_defs node_ptr_kinds_def)
+
+
+global_interpretation l_dummy defines get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e = "l_get_M.a_get_M get\<^sub>N\<^sub>o\<^sub>d\<^sub>e" .
+lemma get_M_is_l_get_M: "l_get_M get\<^sub>N\<^sub>o\<^sub>d\<^sub>e type_wf node_ptr_kinds"
+ apply(simp add: get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_type_wf l_get_M_def)
+ by (metis ObjectClass.a_type_wf_def ObjectClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf bind_eq_None_conv get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ node_ptr_kinds_commutes option.simps(3))
+lemmas get_M_defs = get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def[unfolded l_get_M.a_get_M_def[OF get_M_is_l_get_M]]
+
+adhoc_overloading get_M get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+
+locale l_get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_lemmas = l_type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+begin
+sublocale l_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas by unfold_locales
+
+interpretation l_get_M get\<^sub>N\<^sub>o\<^sub>d\<^sub>e type_wf node_ptr_kinds
+ apply(unfold_locales)
+ apply (simp add: get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_type_wf local.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e)
+ by (meson NodeMonad.get_M_is_l_get_M l_get_M_def)
+lemmas get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_ok = get_M_ok[folded get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def]
+end
+
+global_interpretation l_get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_lemmas type_wf by unfold_locales
+
+lemma node_ptr_kinds_M_reads:
+ "reads (\<Union>object_ptr. {preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing)}) node_ptr_kinds_M h h'"
+ using object_ptr_kinds_M_reads
+ apply (simp add: reads_def node_ptr_kinds_M_defs node_ptr_kinds_def
+ object_ptr_kinds_M_reads preserved_def)
+ by (smt object_ptr_kinds_preserved_small preserved_def unit_all_impI)
+
+global_interpretation l_put_M type_wf node_ptr_kinds get\<^sub>N\<^sub>o\<^sub>d\<^sub>e put\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+ rewrites "a_get_M = get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e"
+ defines put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e = a_put_M
+ apply (simp add: get_M_is_l_get_M l_put_M_def)
+ by (simp add: get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+
+lemmas put_M_defs = a_put_M_def
+adhoc_overloading put_M put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+
+
+locale l_put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_lemmas = l_type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+begin
+sublocale l_put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas by unfold_locales
+
+interpretation l_put_M type_wf node_ptr_kinds get\<^sub>N\<^sub>o\<^sub>d\<^sub>e put\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+ apply(unfold_locales)
+ apply (simp add: get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_type_wf local.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e)
+ by (meson NodeMonad.get_M_is_l_get_M l_get_M_def)
+lemmas put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_ok = put_M_ok[folded put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def]
+end
+
+global_interpretation l_put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e_lemmas type_wf by unfold_locales
+
+lemma get_M_Object_preserved1 [simp]:
+ "(\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x)) \<Longrightarrow> h \<turnstile> put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ apply(cases "cast node_ptr = object_ptr")
+ by(auto simp add: put_M_defs get_M_defs ObjectMonad.get_M_defs get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def preserved_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+ bind_eq_Some_conv
+ split: option.splits)
+
+lemma get_M_Object_preserved2 [simp]:
+ "cast node_ptr \<noteq> object_ptr \<Longrightarrow> h \<turnstile> put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def ObjectMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_Object_preserved3 [simp]:
+ "h \<turnstile> put_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> (\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ apply(cases "cast node_ptr \<noteq> object_ptr")
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def ObjectMonad.get_M_defs preserved_def
+ split: option.splits bind_splits dest: get_heap_E)
+
+lemma get_M_Object_preserved4 [simp]:
+ "cast node_ptr \<noteq> object_ptr \<Longrightarrow> h \<turnstile> put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr getter) h h'"
+ by(auto simp add: ObjectMonad.put_M_defs get_M_defs get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def ObjectMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+
+subsection\<open>Modified Heaps\<close>
+
+lemma get_node_ptr_simp [simp]:
+ "get\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h) = (if ptr = cast node_ptr then cast obj else get node_ptr h)"
+ by(auto simp add: get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+
+lemma node_ptr_kinds_simp [simp]:
+ "node_ptr_kinds (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)
+ = node_ptr_kinds h |\<union>| (if is_node_ptr_kind ptr then {|the (cast ptr)|} else {||})"
+ by(auto simp add: node_ptr_kinds_def)
+
+lemma type_wf_put_I:
+ assumes "type_wf h"
+ assumes "ObjectClass.type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "is_node_ptr_kind ptr \<Longrightarrow> is_node_kind obj"
+ shows "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ using assms
+ apply(auto simp add: type_wf_defs split: option.splits)[1]
+ using cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_none is_node_kind_def apply blast
+ using cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_none is_node_kind_def apply blast
+ done
+
+lemma type_wf_put_ptr_not_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<notin>| object_ptr_kinds h"
+ shows "type_wf h"
+ using assms
+ by(auto simp add: type_wf_defs elim!: ObjectMonad.type_wf_put_ptr_not_in_heap_E
+ split: option.splits if_splits)
+
+lemma type_wf_put_ptr_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ assumes "ObjectClass.type_wf h"
+ assumes "is_node_ptr_kind ptr \<Longrightarrow> is_node_kind (the (get ptr h))"
+ shows "type_wf h"
+ using assms
+ apply(auto simp add: type_wf_defs split: option.splits if_splits)[1]
+ by (metis ObjectClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf bind.bind_lunit finite_set_in get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def is_node_kind_def option.exhaust_sel)
+
+
+subsection\<open>Preserving Types\<close>
+
+lemma node_ptr_kinds_small:
+ assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ shows "node_ptr_kinds h = node_ptr_kinds h'"
+ by(simp add: node_ptr_kinds_def preserved_def object_ptr_kinds_preserved_small[OF assms])
+
+lemma node_ptr_kinds_preserved:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h'. \<forall>w \<in> SW. h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<longrightarrow> (\<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h')"
+ shows "node_ptr_kinds h = node_ptr_kinds h'"
+ using writes_small_big[OF assms]
+ apply(simp add: reflp_def transp_def preserved_def node_ptr_kinds_def)
+ by (metis assms object_ptr_kinds_preserved)
+
+
+lemma type_wf_preserved_small:
+ assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ assumes "\<And>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
+ shows "type_wf h = type_wf h'"
+ using type_wf_preserved allI[OF assms(2), of id, simplified]
+ apply(auto simp add: type_wf_defs)[1]
+ apply(auto simp add: preserved_def get_M_defs node_ptr_kinds_small[OF assms(1)]
+ split: option.splits)[1]
+ apply (metis notin_fset option.simps(3))
+ by(auto simp add: preserved_def get_M_defs node_ptr_kinds_small[OF assms(1)]
+ split: option.splits, force)[1]
+
+lemma type_wf_preserved:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
+ shows "type_wf h = type_wf h'"
+proof -
+ have "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ using assms type_wf_preserved_small by fast
+ with assms(1) assms(2) show ?thesis
+ apply(rule writes_small_big)
+ by(auto simp add: reflp_def transp_def)
+qed
+end
+
diff --git a/thys/Core_SC_DOM/common/monads/ObjectMonad.thy b/thys/Core_SC_DOM/common/monads/ObjectMonad.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/monads/ObjectMonad.thy
@@ -0,0 +1,258 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Object\<close>
+text\<open>In this theory, we introduce the monadic method setup for the Object class.\<close>
+theory ObjectMonad
+ imports
+ BaseMonad
+ "../classes/ObjectClass"
+begin
+
+type_synonym ('object_ptr, 'Object, 'result) dom_prog
+ = "((_) heap, exception, 'result) prog"
+register_default_tvars "('object_ptr, 'Object, 'result) dom_prog"
+
+global_interpretation l_ptr_kinds_M object_ptr_kinds defines object_ptr_kinds_M = a_ptr_kinds_M .
+lemmas object_ptr_kinds_M_defs = a_ptr_kinds_M_def
+
+
+global_interpretation l_dummy defines get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t = "l_get_M.a_get_M get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t" .
+lemma get_M_is_l_get_M: "l_get_M get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t type_wf object_ptr_kinds"
+ by (simp add: a_type_wf_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf l_get_M_def)
+lemmas get_M_defs = get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def[unfolded l_get_M.a_get_M_def[OF get_M_is_l_get_M]]
+
+adhoc_overloading get_M get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+locale l_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas = l_type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+begin
+interpretation l_get_M get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t type_wf object_ptr_kinds
+ apply(unfold_locales)
+ apply (simp add: get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf local.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t)
+ by (simp add: a_type_wf_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf)
+lemmas get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ok = get_M_ok[folded get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def]
+lemmas get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ptr_in_heap = get_M_ptr_in_heap[folded get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def]
+end
+
+global_interpretation l_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas type_wf
+ by (simp add: l_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas_def l_type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_axioms)
+
+lemma object_ptr_kinds_M_reads:
+ "reads (\<Union>object_ptr. {preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing)}) object_ptr_kinds_M h h'"
+ apply(auto simp add: object_ptr_kinds_M_defs get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf type_wf_defs reads_def
+ preserved_def get_M_defs
+ split: option.splits)[1]
+ using a_type_wf_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf by blast+
+
+
+global_interpretation l_put_M type_wf object_ptr_kinds get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ rewrites "a_get_M = get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t"
+ defines put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t = a_put_M
+ apply (simp add: get_M_is_l_get_M l_put_M_def)
+ by (simp add: get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def)
+lemmas put_M_defs = a_put_M_def
+adhoc_overloading put_M put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+
+locale l_put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas = l_type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+begin
+interpretation l_put_M type_wf object_ptr_kinds get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ apply(unfold_locales)
+ using get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf l_type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t local.l_type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_axioms apply blast
+ by (simp add: a_type_wf_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf)
+lemmas put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ok = put_M_ok[folded put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def]
+lemmas put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ptr_in_heap = put_M_ptr_in_heap[folded put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def]
+end
+
+global_interpretation l_put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas type_wf
+ by (simp add: l_put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas_def l_type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_axioms)
+
+
+definition check_in_heap :: "(_) object_ptr \<Rightarrow> (_, unit) dom_prog"
+ where
+ "check_in_heap ptr = do {
+ h \<leftarrow> get_heap;
+ (if ptr |\<in>| object_ptr_kinds h then
+ return ()
+ else
+ error SegmentationFault
+ )}"
+
+lemma check_in_heap_ptr_in_heap: "ptr |\<in>| object_ptr_kinds h \<longleftrightarrow> h \<turnstile> ok (check_in_heap ptr)"
+ by(auto simp add: check_in_heap_def)
+lemma check_in_heap_pure [simp]: "pure (check_in_heap ptr) h"
+ by(auto simp add: check_in_heap_def intro!: bind_pure_I)
+lemma check_in_heap_is_OK [simp]:
+ "ptr |\<in>| object_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (check_in_heap ptr \<bind> f) = h \<turnstile> ok (f ())"
+ by(simp add: check_in_heap_def)
+lemma check_in_heap_returns_result [simp]:
+ "ptr |\<in>| object_ptr_kinds h \<Longrightarrow> h \<turnstile> (check_in_heap ptr \<bind> f) \<rightarrow>\<^sub>r x = h \<turnstile> f () \<rightarrow>\<^sub>r x"
+ by(simp add: check_in_heap_def)
+lemma check_in_heap_returns_heap [simp]:
+ "ptr |\<in>| object_ptr_kinds h \<Longrightarrow> h \<turnstile> (check_in_heap ptr \<bind> f) \<rightarrow>\<^sub>h h' = h \<turnstile> f () \<rightarrow>\<^sub>h h'"
+ by(simp add: check_in_heap_def)
+
+lemma check_in_heap_reads:
+ "reads {preserved (get_M object_ptr nothing)} (check_in_heap object_ptr) h h'"
+ apply(simp add: check_in_heap_def reads_def preserved_def)
+ by (metis a_type_wf_def get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ok get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ptr_in_heap is_OK_returns_result_E
+ is_OK_returns_result_I unit_all_impI)
+
+subsection\<open>Invoke\<close>
+
+fun invoke_rec :: "(((_) object_ptr \<Rightarrow> bool) \<times> ((_) object_ptr \<Rightarrow> 'args
+ \<Rightarrow> (_, 'result) dom_prog)) list \<Rightarrow> (_) object_ptr \<Rightarrow> 'args
+ \<Rightarrow> (_, 'result) dom_prog"
+ where
+ "invoke_rec ((P, f)#xs) ptr args = (if P ptr then f ptr args else invoke_rec xs ptr args)"
+ | "invoke_rec [] ptr args = error InvokeError"
+
+definition invoke :: "(((_) object_ptr \<Rightarrow> bool) \<times> ((_) object_ptr \<Rightarrow> 'args
+ \<Rightarrow> (_, 'result) dom_prog)) list
+ \<Rightarrow> (_) object_ptr \<Rightarrow> 'args \<Rightarrow> (_, 'result) dom_prog"
+ where
+ "invoke xs ptr args = do { check_in_heap ptr; invoke_rec xs ptr args}"
+
+lemma invoke_split: "P (invoke ((Pred, f) # xs) ptr args) =
+ ((\<not>(Pred ptr) \<longrightarrow> P (invoke xs ptr args))
+ \<and> (Pred ptr \<longrightarrow> P (do {check_in_heap ptr; f ptr args})))"
+ by(simp add: invoke_def)
+
+lemma invoke_split_asm: "P (invoke ((Pred, f) # xs) ptr args) =
+ (\<not>((\<not>(Pred ptr) \<and> (\<not> P (invoke xs ptr args)))
+ \<or> (Pred ptr \<and> (\<not> P (do {check_in_heap ptr; f ptr args})))))"
+ by(simp add: invoke_def)
+lemmas invoke_splits = invoke_split invoke_split_asm
+
+lemma invoke_ptr_in_heap: "h \<turnstile> ok (invoke xs ptr args) \<Longrightarrow> ptr |\<in>| object_ptr_kinds h"
+ by (metis bind_is_OK_E check_in_heap_ptr_in_heap invoke_def is_OK_returns_heap_I)
+
+lemma invoke_pure [simp]: "pure (invoke [] ptr args) h"
+ by(auto simp add: invoke_def intro!: bind_pure_I)
+
+lemma invoke_is_OK [simp]:
+ "ptr |\<in>| object_ptr_kinds h \<Longrightarrow> Pred ptr
+ \<Longrightarrow> h \<turnstile> ok (invoke ((Pred, f) # xs) ptr args) = h \<turnstile> ok (f ptr args)"
+ by(simp add: invoke_def)
+lemma invoke_returns_result [simp]:
+ "ptr |\<in>| object_ptr_kinds h \<Longrightarrow> Pred ptr
+ \<Longrightarrow> h \<turnstile> (invoke ((Pred, f) # xs) ptr args) \<rightarrow>\<^sub>r x = h \<turnstile> f ptr args \<rightarrow>\<^sub>r x"
+ by(simp add: invoke_def)
+lemma invoke_returns_heap [simp]:
+ "ptr |\<in>| object_ptr_kinds h \<Longrightarrow> Pred ptr
+ \<Longrightarrow> h \<turnstile> (invoke ((Pred, f) # xs) ptr args) \<rightarrow>\<^sub>h h' = h \<turnstile> f ptr args \<rightarrow>\<^sub>h h'"
+ by(simp add: invoke_def)
+
+lemma invoke_not [simp]: "\<not>Pred ptr \<Longrightarrow> invoke ((Pred, f) # xs) ptr args = invoke xs ptr args"
+ by(auto simp add: invoke_def)
+
+lemma invoke_empty [simp]: "\<not>h \<turnstile> ok (invoke [] ptr args)"
+ by(auto simp add: invoke_def check_in_heap_def)
+
+lemma invoke_empty_reads [simp]: "\<forall>P \<in> S. reflp P \<and> transp P \<Longrightarrow> reads S (invoke [] ptr args) h h'"
+ apply(simp add: invoke_def reads_def preserved_def)
+ by (meson bind_returns_result_E error_returns_result)
+
+
+subsection\<open>Modified Heaps\<close>
+
+lemma get_object_ptr_simp [simp]:
+ "get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h) = (if ptr = object_ptr then Some obj else get object_ptr h)"
+ by(auto simp add: get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: option.splits Option.bind_splits)
+
+lemma object_ptr_kinds_simp [simp]: "object_ptr_kinds (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h) = object_ptr_kinds h |\<union>| {|ptr|}"
+ by(auto simp add: object_ptr_kinds_def put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: option.splits)
+
+lemma type_wf_put_I:
+ assumes "type_wf h"
+ shows "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ using assms
+ by(auto simp add: type_wf_defs split: option.splits)
+
+lemma type_wf_put_ptr_not_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<notin>| object_ptr_kinds h"
+ shows "type_wf h"
+ using assms
+ by(auto simp add: type_wf_defs split: option.splits if_splits)
+
+lemma type_wf_put_ptr_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ shows "type_wf h"
+ using assms
+ by(auto simp add: type_wf_defs split: option.splits if_splits)
+
+
+subsection\<open>Preserving Types\<close>
+
+lemma type_wf_preserved: "type_wf h = type_wf h'"
+ by(auto simp add: type_wf_defs)
+
+
+lemma object_ptr_kinds_preserved_small:
+ assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms
+ apply(auto simp add: object_ptr_kinds_def preserved_def get_M_defs get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ split: option.splits)[1]
+ apply (metis (mono_tags, lifting) domIff error_returns_result fmdom.rep_eq fmember.rep_eq
+ old.unit.exhaust option.case_eq_if return_returns_result)
+ by (metis (mono_tags, lifting) domIff error_returns_result fmdom.rep_eq fmember.rep_eq
+ old.unit.exhaust option.case_eq_if return_returns_result)
+
+lemma object_ptr_kinds_preserved:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h' w object_ptr. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+proof -
+ {
+ fix object_ptr w
+ have "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ apply(rule writes_small_big[OF assms])
+ by auto
+ }
+ then show ?thesis
+ using object_ptr_kinds_preserved_small by blast
+qed
+
+
+lemma reads_writes_preserved2:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h' x. \<forall>w \<in> SW. h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'"
+ shows "preserved (get_M ptr getter) h h'"
+ apply(clarsimp simp add: preserved_def)
+ using reads_singleton assms(1) assms(2)
+ apply(rule reads_writes_preserved)
+ using assms(3)
+ by(auto simp add: preserved_def)
+end
diff --git a/thys/Core_SC_DOM/common/pointers/CharacterDataPointer.thy b/thys/Core_SC_DOM/common/pointers/CharacterDataPointer.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/pointers/CharacterDataPointer.thy
@@ -0,0 +1,199 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>CharacterData\<close>
+text\<open>In this theory, we introduce the typed pointers for the class CharacterData.\<close>
+theory CharacterDataPointer
+ imports
+ ElementPointer
+begin
+
+datatype 'character_data_ptr character_data_ptr = Ref (the_ref: ref) | Ext 'character_data_ptr
+register_default_tvars "'character_data_ptr character_data_ptr"
+type_synonym ('node_ptr, 'element_ptr, 'character_data_ptr) node_ptr
+ = "('character_data_ptr character_data_ptr + 'node_ptr, 'element_ptr) node_ptr"
+register_default_tvars "('node_ptr, 'element_ptr, 'character_data_ptr) node_ptr"
+type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr) object_ptr
+ = "('object_ptr, 'character_data_ptr character_data_ptr + 'node_ptr, 'element_ptr) object_ptr"
+register_default_tvars "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr) object_ptr"
+
+definition cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) character_data_ptr \<Rightarrow> (_) node_ptr"
+ where
+ "cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = node_ptr.Ext (Inr (Inl ptr))"
+
+abbreviation cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) character_data_ptr \<Rightarrow> (_) object_ptr"
+ where
+ "cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr)"
+
+definition cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) node_ptr \<Rightarrow> (_) character_data_ptr option"
+ where
+ "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = (case node_ptr of
+ node_ptr.Ext (Inr (Inl character_data_ptr)) \<Rightarrow> Some character_data_ptr
+ | _ \<Rightarrow> None)"
+
+abbreviation cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> (_) character_data_ptr option"
+ where
+ "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some node_ptr \<Rightarrow> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr
+ | None \<Rightarrow> None)"
+
+adhoc_overloading cast cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+ cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+
+consts is_character_data_ptr_kind :: 'a
+definition is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) node_ptr \<Rightarrow> bool"
+ where
+ "is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = (case cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr
+ of Some _ \<Rightarrow> True | _ \<Rightarrow> False)"
+
+abbreviation is_character_data_ptr_kind\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "is_character_data_ptr_kind\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast ptr of
+ Some node_ptr \<Rightarrow> is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr
+ | None \<Rightarrow> False)"
+
+adhoc_overloading is_character_data_ptr_kind is_character_data_ptr_kind\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+ is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+lemmas is_character_data_ptr_kind_def = is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+
+consts is_character_data_ptr :: 'a
+definition is_character_data_ptr\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) character_data_ptr \<Rightarrow> bool"
+ where
+ "is_character_data_ptr\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = (case ptr
+ of character_data_ptr.Ref _ \<Rightarrow> True | _ \<Rightarrow> False)"
+
+abbreviation is_character_data_ptr\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) node_ptr \<Rightarrow> bool"
+ where
+ "is_character_data_ptr\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast ptr of
+ Some character_data_ptr \<Rightarrow> is_character_data_ptr\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r character_data_ptr
+ | _ \<Rightarrow> False)"
+
+abbreviation is_character_data_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "is_character_data_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some node_ptr \<Rightarrow> is_character_data_ptr\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr
+ | None \<Rightarrow> False)"
+
+adhoc_overloading is_character_data_ptr
+ is_character_data_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_character_data_ptr\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_character_data_ptr\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+lemmas is_character_data_ptr_def = is_character_data_ptr\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+
+consts is_character_data_ptr_ext :: 'a
+abbreviation
+ "is_character_data_ptr_ext\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> \<not> is_character_data_ptr\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+
+abbreviation "is_character_data_ptr_ext\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some character_data_ptr \<Rightarrow> is_character_data_ptr_ext\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r character_data_ptr
+| None \<Rightarrow> False)"
+
+abbreviation "is_character_data_ptr_ext\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some node_ptr \<Rightarrow> is_character_data_ptr_ext\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr
+| None \<Rightarrow> False)"
+
+adhoc_overloading is_character_data_ptr_ext
+ is_character_data_ptr_ext\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_character_data_ptr_ext\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_character_data_ptr_ext\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+
+instantiation character_data_ptr :: (linorder) linorder
+begin
+definition
+ less_eq_character_data_ptr :: "(_::linorder) character_data_ptr \<Rightarrow> (_) character_data_ptr \<Rightarrow> bool"
+ where
+ "less_eq_character_data_ptr x y \<equiv> (case x of Ext i \<Rightarrow> (case y of Ext j \<Rightarrow> i \<le> j | Ref _ \<Rightarrow> False)
+ | Ref i \<Rightarrow> (case y of Ext _ \<Rightarrow> True | Ref j \<Rightarrow> i \<le> j))"
+definition
+ less_character_data_ptr :: "(_::linorder) character_data_ptr \<Rightarrow> (_) character_data_ptr \<Rightarrow> bool"
+ where "less_character_data_ptr x y \<equiv> x \<le> y \<and> \<not> y \<le> x"
+instance
+ apply(standard)
+ by(auto simp add: less_eq_character_data_ptr_def less_character_data_ptr_def
+ split: character_data_ptr.splits)
+end
+
+lemma is_character_data_ptr_ref [simp]: "is_character_data_ptr (character_data_ptr.Ref n)"
+ by(simp add: is_character_data_ptr\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma cast_element_ptr_not_character_data_ptr [simp]:
+ "(cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr \<noteq> cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r character_data_ptr)"
+ "(cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r character_data_ptr \<noteq> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr)"
+ unfolding cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by(auto)
+
+lemma is_character_data_ptr_kind_not_element_ptr [simp]:
+ "\<not> is_character_data_ptr_kind (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr)"
+ unfolding is_character_data_ptr_kind_def cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by auto
+lemma is_element_ptr_kind_not_character_data_ptr [simp]:
+ "\<not> is_element_ptr_kind (cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r character_data_ptr)"
+ using is_element_ptr_kind_obtains by fastforce
+
+lemma is_character_data_ptr_kind\<^sub>_cast [simp]:
+ "is_character_data_ptr_kind (cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r character_data_ptr)"
+ by (simp add: cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma character_data_ptr_casts_commute [simp]:
+ "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = Some character_data_ptr
+ \<longleftrightarrow> cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r character_data_ptr = node_ptr"
+ unfolding cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by(auto split: node_ptr.splits sum.splits)
+
+lemma character_data_ptr_casts_commute2 [simp]:
+ "(cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r character_data_ptr) = Some character_data_ptr)"
+ by simp
+
+lemma character_data_ptr_casts_commute3 [simp]:
+ assumes "is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr"
+ shows "cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r (the (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)) = node_ptr"
+ using assms
+ by(auto simp add: is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: node_ptr.splits sum.splits)
+
+lemma is_character_data_ptr_kind_obtains:
+ assumes "is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr"
+ obtains character_data_ptr where "cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r character_data_ptr = node_ptr"
+ by (metis assms is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def case_optionE
+ character_data_ptr_casts_commute)
+
+lemma is_character_data_ptr_kind_none:
+ assumes "\<not>is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr"
+ shows "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = None"
+ using assms
+ unfolding is_character_data_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by(auto split: node_ptr.splits sum.splits)
+
+lemma cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject [simp]:
+ "cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r x = cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r y \<longleftrightarrow> x = y"
+ by(simp add: cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_ext_none [simp]:
+ "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r (node_ptr.Ext (Inr (Inr node_ext_ptr))) = None"
+ by(simp add: cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+end
diff --git a/thys/Core_SC_DOM/common/pointers/DocumentPointer.thy b/thys/Core_SC_DOM/common/pointers/DocumentPointer.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/pointers/DocumentPointer.thy
@@ -0,0 +1,154 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Document\<close>
+text\<open>In this theory, we introduce the typed pointers for the class Document.\<close>
+theory DocumentPointer
+ imports
+ CharacterDataPointer
+begin
+
+datatype 'document_ptr document_ptr = Ref (the_ref: ref) | Ext 'document_ptr
+register_default_tvars "'document_ptr document_ptr"
+type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr) object_ptr
+ = "('document_ptr document_ptr + 'object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr) object_ptr"
+register_default_tvars "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr) object_ptr"
+
+definition cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_)document_ptr \<Rightarrow> (_) object_ptr"
+ where
+ "cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = object_ptr.Ext (Inr (Inl ptr))"
+
+definition cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> (_) document_ptr option"
+ where
+ "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = (case ptr of
+ object_ptr.Ext (Inr (Inl document_ptr)) \<Rightarrow> Some document_ptr
+ | _ \<Rightarrow> None)"
+
+adhoc_overloading cast cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+
+
+definition is_document_ptr_kind :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "is_document_ptr_kind ptr = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some _ \<Rightarrow> True | None \<Rightarrow> False)"
+
+consts is_document_ptr :: 'a
+definition is_document_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) document_ptr \<Rightarrow> bool"
+ where
+ "is_document_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = (case ptr of document_ptr.Ref _ \<Rightarrow> True | _ \<Rightarrow> False)"
+
+abbreviation is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some document_ptr \<Rightarrow> is_document_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr
+ | None \<Rightarrow> False)"
+adhoc_overloading is_document_ptr is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_document_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+lemmas is_document_ptr_def = is_document_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+
+consts is_document_ptr_ext :: 'a
+abbreviation "is_document_ptr_ext\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> \<not> is_document_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+
+abbreviation "is_document_ptr_ext\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some document_ptr \<Rightarrow> is_document_ptr_ext\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr
+| None \<Rightarrow> False)"
+adhoc_overloading is_document_ptr_ext is_document_ptr_ext\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_document_ptr_ext\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+
+instantiation document_ptr :: (linorder) linorder
+begin
+definition less_eq_document_ptr :: "(_::linorder) document_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> bool"
+ where "less_eq_document_ptr x y \<equiv> (case x of Ext i \<Rightarrow> (case y of Ext j \<Rightarrow> i \<le> j | Ref _ \<Rightarrow> False)
+ | Ref i \<Rightarrow> (case y of Ext _ \<Rightarrow> True | Ref j \<Rightarrow> i \<le> j))"
+definition less_document_ptr :: "(_::linorder) document_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> bool"
+ where "less_document_ptr x y \<equiv> x \<le> y \<and> \<not> y \<le> x"
+instance
+ apply(standard)
+ by(auto simp add: less_eq_document_ptr_def less_document_ptr_def split: document_ptr.splits)
+end
+
+lemma is_document_ptr_ref [simp]: "is_document_ptr (document_ptr.Ref n)"
+ by(simp add: is_document_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma cast_document_ptr_not_node_ptr [simp]:
+ "cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr \<noteq> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr"
+ "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr"
+ unfolding cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by auto
+
+lemma document_ptr_no_node_ptr_cast [simp]:
+ "\<not> is_document_ptr_kind (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)"
+ by(simp add: cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def is_document_ptr_kind_def)
+lemma node_ptr_no_document_ptr_cast [simp]:
+ "\<not> is_node_ptr_kind (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)"
+ using is_node_ptr_kind_obtains by fastforce
+
+lemma document_ptr_document_ptr_cast [simp]:
+ "is_document_ptr_kind (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)"
+ by (simp add: cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def is_document_ptr_kind_def)
+
+lemma document_ptr_casts_commute [simp]:
+ "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = Some document_ptr \<longleftrightarrow> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr = ptr"
+ unfolding cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by(auto split: object_ptr.splits sum.splits)
+
+lemma document_ptr_casts_commute2 [simp]:
+ "(cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr) = Some document_ptr)"
+ by simp
+
+lemma document_ptr_casts_commute3 [simp]:
+ assumes "is_document_ptr_kind ptr"
+ shows "cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (the (cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr)) = ptr"
+ using assms
+ by(auto simp add: is_document_ptr_kind_def cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: object_ptr.splits sum.splits)
+
+lemma is_document_ptr_kind_obtains:
+ assumes "is_document_ptr_kind ptr"
+ obtains document_ptr where "ptr = cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr"
+ using assms is_document_ptr_kind_def
+ by (metis case_optionE document_ptr_casts_commute)
+
+lemma is_document_ptr_kind_none:
+ assumes "\<not>is_document_ptr_kind ptr"
+ shows "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = None"
+ using assms
+ unfolding is_document_ptr_kind_def cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by (auto split: object_ptr.splits sum.splits)
+
+lemma cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject [simp]:
+ "cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r x = cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r y \<longleftrightarrow> x = y"
+ by(simp add: cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_ext_none [simp]:
+ "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (object_ptr.Ext (Inr (Inr (Inr object_ext_ptr)))) = None"
+ by(simp add: cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma is_document_ptr_kind_not_element_ptr_kind [dest]:
+ "is_document_ptr_kind ptr \<Longrightarrow> \<not> is_element_ptr_kind ptr"
+ by(auto simp add: split: option.splits)
+end
diff --git a/thys/Core_SC_DOM/common/pointers/ElementPointer.thy b/thys/Core_SC_DOM/common/pointers/ElementPointer.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/pointers/ElementPointer.thy
@@ -0,0 +1,178 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Element\<close>
+text\<open>In this theory, we introduce the typed pointers for the class Element.\<close>
+theory ElementPointer
+ imports
+ NodePointer
+begin
+
+datatype 'element_ptr element_ptr = Ref (the_ref: ref) | Ext 'element_ptr
+register_default_tvars "'element_ptr element_ptr"
+
+type_synonym ('node_ptr, 'element_ptr) node_ptr
+ = "('element_ptr element_ptr + 'node_ptr) node_ptr"
+register_default_tvars "('node_ptr, 'element_ptr) node_ptr"
+type_synonym ('object_ptr, 'node_ptr, 'element_ptr) object_ptr
+ = "('object_ptr, 'element_ptr element_ptr + 'node_ptr) object_ptr"
+register_default_tvars "('object_ptr, 'node_ptr, 'element_ptr) object_ptr"
+
+
+definition cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) element_ptr \<Rightarrow> (_) element_ptr"
+ where
+ "cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r = id"
+
+definition cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) element_ptr \<Rightarrow> (_) node_ptr"
+ where
+ "cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = node_ptr.Ext (Inl ptr)"
+
+abbreviation cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) element_ptr \<Rightarrow> (_) object_ptr"
+ where
+ "cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr)"
+
+definition cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) node_ptr \<Rightarrow> (_) element_ptr option"
+ where
+ "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = (case node_ptr of node_ptr.Ext (Inl element_ptr)
+ \<Rightarrow> Some element_ptr | _ \<Rightarrow> None)"
+
+abbreviation cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> (_) element_ptr option"
+ where
+ "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some node_ptr \<Rightarrow> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr
+ | None \<Rightarrow> None)"
+
+adhoc_overloading cast cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+ cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+
+consts is_element_ptr_kind :: 'a
+definition is_element_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) node_ptr \<Rightarrow> bool"
+ where
+ "is_element_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = (case cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of Some _ \<Rightarrow> True | _ \<Rightarrow> False)"
+
+abbreviation is_element_ptr_kind\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "is_element_ptr_kind\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast ptr of
+ Some node_ptr \<Rightarrow> is_element_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr
+ | None \<Rightarrow> False)"
+
+adhoc_overloading is_element_ptr_kind is_element_ptr_kind\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_element_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+lemmas is_element_ptr_kind_def = is_element_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+
+consts is_element_ptr :: 'a
+definition is_element_ptr\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) element_ptr \<Rightarrow> bool"
+ where
+ "is_element_ptr\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = (case ptr of element_ptr.Ref _ \<Rightarrow> True | _ \<Rightarrow> False)"
+
+abbreviation is_element_ptr\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) node_ptr \<Rightarrow> bool"
+ where
+ "is_element_ptr\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast ptr of
+ Some element_ptr \<Rightarrow> is_element_ptr\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr
+ | _ \<Rightarrow> False)"
+
+abbreviation is_element_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "is_element_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast ptr of
+ Some node_ptr \<Rightarrow> is_element_ptr\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr
+ | None \<Rightarrow> False)"
+
+adhoc_overloading is_element_ptr is_element_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_element_ptr\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_element_ptr\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+lemmas is_element_ptr_def = is_element_ptr\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+
+consts is_element_ptr_ext :: 'a
+abbreviation "is_element_ptr_ext\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> \<not> is_element_ptr\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+
+abbreviation "is_element_ptr_ext\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> is_element_ptr_kind ptr \<and> (\<not> is_element_ptr\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr)"
+
+abbreviation "is_element_ptr_ext\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> is_element_ptr_kind ptr \<and> (\<not> is_element_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr)"
+adhoc_overloading is_element_ptr_ext is_element_ptr_ext\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_element_ptr_ext\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+
+
+instantiation element_ptr :: (linorder) linorder
+begin
+definition
+ less_eq_element_ptr :: "(_::linorder) element_ptr \<Rightarrow> (_)element_ptr \<Rightarrow> bool"
+ where
+ "less_eq_element_ptr x y \<equiv> (case x of Ext i \<Rightarrow> (case y of Ext j \<Rightarrow> i \<le> j | Ref _ \<Rightarrow> False)
+ | Ref i \<Rightarrow> (case y of Ext _ \<Rightarrow> True | Ref j \<Rightarrow> i \<le> j))"
+definition
+ less_element_ptr :: "(_::linorder) element_ptr \<Rightarrow> (_) element_ptr \<Rightarrow> bool"
+ where "less_element_ptr x y \<equiv> x \<le> y \<and> \<not> y \<le> x"
+instance
+ apply(standard)
+ by(auto simp add: less_eq_element_ptr_def less_element_ptr_def split: element_ptr.splits)
+end
+
+lemma is_element_ptr_ref [simp]: "is_element_ptr (element_ptr.Ref n)"
+ by(simp add: is_element_ptr\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma element_ptr_casts_commute [simp]:
+ "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = Some element_ptr \<longleftrightarrow> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr = node_ptr"
+ unfolding cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by(auto split: node_ptr.splits sum.splits)
+
+lemma element_ptr_casts_commute2 [simp]:
+ "(cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr) = Some element_ptr)"
+ by simp
+
+lemma element_ptr_casts_commute3 [simp]:
+ assumes "is_element_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr"
+ shows "cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r (the (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)) = node_ptr"
+ using assms
+ by(auto simp add: is_element_ptr_kind_def cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: node_ptr.splits sum.splits)
+
+lemma is_element_ptr_kind_obtains:
+ assumes "is_element_ptr_kind node_ptr"
+ obtains element_ptr where "node_ptr = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr"
+ by (metis assms is_element_ptr_kind_def case_optionE element_ptr_casts_commute)
+
+lemma is_element_ptr_kind_none:
+ assumes "\<not>is_element_ptr_kind node_ptr"
+ shows "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = None"
+ using assms
+ unfolding is_element_ptr_kind_def cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by(auto split: node_ptr.splits sum.splits)
+
+lemma is_element_ptr_kind_cast [simp]:
+ "is_element_ptr_kind (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr)"
+ by (metis element_ptr_casts_commute is_element_ptr_kind_none option.distinct(1))
+
+lemma cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject [simp]:
+ "cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r x = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r y \<longleftrightarrow> x = y"
+ by(simp add: cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_ext_none [simp]:
+ "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (node_ptr.Ext (Inr (Inr node_ext_ptr))) = None"
+ by(simp add: cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma is_element_ptr_implies_kind [dest]: "is_element_ptr\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<Longrightarrow> is_element_ptr_kind\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ by(auto split: option.splits)
+
+end
diff --git a/thys/Core_SC_DOM/common/pointers/NodePointer.thy b/thys/Core_SC_DOM/common/pointers/NodePointer.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/pointers/NodePointer.thy
@@ -0,0 +1,111 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Node\<close>
+text\<open>In this theory, we introduce the typed pointers for the class Node.\<close>
+theory NodePointer
+ imports
+ ObjectPointer
+begin
+
+datatype 'node_ptr node_ptr = Ext 'node_ptr
+register_default_tvars "'node_ptr node_ptr"
+
+type_synonym ('object_ptr, 'node_ptr) object_ptr = "('node_ptr node_ptr + 'object_ptr) object_ptr"
+register_default_tvars "('object_ptr, 'node_ptr) object_ptr"
+
+definition cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) node_ptr \<Rightarrow> (_) object_ptr"
+ where
+ "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = object_ptr.Ext (Inl ptr)"
+
+definition cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> (_) node_ptr option"
+ where
+ "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r object_ptr = (case object_ptr of object_ptr.Ext (Inl node_ptr)
+ \<Rightarrow> Some node_ptr | _ \<Rightarrow> None)"
+
+adhoc_overloading cast cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+
+definition is_node_ptr_kind :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "is_node_ptr_kind ptr = (cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<noteq> None)"
+
+instantiation node_ptr :: (linorder) linorder
+begin
+definition less_eq_node_ptr :: "(_::linorder) node_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> bool"
+ where "less_eq_node_ptr x y \<equiv> (case x of Ext i \<Rightarrow> (case y of Ext j \<Rightarrow> i \<le> j))"
+definition less_node_ptr :: "(_::linorder) node_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> bool"
+ where "less_node_ptr x y \<equiv> x \<le> y \<and> \<not> y \<le> x"
+instance
+ apply(standard)
+ by(auto simp add: less_eq_node_ptr_def less_node_ptr_def split: node_ptr.splits)
+end
+
+lemma node_ptr_casts_commute [simp]:
+ "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = Some node_ptr \<longleftrightarrow> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = ptr"
+ unfolding cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by(auto split: object_ptr.splits sum.splits)
+
+lemma node_ptr_casts_commute2 [simp]:
+ "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr) = Some node_ptr"
+ by simp
+
+lemma node_ptr_casts_commute3 [simp]:
+ assumes "is_node_ptr_kind ptr"
+ shows "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (the (cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr)) = ptr"
+ using assms
+ by(auto simp add: is_node_ptr_kind_def cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: object_ptr.splits sum.splits)
+
+lemma is_node_ptr_kind_obtains:
+ assumes "is_node_ptr_kind ptr"
+ obtains node_ptr where "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = Some node_ptr"
+ using assms is_node_ptr_kind_def by auto
+
+lemma is_node_ptr_kind_none:
+ assumes "\<not>is_node_ptr_kind ptr"
+ shows "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = None"
+ using assms
+ unfolding is_node_ptr_kind_def cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by auto
+
+lemma is_node_ptr_kind_cast [simp]: "is_node_ptr_kind (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)"
+ unfolding is_node_ptr_kind_def by simp
+
+lemma cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject [simp]:
+ "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r x = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r y \<longleftrightarrow> x = y"
+ by(simp add: cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_ext_none [simp]:
+ "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r (object_ptr.Ext (Inr (Inr (Inr object_ext_ptr)))) = None"
+ by(simp add: cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma node_ptr_inclusion [simp]:
+ "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr \<in> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ` node_ptrs \<longleftrightarrow> node_ptr \<in> node_ptrs"
+ by auto
+end
diff --git a/thys/Core_SC_DOM/common/pointers/ObjectPointer.thy b/thys/Core_SC_DOM/common/pointers/ObjectPointer.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/pointers/ObjectPointer.thy
@@ -0,0 +1,51 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Object\<close>
+text\<open>In this theory, we introduce the typed pointer for the class Object. This class is the
+common superclass of our class model.\<close>
+theory ObjectPointer
+ imports
+ Ref
+begin
+
+datatype 'object_ptr object_ptr = Ext 'object_ptr
+register_default_tvars "'object_ptr object_ptr"
+
+instantiation object_ptr :: (linorder) linorder
+begin
+definition less_eq_object_ptr :: "'object_ptr::linorder object_ptr \<Rightarrow> 'object_ptr object_ptr \<Rightarrow> bool"
+ where "less_eq_object_ptr x y \<equiv> (case x of Ext i \<Rightarrow> (case y of Ext j \<Rightarrow> i \<le> j))"
+definition less_object_ptr :: "'object_ptr::linorder object_ptr \<Rightarrow> 'object_ptr object_ptr \<Rightarrow> bool"
+ where "less_object_ptr x y \<equiv> x \<le> y \<and> \<not> y \<le> x"
+instance by(standard, auto simp add: less_eq_object_ptr_def less_object_ptr_def
+ split: object_ptr.splits)
+end
+
+end
diff --git a/thys/Core_SC_DOM/common/pointers/Ref.thy b/thys/Core_SC_DOM/common/pointers/Ref.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/pointers/Ref.thy
@@ -0,0 +1,62 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>References\<close>
+text\<open>
+ This theory, we introduce a generic reference. All our typed pointers include such
+ a reference, which allows us to distinguish pointers of the same type, but also to
+ iterate over all pointers in a set.\<close>
+theory
+ Ref
+ imports
+ "HOL-Library.Adhoc_Overloading"
+ "../preliminaries/Hiding_Type_Variables"
+begin
+
+instantiation sum :: (linorder, linorder) linorder
+begin
+definition less_eq_sum :: "'a + 'b \<Rightarrow> 'a + 'b \<Rightarrow> bool"
+ where
+ "less_eq_sum t t' = (case t of
+ Inl l \<Rightarrow> (case t' of
+ Inl l' \<Rightarrow> l \<le> l'
+ | Inr r' \<Rightarrow> True)
+ | Inr r \<Rightarrow> (case t' of
+ Inl l' \<Rightarrow> False
+ | Inr r' \<Rightarrow> r \<le> r'))"
+definition less_sum :: "'a + 'b \<Rightarrow> 'a + 'b \<Rightarrow> bool"
+ where
+ "less_sum t t' \<equiv> t \<le> t' \<and> \<not> t' \<le> t"
+instance by(standard) (auto simp add: less_eq_sum_def less_sum_def split: sum.splits)
+end
+
+type_synonym ref = nat
+consts cast :: 'a
+
+end
diff --git a/thys/Core_SC_DOM/common/preliminaries/Heap_Error_Monad.thy b/thys/Core_SC_DOM/common/preliminaries/Heap_Error_Monad.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/preliminaries/Heap_Error_Monad.thy
@@ -0,0 +1,917 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>The Heap Error Monad\<close>
+text \<open>In this theory, we define a heap and error monad for modeling exceptions.
+This allows us to define composite methods similar to stateful programming in Haskell,
+but also to stay close to the official DOM specification.\<close>
+theory
+ Heap_Error_Monad
+ imports
+ Hiding_Type_Variables
+ "HOL-Library.Monad_Syntax"
+begin
+
+subsection \<open>The Program Data Type\<close>
+
+datatype ('heap, 'e, 'result) prog = Prog (the_prog: "'heap \<Rightarrow> 'e + 'result \<times> 'heap")
+register_default_tvars "('heap, 'e, 'result) prog" (print, parse)
+
+subsection \<open>Basic Functions\<close>
+
+definition
+ bind :: "(_, 'result) prog \<Rightarrow> ('result \<Rightarrow> (_, 'result2) prog) \<Rightarrow> (_, 'result2) prog"
+ where
+ "bind f g = Prog (\<lambda>h. (case (the_prog f) h of Inr (x, h') \<Rightarrow> (the_prog (g x)) h'
+ | Inl exception \<Rightarrow> Inl exception))"
+
+adhoc_overloading Monad_Syntax.bind bind
+
+definition
+ execute :: "'heap \<Rightarrow> ('heap, 'e, 'result) prog \<Rightarrow> ('e + 'result \<times> 'heap)"
+ ("((_)/ \<turnstile> (_))" [51, 52] 55)
+ where
+ "execute h p = (the_prog p) h"
+
+definition
+ returns_result :: "'heap \<Rightarrow> ('heap, 'e, 'result) prog \<Rightarrow> 'result \<Rightarrow> bool"
+ ("((_)/ \<turnstile> (_)/ \<rightarrow>\<^sub>r (_))" [60, 35, 61] 65)
+ where
+ "returns_result h p r \<longleftrightarrow> (case h \<turnstile> p of Inr (r', _) \<Rightarrow> r = r' | Inl _ \<Rightarrow> False)"
+
+fun select_result ("|(_)|\<^sub>r")
+ where
+ "select_result (Inr (r, _)) = r"
+ | "select_result (Inl _) = undefined"
+
+lemma returns_result_eq [elim]: "h \<turnstile> f \<rightarrow>\<^sub>r y \<Longrightarrow> h \<turnstile> f \<rightarrow>\<^sub>r y' \<Longrightarrow> y = y'"
+ by(auto simp add: returns_result_def split: sum.splits)
+
+definition
+ returns_heap :: "'heap \<Rightarrow> ('heap, 'e, 'result) prog \<Rightarrow> 'heap \<Rightarrow> bool"
+ ("((_)/ \<turnstile> (_)/ \<rightarrow>\<^sub>h (_))" [60, 35, 61] 65)
+ where
+ "returns_heap h p h' \<longleftrightarrow> (case h \<turnstile> p of Inr (_ , h'') \<Rightarrow> h' = h'' | Inl _ \<Rightarrow> False)"
+
+fun select_heap ("|(_)|\<^sub>h")
+ where
+ "select_heap (Inr ( _, h)) = h"
+ | "select_heap (Inl _) = undefined"
+
+lemma returns_heap_eq [elim]: "h \<turnstile> f \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> f \<rightarrow>\<^sub>h h'' \<Longrightarrow> h' = h''"
+ by(auto simp add: returns_heap_def split: sum.splits)
+
+definition
+ returns_result_heap :: "'heap \<Rightarrow> ('heap, 'e, 'result) prog \<Rightarrow> 'result \<Rightarrow> 'heap \<Rightarrow> bool"
+ ("((_)/ \<turnstile> (_)/ \<rightarrow>\<^sub>r (_) \<rightarrow>\<^sub>h (_))" [60, 35, 61, 62] 65)
+ where
+ "returns_result_heap h p r h' \<longleftrightarrow> h \<turnstile> p \<rightarrow>\<^sub>r r \<and> h \<turnstile> p \<rightarrow>\<^sub>h h'"
+
+lemma return_result_heap_code [code]:
+ "returns_result_heap h p r h' \<longleftrightarrow> (case h \<turnstile> p of Inr (r', h'') \<Rightarrow> r = r' \<and> h' = h'' | Inl _ \<Rightarrow> False)"
+ by(auto simp add: returns_result_heap_def returns_result_def returns_heap_def split: sum.splits)
+
+fun select_result_heap ("|(_)|\<^sub>r\<^sub>h")
+ where
+ "select_result_heap (Inr (r, h)) = (r, h)"
+ | "select_result_heap (Inl _) = undefined"
+
+definition
+ returns_error :: "'heap \<Rightarrow> ('heap, 'e, 'result) prog \<Rightarrow> 'e \<Rightarrow> bool"
+ ("((_)/ \<turnstile> (_)/ \<rightarrow>\<^sub>e (_))" [60, 35, 61] 65)
+ where
+ "returns_error h p e = (case h \<turnstile> p of Inr _ \<Rightarrow> False | Inl e' \<Rightarrow> e = e')"
+
+definition is_OK :: "'heap \<Rightarrow> ('heap, 'e, 'result) prog \<Rightarrow> bool" ("((_)/ \<turnstile> ok (_))" [75, 75])
+ where
+ "is_OK h p = (case h \<turnstile> p of Inr _ \<Rightarrow> True | Inl _ \<Rightarrow> False)"
+
+lemma is_OK_returns_result_I [intro]: "h \<turnstile> f \<rightarrow>\<^sub>r y \<Longrightarrow> h \<turnstile> ok f"
+ by(auto simp add: is_OK_def returns_result_def split: sum.splits)
+
+lemma is_OK_returns_result_E [elim]:
+ assumes "h \<turnstile> ok f"
+ obtains x where "h \<turnstile> f \<rightarrow>\<^sub>r x"
+ using assms by(auto simp add: is_OK_def returns_result_def split: sum.splits)
+
+lemma is_OK_returns_heap_I [intro]: "h \<turnstile> f \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> ok f"
+ by(auto simp add: is_OK_def returns_heap_def split: sum.splits)
+
+lemma is_OK_returns_heap_E [elim]:
+ assumes "h \<turnstile> ok f"
+ obtains h' where "h \<turnstile> f \<rightarrow>\<^sub>h h'"
+ using assms by(auto simp add: is_OK_def returns_heap_def split: sum.splits)
+
+lemma select_result_I:
+ assumes "h \<turnstile> ok f"
+ and "\<And>x. h \<turnstile> f \<rightarrow>\<^sub>r x \<Longrightarrow> P x"
+ shows "P |h \<turnstile> f|\<^sub>r"
+ using assms
+ by(auto simp add: is_OK_def returns_result_def split: sum.splits)
+
+lemma select_result_I2 [simp]:
+ assumes "h \<turnstile> f \<rightarrow>\<^sub>r x"
+ shows "|h \<turnstile> f|\<^sub>r = x"
+ using assms
+ by(auto simp add: is_OK_def returns_result_def split: sum.splits)
+
+lemma returns_result_select_result [simp]:
+ assumes "h \<turnstile> ok f"
+ shows "h \<turnstile> f \<rightarrow>\<^sub>r |h \<turnstile> f|\<^sub>r"
+ using assms
+ by (simp add: select_result_I)
+
+lemma select_result_E:
+ assumes "P |h \<turnstile> f|\<^sub>r" and "h \<turnstile> ok f"
+ obtains x where "h \<turnstile> f \<rightarrow>\<^sub>r x" and "P x"
+ using assms
+ by(auto simp add: is_OK_def returns_result_def split: sum.splits)
+
+lemma select_result_eq: "(\<And>x .h \<turnstile> f \<rightarrow>\<^sub>r x = h' \<turnstile> f \<rightarrow>\<^sub>r x) \<Longrightarrow> |h \<turnstile> f|\<^sub>r = |h' \<turnstile> f|\<^sub>r"
+ by (metis (no_types, lifting) is_OK_def old.sum.simps(6) select_result.elims
+ select_result_I select_result_I2)
+
+definition error :: "'e \<Rightarrow> ('heap, 'e, 'result) prog"
+ where
+ "error exception = Prog (\<lambda>h. Inl exception)"
+
+lemma error_bind [iff]: "(error e \<bind> g) = error e"
+ unfolding error_def bind_def by auto
+
+lemma error_returns_result [simp]: "\<not> (h \<turnstile> error e \<rightarrow>\<^sub>r y)"
+ unfolding returns_result_def error_def execute_def by auto
+
+lemma error_returns_heap [simp]: "\<not> (h \<turnstile> error e \<rightarrow>\<^sub>h h')"
+ unfolding returns_heap_def error_def execute_def by auto
+
+lemma error_returns_error [simp]: "h \<turnstile> error e \<rightarrow>\<^sub>e e"
+ unfolding returns_error_def error_def execute_def by auto
+
+definition return :: "'result \<Rightarrow> ('heap, 'e, 'result) prog"
+ where
+ "return result = Prog (\<lambda>h. Inr (result, h))"
+
+lemma return_ok [simp]: "h \<turnstile> ok (return x)"
+ by(simp add: return_def is_OK_def execute_def)
+
+lemma return_bind [iff]: "(return x \<bind> g) = g x"
+ unfolding return_def bind_def by auto
+
+lemma return_id [simp]: "f \<bind> return = f"
+ by (induct f) (auto simp add: return_def bind_def split: sum.splits prod.splits)
+
+lemma return_returns_result [iff]: "(h \<turnstile> return x \<rightarrow>\<^sub>r y) = (x = y)"
+ unfolding returns_result_def return_def execute_def by auto
+
+lemma return_returns_heap [iff]: "(h \<turnstile> return x \<rightarrow>\<^sub>h h') = (h = h')"
+ unfolding returns_heap_def return_def execute_def by auto
+
+lemma return_returns_error [iff]: "\<not> h \<turnstile> return x \<rightarrow>\<^sub>e e"
+ unfolding returns_error_def execute_def return_def by auto
+
+definition noop :: "('heap, 'e, unit) prog"
+ where
+ "noop = return ()"
+
+lemma noop_returns_heap [simp]: "h \<turnstile> noop \<rightarrow>\<^sub>h h' \<longleftrightarrow> h = h'"
+ by(simp add: noop_def)
+
+definition get_heap :: "('heap, 'e, 'heap) prog"
+ where
+ "get_heap = Prog (\<lambda>h. h \<turnstile> return h)"
+
+lemma get_heap_ok [simp]: "h \<turnstile> ok (get_heap)"
+ by (simp add: get_heap_def execute_def is_OK_def return_def)
+
+lemma get_heap_returns_result [simp]: "(h \<turnstile> get_heap \<bind> (\<lambda>h'. f h') \<rightarrow>\<^sub>r x) = (h \<turnstile> f h \<rightarrow>\<^sub>r x)"
+ by(simp add: get_heap_def returns_result_def bind_def return_def execute_def)
+
+lemma get_heap_returns_heap [simp]: "(h \<turnstile> get_heap \<bind> (\<lambda>h'. f h') \<rightarrow>\<^sub>h h'') = (h \<turnstile> f h \<rightarrow>\<^sub>h h'')"
+ by(simp add: get_heap_def returns_heap_def bind_def return_def execute_def)
+
+lemma get_heap_is_OK [simp]: "(h \<turnstile> ok (get_heap \<bind> (\<lambda>h'. f h'))) = (h \<turnstile> ok (f h))"
+ by(auto simp add: get_heap_def is_OK_def bind_def return_def execute_def)
+
+lemma get_heap_E [elim]: "(h \<turnstile> get_heap \<rightarrow>\<^sub>r x) \<Longrightarrow> x = h"
+ by(simp add: get_heap_def returns_result_def return_def execute_def)
+
+definition return_heap :: "'heap \<Rightarrow> ('heap, 'e, unit) prog"
+ where
+ "return_heap h = Prog (\<lambda>_. h \<turnstile> return ())"
+
+lemma return_heap_E [iff]: "(h \<turnstile> return_heap h' \<rightarrow>\<^sub>h h'') = (h'' = h')"
+ by(simp add: return_heap_def returns_heap_def return_def execute_def)
+
+lemma return_heap_returns_result [simp]: "h \<turnstile> return_heap h' \<rightarrow>\<^sub>r ()"
+ by(simp add: return_heap_def execute_def returns_result_def return_def)
+
+
+subsection \<open>Pure Heaps\<close>
+
+definition pure :: "('heap, 'e, 'result) prog \<Rightarrow> 'heap \<Rightarrow> bool"
+ where "pure f h \<longleftrightarrow> h \<turnstile> ok f \<longrightarrow> h \<turnstile> f \<rightarrow>\<^sub>h h"
+
+lemma return_pure [simp]: "pure (return x) h"
+ by(simp add: pure_def return_def is_OK_def returns_heap_def execute_def)
+
+lemma error_pure [simp]: "pure (error e) h"
+ by(simp add: pure_def error_def is_OK_def returns_heap_def execute_def)
+
+lemma noop_pure [simp]: "pure (noop) h"
+ by (simp add: noop_def)
+
+lemma get_pure [simp]: "pure get_heap h"
+ by(simp add: pure_def get_heap_def is_OK_def returns_heap_def return_def execute_def)
+
+lemma pure_returns_heap_eq:
+ "h \<turnstile> f \<rightarrow>\<^sub>h h' \<Longrightarrow> pure f h \<Longrightarrow> h = h'"
+ by (meson pure_def is_OK_returns_heap_I returns_heap_eq)
+
+lemma pure_eq_iff:
+ "(\<forall>h' x. h \<turnstile> f \<rightarrow>\<^sub>r x \<longrightarrow> h \<turnstile> f \<rightarrow>\<^sub>h h' \<longrightarrow> h = h') \<longleftrightarrow> pure f h"
+ by(auto simp add: pure_def)
+
+subsection \<open>Bind\<close>
+
+lemma bind_assoc [simp]:
+ "((bind f g) \<bind> h) = (f \<bind> (\<lambda>x. (g x \<bind> h)))"
+ by(auto simp add: bind_def split: sum.splits)
+
+lemma bind_returns_result_E:
+ assumes "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>r y"
+ obtains x h' where "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> f \<rightarrow>\<^sub>h h'" and "h' \<turnstile> g x \<rightarrow>\<^sub>r y"
+ using assms by(auto simp add: bind_def returns_result_def returns_heap_def execute_def
+ split: sum.splits)
+
+lemma bind_returns_result_E2:
+ assumes "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>r y" and "pure f h"
+ obtains x where "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> g x \<rightarrow>\<^sub>r y"
+ using assms pure_returns_heap_eq bind_returns_result_E by metis
+
+lemma bind_returns_result_E3:
+ assumes "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>r y" and "h \<turnstile> f \<rightarrow>\<^sub>r x" and "pure f h"
+ shows "h \<turnstile> g x \<rightarrow>\<^sub>r y"
+ using assms returns_result_eq bind_returns_result_E2 by metis
+
+lemma bind_returns_result_E4:
+ assumes "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>r y" and "h \<turnstile> f \<rightarrow>\<^sub>r x"
+ obtains h' where "h \<turnstile> f \<rightarrow>\<^sub>h h'" and "h' \<turnstile> g x \<rightarrow>\<^sub>r y"
+ using assms returns_result_eq bind_returns_result_E by metis
+
+lemma bind_returns_heap_E:
+ assumes "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>h h''"
+ obtains x h' where "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> f \<rightarrow>\<^sub>h h'" and "h' \<turnstile> g x \<rightarrow>\<^sub>h h''"
+ using assms by(auto simp add: bind_def returns_result_def returns_heap_def execute_def
+ split: sum.splits)
+
+lemma bind_returns_heap_E2 [elim]:
+ assumes "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>h h'" and "pure f h"
+ obtains x where "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> g x \<rightarrow>\<^sub>h h'"
+ using assms pure_returns_heap_eq by (fastforce elim: bind_returns_heap_E)
+
+lemma bind_returns_heap_E3 [elim]:
+ assumes "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>h h'" and "h \<turnstile> f \<rightarrow>\<^sub>r x" and "pure f h"
+ shows "h \<turnstile> g x \<rightarrow>\<^sub>h h'"
+ using assms pure_returns_heap_eq returns_result_eq by (fastforce elim: bind_returns_heap_E)
+
+lemma bind_returns_heap_E4:
+ assumes "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>h h''" and "h \<turnstile> f \<rightarrow>\<^sub>h h'"
+ obtains x where "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h' \<turnstile> g x \<rightarrow>\<^sub>h h''"
+ using assms
+ by (metis bind_returns_heap_E returns_heap_eq)
+
+lemma bind_returns_error_I [intro]:
+ assumes "h \<turnstile> f \<rightarrow>\<^sub>e e"
+ shows "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>e e"
+ using assms
+ by(auto simp add: returns_error_def bind_def execute_def split: sum.splits)
+
+lemma bind_returns_error_I3:
+ assumes "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> f \<rightarrow>\<^sub>h h'" and "h' \<turnstile> g x \<rightarrow>\<^sub>e e"
+ shows "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>e e"
+ using assms
+ by(auto simp add: returns_error_def bind_def execute_def returns_heap_def returns_result_def
+ split: sum.splits)
+
+lemma bind_returns_error_I2 [intro]:
+ assumes "pure f h" and "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> g x \<rightarrow>\<^sub>e e"
+ shows "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>e e"
+ using assms
+ by (meson bind_returns_error_I3 is_OK_returns_result_I pure_def)
+
+lemma bind_is_OK_E [elim]:
+ assumes "h \<turnstile> ok (f \<bind> g)"
+ obtains x h' where "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> f \<rightarrow>\<^sub>h h'" and "h' \<turnstile> ok (g x)"
+ using assms
+ by(auto simp add: bind_def returns_result_def returns_heap_def is_OK_def execute_def
+ split: sum.splits)
+
+lemma bind_is_OK_E2:
+ assumes "h \<turnstile> ok (f \<bind> g)" and "h \<turnstile> f \<rightarrow>\<^sub>r x"
+ obtains h' where "h \<turnstile> f \<rightarrow>\<^sub>h h'" and "h' \<turnstile> ok (g x)"
+ using assms
+ by(auto simp add: bind_def returns_result_def returns_heap_def is_OK_def execute_def
+ split: sum.splits)
+
+lemma bind_returns_result_I [intro]:
+ assumes "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> f \<rightarrow>\<^sub>h h'" and "h' \<turnstile> g x \<rightarrow>\<^sub>r y"
+ shows "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>r y"
+ using assms
+ by(auto simp add: bind_def returns_result_def returns_heap_def execute_def
+ split: sum.splits)
+
+lemma bind_pure_returns_result_I [intro]:
+ assumes "pure f h" and "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> g x \<rightarrow>\<^sub>r y"
+ shows "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>r y"
+ using assms
+ by (meson bind_returns_result_I pure_def is_OK_returns_result_I)
+
+lemma bind_pure_returns_result_I2 [intro]:
+ assumes "pure f h" and "h \<turnstile> ok f" and "\<And>x. h \<turnstile> f \<rightarrow>\<^sub>r x \<Longrightarrow> h \<turnstile> g x \<rightarrow>\<^sub>r y"
+ shows "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>r y"
+ using assms by auto
+
+lemma bind_returns_heap_I [intro]:
+ assumes "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> f \<rightarrow>\<^sub>h h'" and "h' \<turnstile> g x \<rightarrow>\<^sub>h h''"
+ shows "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>h h''"
+ using assms
+ by(auto simp add: bind_def returns_result_def returns_heap_def execute_def
+ split: sum.splits)
+
+lemma bind_returns_heap_I2 [intro]:
+ assumes "h \<turnstile> f \<rightarrow>\<^sub>h h'" and "\<And>x. h \<turnstile> f \<rightarrow>\<^sub>r x \<Longrightarrow> h' \<turnstile> g x \<rightarrow>\<^sub>h h''"
+ shows "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>h h''"
+ using assms
+ by (meson bind_returns_heap_I is_OK_returns_heap_I is_OK_returns_result_E)
+
+lemma bind_is_OK_I [intro]:
+ assumes "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> f \<rightarrow>\<^sub>h h'" and "h' \<turnstile> ok (g x)"
+ shows "h \<turnstile> ok (f \<bind> g)"
+ by (meson assms(1) assms(2) assms(3) bind_returns_heap_I is_OK_returns_heap_E
+ is_OK_returns_heap_I)
+
+lemma bind_is_OK_I2 [intro]:
+ assumes "h \<turnstile> ok f" and "\<And>x h'. h \<turnstile> f \<rightarrow>\<^sub>r x \<Longrightarrow> h \<turnstile> f \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> ok (g x)"
+ shows "h \<turnstile> ok (f \<bind> g)"
+ using assms by blast
+
+lemma bind_is_OK_pure_I [intro]:
+ assumes "pure f h" and "h \<turnstile> ok f" and "\<And>x. h \<turnstile> f \<rightarrow>\<^sub>r x \<Longrightarrow> h \<turnstile> ok (g x)"
+ shows "h \<turnstile> ok (f \<bind> g)"
+ using assms by blast
+
+lemma bind_pure_I:
+ assumes "pure f h" and "\<And>x. h \<turnstile> f \<rightarrow>\<^sub>r x \<Longrightarrow> pure (g x) h"
+ shows "pure (f \<bind> g) h"
+ using assms
+ by (metis bind_returns_heap_E2 pure_def pure_returns_heap_eq is_OK_returns_heap_E)
+
+lemma pure_pure:
+ assumes "h \<turnstile> ok f" and "pure f h"
+ shows "h \<turnstile> f \<rightarrow>\<^sub>h h"
+ using assms returns_heap_eq
+ unfolding pure_def
+ by auto
+
+lemma bind_returns_error_eq:
+ assumes "h \<turnstile> f \<rightarrow>\<^sub>e e"
+ and "h \<turnstile> g \<rightarrow>\<^sub>e e"
+ shows "h \<turnstile> f = h \<turnstile> g"
+ using assms
+ by(auto simp add: returns_error_def split: sum.splits)
+
+subsection \<open>Map\<close>
+
+fun map_M :: "('x \<Rightarrow> ('heap, 'e, 'result) prog) \<Rightarrow> 'x list \<Rightarrow> ('heap, 'e, 'result list) prog"
+ where
+ "map_M f [] = return []"
+ | "map_M f (x#xs) = do {
+ y \<leftarrow> f x;
+ ys \<leftarrow> map_M f xs;
+ return (y # ys)
+ }"
+
+lemma map_M_ok_I [intro]:
+ "(\<And>x. x \<in> set xs \<Longrightarrow> h \<turnstile> ok (f x)) \<Longrightarrow> (\<And>x. x \<in> set xs \<Longrightarrow> pure (f x) h) \<Longrightarrow> h \<turnstile> ok (map_M f xs)"
+ apply(induct xs)
+ by (simp_all add: bind_is_OK_I2 bind_is_OK_pure_I)
+
+lemma map_M_pure_I : "\<And>h. (\<And>x. x \<in> set xs \<Longrightarrow> pure (f x) h) \<Longrightarrow> pure (map_M f xs) h"
+ apply(induct xs)
+ apply(simp)
+ by(auto intro!: bind_pure_I)
+
+lemma map_M_pure_E :
+ assumes "h \<turnstile> map_M g xs \<rightarrow>\<^sub>r ys" and "x \<in> set xs" and "\<And>x h. x \<in> set xs \<Longrightarrow> pure (g x) h"
+ obtains y where "h \<turnstile> g x \<rightarrow>\<^sub>r y" and "y \<in> set ys"
+ apply(insert assms, induct xs arbitrary: ys)
+ apply(simp)
+ apply(auto elim!: bind_returns_result_E)[1]
+ by (metis (full_types) pure_returns_heap_eq)
+
+lemma map_M_pure_E2:
+ assumes "h \<turnstile> map_M g xs \<rightarrow>\<^sub>r ys" and "y \<in> set ys" and "\<And>x h. x \<in> set xs \<Longrightarrow> pure (g x) h"
+ obtains x where "h \<turnstile> g x \<rightarrow>\<^sub>r y" and "x \<in> set xs"
+ apply(insert assms, induct xs arbitrary: ys)
+ apply(simp)
+ apply(auto elim!: bind_returns_result_E)[1]
+ by (metis (full_types) pure_returns_heap_eq)
+
+
+subsection \<open>Forall\<close>
+
+fun forall_M :: "('y \<Rightarrow> ('heap, 'e, 'result) prog) \<Rightarrow> 'y list \<Rightarrow> ('heap, 'e, unit) prog"
+ where
+ "forall_M P [] = return ()"
+ | "forall_M P (x # xs) = do {
+ P x;
+ forall_M P xs
+ }"
+
+
+lemma pure_forall_M_I: "(\<And>x. x \<in> set xs \<Longrightarrow> pure (P x) h) \<Longrightarrow> pure (forall_M P xs) h"
+ apply(induct xs)
+ by(auto intro!: bind_pure_I)
+
+
+subsection \<open>Fold\<close>
+
+fun fold_M :: "('result \<Rightarrow> 'y \<Rightarrow> ('heap, 'e, 'result) prog) \<Rightarrow> 'result \<Rightarrow> 'y list
+ \<Rightarrow> ('heap, 'e, 'result) prog"
+ where
+ "fold_M f d [] = return d" |
+ "fold_M f d (x # xs) = do { y \<leftarrow> f d x; fold_M f y xs }"
+
+lemma fold_M_pure_I : "(\<And>d x. pure (f d x) h) \<Longrightarrow> (\<And>d. pure (fold_M f d xs) h)"
+ apply(induct xs)
+ by(auto intro: bind_pure_I)
+
+subsection \<open>Filter\<close>
+
+fun filter_M :: "('x \<Rightarrow> ('heap, 'e, bool) prog) \<Rightarrow> 'x list \<Rightarrow> ('heap, 'e, 'x list) prog"
+ where
+ "filter_M P [] = return []"
+ | "filter_M P (x#xs) = do {
+ p \<leftarrow> P x;
+ ys \<leftarrow> filter_M P xs;
+ return (if p then x # ys else ys)
+ }"
+
+lemma filter_M_pure_I [intro]: "(\<And>x. x \<in> set xs \<Longrightarrow> pure (P x) h) \<Longrightarrow> pure (filter_M P xs)h"
+ apply(induct xs)
+ by(auto intro!: bind_pure_I)
+
+lemma filter_M_is_OK_I [intro]:
+ "(\<And>x. x \<in> set xs \<Longrightarrow> h \<turnstile> ok (P x)) \<Longrightarrow> (\<And>x. x \<in> set xs \<Longrightarrow> pure (P x) h) \<Longrightarrow> h \<turnstile> ok (filter_M P xs)"
+ apply(induct xs)
+ apply(simp)
+ by(auto intro!: bind_is_OK_pure_I)
+
+lemma filter_M_not_more_elements:
+ assumes "h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys" and "\<And>x. x \<in> set xs \<Longrightarrow> pure (P x) h" and "x \<in> set ys"
+ shows "x \<in> set xs"
+ apply(insert assms, induct xs arbitrary: ys)
+ by(auto elim!: bind_returns_result_E2 split: if_splits intro!: set_ConsD)
+
+lemma filter_M_in_result_if_ok:
+ assumes "h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys" and "\<And>h x. x \<in> set xs \<Longrightarrow> pure (P x) h" and "x \<in> set xs" and
+ "h \<turnstile> P x \<rightarrow>\<^sub>r True"
+ shows "x \<in> set ys"
+ apply(insert assms, induct xs arbitrary: ys)
+ apply(simp)
+ apply(auto elim!: bind_returns_result_E2)[1]
+ by (metis returns_result_eq)
+
+lemma filter_M_holds_for_result:
+ assumes "h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys" and "x \<in> set ys" and "\<And>x h. x \<in> set xs \<Longrightarrow> pure (P x) h"
+ shows "h \<turnstile> P x \<rightarrow>\<^sub>r True"
+ apply(insert assms, induct xs arbitrary: ys)
+ by(auto elim!: bind_returns_result_E2 split: if_splits intro!: set_ConsD)
+
+lemma filter_M_empty_I:
+ assumes "\<And>x. pure (P x) h"
+ and "\<forall>x \<in> set xs. h \<turnstile> P x \<rightarrow>\<^sub>r False"
+ shows "h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r []"
+ using assms
+ apply(induct xs)
+ by(auto intro!: bind_pure_returns_result_I)
+
+lemma filter_M_subset_2: "h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys \<Longrightarrow> h' \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys'
+ \<Longrightarrow> (\<And>x. pure (P x) h) \<Longrightarrow> (\<And>x. pure (P x) h')
+ \<Longrightarrow> (\<forall>b. \<forall>x \<in> set xs. h \<turnstile> P x \<rightarrow>\<^sub>r True \<longrightarrow> h' \<turnstile> P x \<rightarrow>\<^sub>r b \<longrightarrow> b)
+ \<Longrightarrow> set ys \<subseteq> set ys'"
+proof -
+ assume 1: "h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys" and 2: "h' \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys'"
+ and 3: "(\<And>x. pure (P x) h)" and "(\<And>x. pure (P x) h')"
+ and 4: "\<forall>b. \<forall>x\<in>set xs. h \<turnstile> P x \<rightarrow>\<^sub>r True \<longrightarrow> h' \<turnstile> P x \<rightarrow>\<^sub>r b \<longrightarrow> b"
+ have h1: "\<forall>x \<in> set xs. h' \<turnstile> ok (P x)"
+ using 2 3 \<open>(\<And>x. pure (P x) h')\<close>
+ apply(induct xs arbitrary: ys')
+ by(auto elim!: bind_returns_result_E2)
+ then have 5: "\<forall>x\<in>set xs. h \<turnstile> P x \<rightarrow>\<^sub>r True \<longrightarrow> h' \<turnstile> P x \<rightarrow>\<^sub>r True"
+ using 4
+ apply(auto)[1]
+ by (metis is_OK_returns_result_E)
+ show ?thesis
+ using 1 2 3 5 \<open>(\<And>x. pure (P x) h')\<close>
+ apply(induct xs arbitrary: ys ys')
+ apply(auto)[1]
+ apply(auto elim!: bind_returns_result_E2 split: if_splits)[1]
+ apply auto[1]
+ apply auto[1]
+ apply(metis returns_result_eq)
+ apply auto[1]
+ apply auto[1]
+ apply auto[1]
+ by(auto)
+qed
+
+lemma filter_M_subset: "h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys \<Longrightarrow> set ys \<subseteq> set xs"
+ apply(induct xs arbitrary: h ys)
+ apply(auto)[1]
+ apply(auto elim!: bind_returns_result_E split: if_splits)[1]
+ apply blast
+ by blast
+
+lemma filter_M_distinct: "h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys \<Longrightarrow> distinct xs \<Longrightarrow> distinct ys"
+ apply(induct xs arbitrary: h ys)
+ apply(auto)[1]
+ using filter_M_subset
+ apply(auto elim!: bind_returns_result_E)[1]
+ by fastforce
+
+lemma filter_M_filter: "h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys \<Longrightarrow> (\<And>x. x \<in> set xs \<Longrightarrow> pure (P x) h)
+ \<Longrightarrow> (\<forall>x \<in> set xs. h \<turnstile> ok P x) \<and> ys = filter (\<lambda>x. |h \<turnstile> P x|\<^sub>r) xs"
+ apply(induct xs arbitrary: ys)
+ by(auto elim!: bind_returns_result_E2)
+
+lemma filter_M_filter2: "(\<And>x. x \<in> set xs \<Longrightarrow> pure (P x) h \<and> h \<turnstile> ok P x)
+ \<Longrightarrow> filter (\<lambda>x. |h \<turnstile> P x|\<^sub>r) xs = ys \<Longrightarrow> h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys"
+ apply(induct xs arbitrary: ys)
+ by(auto elim!: bind_returns_result_E2 intro!: bind_pure_returns_result_I)
+
+lemma filter_ex1: "\<exists>!x \<in> set xs. P x \<Longrightarrow> P x \<Longrightarrow> x \<in> set xs \<Longrightarrow> distinct xs
+ \<Longrightarrow> filter P xs = [x]"
+ apply(auto)[1]
+ apply(induct xs)
+ apply(auto)[1]
+ apply(auto)[1]
+ using filter_empty_conv by fastforce
+
+lemma filter_M_ex1:
+ assumes "h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys"
+ and "x \<in> set xs"
+ and "\<exists>!x \<in> set xs. h \<turnstile> P x \<rightarrow>\<^sub>r True"
+ and "\<And>x. x \<in> set xs \<Longrightarrow> pure (P x) h"
+ and "distinct xs"
+ and "h \<turnstile> P x \<rightarrow>\<^sub>r True"
+ shows "ys = [x]"
+proof -
+ have *: "\<exists>!x \<in> set xs. |h \<turnstile> P x|\<^sub>r"
+ apply(insert assms(1) assms(3) assms(4))
+ apply(drule filter_M_filter)
+ apply(simp)
+ apply(auto simp add: select_result_I2)[1]
+ by (metis (full_types) is_OK_returns_result_E select_result_I2)
+ then show ?thesis
+ apply(insert assms(1) assms(4))
+ apply(drule filter_M_filter)
+ apply(auto)[1]
+ by (metis * assms(2) assms(5) assms(6) distinct_filter
+ distinct_length_2_or_more filter_empty_conv filter_set list.exhaust
+ list.set_intros(1) list.set_intros(2) member_filter select_result_I2)
+qed
+
+lemma filter_M_eq:
+ assumes "\<And>x. pure (P x) h" and "\<And>x. pure (P x) h'"
+ and "\<And>b x. x \<in> set xs \<Longrightarrow> h \<turnstile> P x \<rightarrow>\<^sub>r b = h' \<turnstile> P x \<rightarrow>\<^sub>r b"
+ shows "h \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys \<longleftrightarrow> h' \<turnstile> filter_M P xs \<rightarrow>\<^sub>r ys"
+ using assms
+ apply (induct xs arbitrary: ys)
+ by(auto elim!: bind_returns_result_E2 intro!: bind_pure_returns_result_I
+ dest: returns_result_eq)
+
+
+subsection \<open>Map Filter\<close>
+
+definition map_filter_M :: "('x \<Rightarrow> ('heap, 'e, 'y option) prog) \<Rightarrow> 'x list
+ \<Rightarrow> ('heap, 'e, 'y list) prog"
+ where
+ "map_filter_M f xs = do {
+ ys_opts \<leftarrow> map_M f xs;
+ ys_no_opts \<leftarrow> filter_M (\<lambda>x. return (x \<noteq> None)) ys_opts;
+ map_M (\<lambda>x. return (the x)) ys_no_opts
+ }"
+
+lemma map_filter_M_pure: "(\<And>x h. x \<in> set xs \<Longrightarrow> pure (f x) h) \<Longrightarrow> pure (map_filter_M f xs) h"
+ by(auto simp add: map_filter_M_def map_M_pure_I intro!: bind_pure_I)
+
+lemma map_filter_M_pure_E:
+ assumes "h \<turnstile> (map_filter_M::('x \<Rightarrow> ('heap, 'e, 'y option) prog) \<Rightarrow> 'x list
+ \<Rightarrow> ('heap, 'e, 'y list) prog) f xs \<rightarrow>\<^sub>r ys" and "y \<in> set ys" and "\<And>x h. x \<in> set xs \<Longrightarrow> pure (f x) h"
+ obtains x where "h \<turnstile> f x \<rightarrow>\<^sub>r Some y" and "x \<in> set xs"
+proof -
+ obtain ys_opts ys_no_opts where
+ ys_opts: "h \<turnstile> map_M f xs \<rightarrow>\<^sub>r ys_opts" and
+ ys_no_opts: "h \<turnstile> filter_M (\<lambda>x. (return (x \<noteq> None)::('heap, 'e, bool) prog)) ys_opts \<rightarrow>\<^sub>r ys_no_opts" and
+ ys: "h \<turnstile> map_M (\<lambda>x. (return (the x)::('heap, 'e, 'y) prog)) ys_no_opts \<rightarrow>\<^sub>r ys"
+ using assms
+ by(auto simp add: map_filter_M_def map_M_pure_I elim!: bind_returns_result_E2)
+ have "\<forall>y \<in> set ys_no_opts. y \<noteq> None"
+ using ys_no_opts filter_M_holds_for_result
+ by fastforce
+ then have "Some y \<in> set ys_no_opts"
+ using map_M_pure_E2 ys \<open>y \<in> set ys\<close>
+ by (metis (no_types, lifting) option.collapse return_pure return_returns_result)
+ then have "Some y \<in> set ys_opts"
+ using filter_M_subset ys_no_opts by fastforce
+ then show "(\<And>x. h \<turnstile> f x \<rightarrow>\<^sub>r Some y \<Longrightarrow> x \<in> set xs \<Longrightarrow> thesis) \<Longrightarrow> thesis"
+ by (metis assms(3) map_M_pure_E2 ys_opts)
+qed
+
+
+subsection \<open>Iterate\<close>
+
+fun iterate_M :: "('heap, 'e, 'result) prog list \<Rightarrow> ('heap, 'e, 'result) prog"
+ where
+ "iterate_M [] = return undefined"
+ | "iterate_M (x # xs) = x \<bind> (\<lambda>_. iterate_M xs)"
+
+
+lemma iterate_M_concat:
+ assumes "h \<turnstile> iterate_M xs \<rightarrow>\<^sub>h h'"
+ and "h' \<turnstile> iterate_M ys \<rightarrow>\<^sub>h h''"
+ shows "h \<turnstile> iterate_M (xs @ ys) \<rightarrow>\<^sub>h h''"
+ using assms
+ apply(induct "xs" arbitrary: h h'')
+ apply(simp)
+ apply(auto)[1]
+ by (meson bind_returns_heap_E bind_returns_heap_I)
+
+subsection\<open>Miscellaneous Rules\<close>
+
+lemma execute_bind_simp:
+ assumes "h \<turnstile> f \<rightarrow>\<^sub>r x" and "h \<turnstile> f \<rightarrow>\<^sub>h h'"
+ shows "h \<turnstile> f \<bind> g = h' \<turnstile> g x"
+ using assms
+ by(auto simp add: returns_result_def returns_heap_def bind_def execute_def
+ split: sum.splits)
+
+lemma bind_cong [fundef_cong]:
+ fixes f1 f2 :: "('heap, 'e, 'result) prog"
+ and g1 g2 :: "'result \<Rightarrow> ('heap, 'e, 'result2) prog"
+ assumes "h \<turnstile> f1 = h \<turnstile> f2"
+ and "\<And>y h'. h \<turnstile> f1 \<rightarrow>\<^sub>r y \<Longrightarrow> h \<turnstile> f1 \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> g1 y = h' \<turnstile> g2 y"
+ shows "h \<turnstile> (f1 \<bind> g1) = h \<turnstile> (f2 \<bind> g2)"
+ apply(insert assms, cases "h \<turnstile> f1")
+ by(auto simp add: bind_def returns_result_def returns_heap_def execute_def
+ split: sum.splits)
+
+lemma bind_cong_2:
+ assumes "pure f h" and "pure f h'"
+ and "\<And>x. h \<turnstile> f \<rightarrow>\<^sub>r x = h' \<turnstile> f \<rightarrow>\<^sub>r x"
+ and "\<And>x. h \<turnstile> f \<rightarrow>\<^sub>r x \<Longrightarrow> h \<turnstile> g x \<rightarrow>\<^sub>r y = h' \<turnstile> g x \<rightarrow>\<^sub>r y'"
+ shows "h \<turnstile> f \<bind> g \<rightarrow>\<^sub>r y = h' \<turnstile> f \<bind> g \<rightarrow>\<^sub>r y'"
+ using assms
+ by(auto intro!: bind_pure_returns_result_I elim!: bind_returns_result_E2)
+
+lemma bind_case_cong [fundef_cong]:
+ assumes "x = x'" and "\<And>a. x = Some a \<Longrightarrow> f a h = f' a h"
+ shows "(case x of Some a \<Rightarrow> f a | None \<Rightarrow> g) h = (case x' of Some a \<Rightarrow> f' a | None \<Rightarrow> g) h"
+ by (insert assms, simp add: option.case_eq_if)
+
+
+subsection \<open>Reasoning About Reads and Writes\<close>
+
+definition preserved :: "('heap, 'e, 'result) prog \<Rightarrow> 'heap \<Rightarrow> 'heap \<Rightarrow> bool"
+ where
+ "preserved f h h' \<longleftrightarrow> (\<forall>x. h \<turnstile> f \<rightarrow>\<^sub>r x \<longleftrightarrow> h' \<turnstile> f \<rightarrow>\<^sub>r x)"
+
+lemma preserved_code [code]:
+ "preserved f h h' = (((h \<turnstile> ok f) \<and> (h' \<turnstile> ok f) \<and> |h \<turnstile> f|\<^sub>r = |h' \<turnstile> f|\<^sub>r) \<or> ((\<not>h \<turnstile> ok f) \<and> (\<not>h' \<turnstile> ok f)))"
+ apply(auto simp add: preserved_def)[1]
+ apply (meson is_OK_returns_result_E is_OK_returns_result_I)+
+ done
+
+lemma reflp_preserved_f [simp]: "reflp (preserved f)"
+ by(auto simp add: preserved_def reflp_def)
+lemma transp_preserved_f [simp]: "transp (preserved f)"
+ by(auto simp add: preserved_def transp_def)
+
+
+definition
+ all_args :: "('a \<Rightarrow> ('heap, 'e, 'result) prog) \<Rightarrow> ('heap, 'e, 'result) prog set"
+ where
+ "all_args f = (\<Union>arg. {f arg})"
+
+
+definition
+ reads :: "('heap \<Rightarrow> 'heap \<Rightarrow> bool) set \<Rightarrow> ('heap, 'e, 'result) prog \<Rightarrow> 'heap
+ \<Rightarrow> 'heap \<Rightarrow> bool"
+ where
+ "reads S getter h h' \<longleftrightarrow> (\<forall>P \<in> S. reflp P \<and> transp P) \<and> ((\<forall>P \<in> S. P h h')
+ \<longrightarrow> preserved getter h h')"
+
+lemma reads_singleton [simp]: "reads {preserved f} f h h'"
+ by(auto simp add: reads_def)
+
+lemma reads_bind_pure:
+ assumes "pure f h" and "pure f h'"
+ and "reads S f h h'"
+ and "\<And>x. h \<turnstile> f \<rightarrow>\<^sub>r x \<Longrightarrow> reads S (g x) h h'"
+ shows "reads S (f \<bind> g) h h'"
+ using assms
+ by(auto simp add: reads_def pure_pure preserved_def
+ intro!: bind_pure_returns_result_I is_OK_returns_result_I
+ dest: pure_returns_heap_eq
+ elim!: bind_returns_result_E)
+
+lemma reads_insert_writes_set_left:
+ "\<forall>P \<in> S. reflp P \<and> transp P \<Longrightarrow> reads {getter} f h h' \<Longrightarrow> reads (insert getter S) f h h'"
+ unfolding reads_def by simp
+
+lemma reads_insert_writes_set_right:
+ "reflp getter \<Longrightarrow> transp getter \<Longrightarrow> reads S f h h' \<Longrightarrow> reads (insert getter S) f h h'"
+ unfolding reads_def by blast
+
+lemma reads_subset:
+ "reads S f h h' \<Longrightarrow> \<forall>P \<in> S' - S. reflp P \<and> transp P \<Longrightarrow> S \<subseteq> S' \<Longrightarrow> reads S' f h h'"
+ by(auto simp add: reads_def)
+
+lemma return_reads [simp]: "reads {} (return x) h h'"
+ by(simp add: reads_def preserved_def)
+
+lemma error_reads [simp]: "reads {} (error e) h h'"
+ by(simp add: reads_def preserved_def)
+
+lemma noop_reads [simp]: "reads {} noop h h'"
+ by(simp add: reads_def noop_def preserved_def)
+
+lemma filter_M_reads:
+ assumes "\<And>x. x \<in> set xs \<Longrightarrow> pure (P x) h" and "\<And>x. x \<in> set xs \<Longrightarrow> pure (P x) h'"
+ and "\<And>x. x \<in> set xs \<Longrightarrow> reads S (P x) h h'"
+ and "\<forall>P \<in> S. reflp P \<and> transp P"
+ shows "reads S (filter_M P xs) h h'"
+ using assms
+ apply(induct xs)
+ by(auto intro: reads_subset[OF return_reads] intro!: reads_bind_pure)
+
+definition writes ::
+ "('heap, 'e, 'result) prog set \<Rightarrow> ('heap, 'e, 'result2) prog \<Rightarrow> 'heap \<Rightarrow> 'heap \<Rightarrow> bool"
+ where
+ "writes S setter h h'
+ \<longleftrightarrow> (h \<turnstile> setter \<rightarrow>\<^sub>h h' \<longrightarrow> (\<exists>progs. set progs \<subseteq> S \<and> h \<turnstile> iterate_M progs \<rightarrow>\<^sub>h h'))"
+
+lemma writes_singleton [simp]: "writes (all_args f) (f a) h h'"
+ apply(auto simp add: writes_def all_args_def)[1]
+ apply(rule exI[where x="[f a]"])
+ by(auto)
+
+lemma writes_singleton2 [simp]: "writes {f} f h h'"
+ apply(auto simp add: writes_def all_args_def)[1]
+ apply(rule exI[where x="[f]"])
+ by(auto)
+
+lemma writes_union_left_I:
+ assumes "writes S f h h'"
+ shows "writes (S \<union> S') f h h'"
+ using assms
+ by(auto simp add: writes_def)
+
+lemma writes_union_right_I:
+ assumes "writes S' f h h'"
+ shows "writes (S \<union> S') f h h'"
+ using assms
+ by(auto simp add: writes_def)
+
+lemma writes_union_minus_split:
+ assumes "writes (S - S2) f h h'"
+ and "writes (S' - S2) f h h'"
+ shows "writes ((S \<union> S') - S2) f h h'"
+ using assms
+ by(auto simp add: writes_def)
+
+lemma writes_subset: "writes S f h h' \<Longrightarrow> S \<subseteq> S' \<Longrightarrow> writes S' f h h'"
+ by(auto simp add: writes_def)
+
+lemma writes_error [simp]: "writes S (error e) h h'"
+ by(simp add: writes_def)
+
+lemma writes_not_ok [simp]: "\<not>h \<turnstile> ok f \<Longrightarrow> writes S f h h'"
+ by(auto simp add: writes_def)
+
+lemma writes_pure [simp]:
+ assumes "pure f h"
+ shows "writes S f h h'"
+ using assms
+ apply(auto simp add: writes_def)[1]
+ by (metis bot.extremum iterate_M.simps(1) list.set(1) pure_returns_heap_eq return_returns_heap)
+
+lemma writes_bind:
+ assumes "\<And>h2. writes S f h h2"
+ assumes "\<And>x h2. h \<turnstile> f \<rightarrow>\<^sub>r x \<Longrightarrow> h \<turnstile> f \<rightarrow>\<^sub>h h2 \<Longrightarrow> writes S (g x) h2 h'"
+ shows "writes S (f \<bind> g) h h'"
+ using assms
+ apply(auto simp add: writes_def elim!: bind_returns_heap_E)[1]
+ by (metis iterate_M_concat le_supI set_append)
+
+lemma writes_bind_pure:
+ assumes "pure f h"
+ assumes "\<And>x. h \<turnstile> f \<rightarrow>\<^sub>r x \<Longrightarrow> writes S (g x) h h'"
+ shows "writes S (f \<bind> g) h h'"
+ using assms
+ by(auto simp add: writes_def elim!: bind_returns_heap_E2)
+
+lemma writes_small_big:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> P h h'"
+ assumes "reflp P"
+ assumes "transp P"
+ shows "P h h'"
+proof -
+ obtain progs where "set progs \<subseteq> SW" and iterate: "h \<turnstile> iterate_M progs \<rightarrow>\<^sub>h h'"
+ by (meson assms(1) assms(2) writes_def)
+ then have "\<And>h h'. \<forall>prog \<in> set progs. h \<turnstile> prog \<rightarrow>\<^sub>h h' \<longrightarrow> P h h'"
+ using assms(3) by auto
+ with iterate assms(4) assms(5) have "h \<turnstile> iterate_M progs \<rightarrow>\<^sub>h h' \<Longrightarrow> P h h'"
+ proof(induct progs arbitrary: h)
+ case Nil
+ then show ?case
+ using reflpE by force
+ next
+ case (Cons a progs)
+ then show ?case
+ apply(auto elim!: bind_returns_heap_E)[1]
+ by (metis (full_types) transpD)
+ qed
+ then show ?thesis
+ using assms(1) iterate by blast
+qed
+
+lemma reads_writes_preserved:
+ assumes "reads SR getter h h'"
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h'. \<forall>w \<in> SW. h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> SR. r h h')"
+ shows "h \<turnstile> getter \<rightarrow>\<^sub>r x \<longleftrightarrow> h' \<turnstile> getter \<rightarrow>\<^sub>r x"
+proof -
+ obtain progs where "set progs \<subseteq> SW" and iterate: "h \<turnstile> iterate_M progs \<rightarrow>\<^sub>h h'"
+ by (meson assms(2) assms(3) writes_def)
+ then have "\<And>h h'. \<forall>prog \<in> set progs. h \<turnstile> prog \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> SR. r h h')"
+ using assms(4) by blast
+ with iterate have "\<forall>r \<in> SR. r h h'"
+ using writes_small_big assms(1) unfolding reads_def
+ by (metis assms(2) assms(3) assms(4))
+ then show ?thesis
+ using assms(1)
+ by (simp add: preserved_def reads_def)
+qed
+
+lemma reads_writes_separate_forwards:
+ assumes "reads SR getter h h'"
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> getter \<rightarrow>\<^sub>r x"
+ assumes "\<And>h h'. \<forall>w \<in> SW. h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> SR. r h h')"
+ shows "h' \<turnstile> getter \<rightarrow>\<^sub>r x"
+ using reads_writes_preserved[OF assms(1) assms(2) assms(3) assms(5)] assms(4)
+ by(auto simp add: preserved_def)
+
+lemma reads_writes_separate_backwards:
+ assumes "reads SR getter h h'"
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "h' \<turnstile> getter \<rightarrow>\<^sub>r x"
+ assumes "\<And>h h'. \<forall>w \<in> SW. h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> SR. r h h')"
+ shows "h \<turnstile> getter \<rightarrow>\<^sub>r x"
+ using reads_writes_preserved[OF assms(1) assms(2) assms(3) assms(5)] assms(4)
+ by(auto simp add: preserved_def)
+
+end
diff --git a/thys/Core_SC_DOM/common/preliminaries/Hiding_Type_Variables.thy b/thys/Core_SC_DOM/common/preliminaries/Hiding_Type_Variables.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/preliminaries/Hiding_Type_Variables.thy
@@ -0,0 +1,584 @@
+(***********************************************************************************
+ * Copyright (c) 2018 Achim D. Brucker
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ * Repository: https://git.logicalhacking.com/adbrucker/isabelle-hacks/
+ * Dependencies: None (assert.thy is used for testing the theory but it is
+ * not required for providing the functionality of this hack)
+ ***********************************************************************************)
+
+(*
+ This file is based on commit 8a5e95421521c36ab71ab2711435a9bc0fa2c5cc from upstream
+ (https://git.logicalhacking.com/adbrucker/isabelle-hacks/). Merely the dependency to
+ Assert.thy has been removed by disabling the example section (which include assert
+ checks).
+*)
+
+section\<open>Hiding Type Variables\<close>
+text\<open> This theory\footnote{This theory can be used ``stand-alone,'' i.e., this theory is
+ not specific to the DOM formalization. The latest version is part of the ``Isabelle Hacks''
+ repository: \url{https://git.logicalhacking.com/adbrucker/isabelle-hacks/}.} implements
+ a mechanism for declaring default type variables for data types. This comes handy for complex
+ data types with many type variables.\<close>
+theory
+ "Hiding_Type_Variables"
+imports
+ Main
+keywords
+ "register_default_tvars"
+ "update_default_tvars_mode"::thy_decl
+begin
+(*<*)
+section\<open>Implementation\<close>
+subsection\<open>Theory Managed Data Structure\<close>
+ML\<open>
+signature HIDE_TVAR = sig
+ datatype print_mode = print_all | print | noprint
+ datatype tvar_subst = right | left
+ datatype parse_mode = parse | noparse
+ type hide_varT = {
+ name: string,
+ tvars: typ list,
+ typ_syn_tab : (string * typ list*string) Symtab.table,
+ print_mode: print_mode,
+ parse_mode: parse_mode
+ }
+ val parse_print_mode : string -> print_mode
+ val parse_parse_mode : string -> parse_mode
+ val register : string -> print_mode option -> parse_mode option ->
+ theory -> theory
+ val update_mode : string -> print_mode option -> parse_mode option ->
+ theory -> theory
+ val lookup : theory -> string -> hide_varT option
+ val hide_tvar_tr' : string -> Proof.context -> term list -> term
+ val hide_tvar_ast_tr : Proof.context -> Ast.ast list -> Ast.ast
+ val hide_tvar_subst_ast_tr : tvar_subst -> Proof.context -> Ast.ast list
+ -> Ast.ast
+ val hide_tvar_subst_return_ast_tr : tvar_subst -> Proof.context
+ -> Ast.ast list -> Ast.ast
+end
+
+structure Hide_Tvar : HIDE_TVAR = struct
+ datatype print_mode = print_all | print | noprint
+ datatype tvar_subst = right | left
+ datatype parse_mode = parse | noparse
+ type hide_varT = {
+ name: string,
+ tvars: typ list,
+ typ_syn_tab : (string * typ list*string) Symtab.table,
+ print_mode: print_mode,
+ parse_mode: parse_mode
+ }
+ type hide_tvar_tab = (hide_varT) Symtab.table
+ fun hide_tvar_eq (a, a') = (#name a) = (#name a')
+ fun merge_tvar_tab (tab,tab') = Symtab.merge hide_tvar_eq (tab,tab')
+
+ structure Data = Generic_Data
+ (
+ type T = hide_tvar_tab
+ val empty = Symtab.empty:hide_tvar_tab
+ val extend = I
+ fun merge(t1,t2) = merge_tvar_tab (t1, t2)
+ );
+
+
+ fun parse_print_mode "print_all" = print_all
+ | parse_print_mode "print" = print
+ | parse_print_mode "noprint" = noprint
+ | parse_print_mode s = error("Print mode not supported: "^s)
+
+ fun parse_parse_mode "parse" = parse
+ | parse_parse_mode "noparse" = noparse
+ | parse_parse_mode s = error("Parse mode not supported: "^s)
+
+ fun update_mode typ_str print_mode parse_mode thy =
+ let
+ val ctx = Toplevel.context_of(Toplevel.theory_toplevel thy)
+ val typ = Syntax.parse_typ ctx typ_str (* no type checking *)
+ val name = case typ of
+ Type(name,_) => name
+ | _ => error("Complex type not (yet) supported.")
+ fun update tab =
+ let
+ val old_entry = (case Symtab.lookup tab name of
+ SOME t => t
+ | NONE => error ("Type shorthand not registered: "^name))
+ val print_m = case print_mode of
+ SOME m => m
+ | NONE => #print_mode old_entry
+ val parse_m = case parse_mode of
+ SOME m => m
+ | NONE => #parse_mode old_entry
+ val entry = {
+ name = name,
+ tvars = #tvars old_entry,
+ typ_syn_tab = #typ_syn_tab old_entry,
+ print_mode = print_m,
+ parse_mode = parse_m
+ }
+ in
+ Symtab.update (name,entry) tab
+ end
+ in
+ Context.theory_of ( (Data.map update) (Context.Theory thy))
+ end
+
+ fun lookup thy name =
+ let
+ val tab = (Data.get o Context.Theory) thy
+ in
+ Symtab.lookup tab name
+ end
+
+ fun obtain_normalized_vname lookup_table vname =
+ case List.find (fn e => fst e = vname) lookup_table of
+ SOME (_,idx) => (lookup_table, Int.toString idx)
+ | NONE => let
+ fun max_idx [] = 0
+ | max_idx ((_,idx)::lt) = Int.max(idx,max_idx lt)
+
+ val idx = (max_idx lookup_table ) + 1
+ in
+ ((vname,idx)::lookup_table, Int.toString idx) end
+
+ fun normalize_typvar_type lt (Type (a, Ts)) =
+ let
+ fun switch (a,b) = (b,a)
+ val (Ts', lt') = fold_map (fn t => fn lt => switch (normalize_typvar_type lt t)) Ts lt
+ in
+ (lt', Type (a, Ts'))
+ end
+ | normalize_typvar_type lt (TFree (vname, S)) =
+ let
+ val (lt, vname) = obtain_normalized_vname lt (vname)
+ in
+ (lt, TFree( vname, S))
+ end
+ | normalize_typvar_type lt (TVar (xi, S)) =
+ let
+ val (lt, vname) = obtain_normalized_vname lt (Term.string_of_vname xi)
+ in
+ (lt, TFree( vname, S))
+ end
+
+ fun normalize_typvar_type' t = snd ( normalize_typvar_type [] t)
+
+ fun mk_p s = s (* "("^s^")" *)
+
+ fun key_of_type (Type(a, TS)) = mk_p (a^String.concat(map key_of_type TS))
+ | key_of_type (TFree (vname, _)) = mk_p vname
+ | key_of_type (TVar (xi, _ )) = mk_p (Term.string_of_vname xi)
+ val key_of_type' = key_of_type o normalize_typvar_type'
+
+
+ fun normalize_typvar_term lt (Const (a, t)) = (lt, Const(a, t))
+ | normalize_typvar_term lt (Free (a, t)) = let
+ val (lt, vname) = obtain_normalized_vname lt a
+ in
+ (lt, Free(vname,t))
+ end
+ | normalize_typvar_term lt (Var (xi, t)) =
+ let
+ val (lt, vname) = obtain_normalized_vname lt (Term.string_of_vname xi)
+ in
+ (lt, Free(vname,t))
+ end
+ | normalize_typvar_term lt (Bound (i)) = (lt, Bound(i))
+ | normalize_typvar_term lt (Abs(s,ty,tr)) =
+ let
+ val (lt,tr) = normalize_typvar_term lt tr
+ in
+ (lt, Abs(s,ty,tr))
+ end
+ | normalize_typvar_term lt (t1$t2) =
+ let
+ val (lt,t1) = normalize_typvar_term lt t1
+ val (lt,t2) = normalize_typvar_term lt t2
+ in
+ (lt, t1$t2)
+ end
+
+
+ fun normalize_typvar_term' t = snd(normalize_typvar_term [] t)
+
+ fun key_of_term (Const(s,_)) = if String.isPrefix "\<^type>" s
+ then Lexicon.unmark_type s
+ else ""
+ | key_of_term (Free(s,_)) = s
+ | key_of_term (Var(xi,_)) = Term.string_of_vname xi
+ | key_of_term (Bound(_)) = error("Bound() not supported in key_of_term")
+ | key_of_term (Abs(_,_,_)) = error("Abs() not supported in key_of_term")
+ | key_of_term (t1$t2) = (key_of_term t1)^(key_of_term t2)
+
+ val key_of_term' = key_of_term o normalize_typvar_term'
+
+
+ fun hide_tvar_tr' tname ctx terms =
+ let
+
+ val mtyp = Syntax.parse_typ ctx tname (* no type checking *)
+
+ val (fq_name, _) = case mtyp of
+ Type(s,ts) => (s,ts)
+ | _ => error("Complex type not (yet) supported.")
+
+ val local_name_of = hd o rev o String.fields (fn c => c = #".")
+
+ fun hide_type tname = Syntax.const("(_) "^tname)
+
+ val reg_type_as_term = Term.list_comb(Const(Lexicon.mark_type tname,dummyT),terms)
+ val key = key_of_term' reg_type_as_term
+ val actual_tvars_key = key_of_term reg_type_as_term
+
+ in
+ case lookup (Proof_Context.theory_of ctx) fq_name of
+ NONE => raise Match
+ | SOME e => let
+ val (tname,default_tvars_key) =
+ case Symtab.lookup (#typ_syn_tab e) key of
+ NONE => (local_name_of tname, "")
+ | SOME (s,_,tv) => (local_name_of s,tv)
+ in
+ case (#print_mode e) of
+ print_all => hide_type tname
+ | print => if default_tvars_key=actual_tvars_key
+ then hide_type tname
+ else raise Match
+ | noprint => raise Match
+ end
+ end
+
+ fun hide_tvar_ast_tr ctx ast=
+ let
+ val thy = Proof_Context.theory_of ctx
+
+ fun parse_ast ((Ast.Constant const)::[]) = (const,NONE)
+ | parse_ast ((Ast.Constant sort)::(Ast.Constant const)::[])
+ = (const,SOME sort)
+ | parse_ast _ = error("AST type not supported.")
+
+ val (decorated_name, decorated_sort) = parse_ast ast
+
+ val name = Lexicon.unmark_type decorated_name
+ val default_info = case lookup thy name of
+ NONE => error("No default type vars registered: "^name)
+ | SOME e => e
+ val _ = if #parse_mode default_info = noparse
+ then error("Default type vars disabled (option noparse): "^name)
+ else ()
+ fun name_of_tvar tvar = case tvar of (TFree(n,_)) => n
+ | _ => error("Unsupported type structure.")
+ val type_vars_ast =
+ let fun mk_tvar n =
+ case decorated_sort of
+ NONE => Ast.Variable(name_of_tvar n)
+ | SOME sort => Ast.Appl([Ast.Constant("_ofsort"),
+ Ast.Variable(name_of_tvar n),
+ Ast.Constant(sort)])
+ in
+ map mk_tvar (#tvars default_info)
+ end
+ in
+ Ast.Appl ((Ast.Constant decorated_name)::type_vars_ast)
+ end
+
+ fun register typ_str print_mode parse_mode thy =
+ let
+ val ctx = Toplevel.context_of(Toplevel.theory_toplevel thy)
+ val typ = Syntax.parse_typ ctx typ_str
+ val (name,tvars) = case typ of Type(name,tvars) => (name,tvars)
+ | _ => error("Unsupported type structure.")
+
+ val base_typ = Syntax.read_typ ctx typ_str
+ val (base_name,base_tvars) = case base_typ of Type(name,tvars) => (name,tvars)
+ | _ => error("Unsupported type structure.")
+
+ val base_key = key_of_type' base_typ
+ val base_tvar_key = key_of_type base_typ
+
+ val print_m = case print_mode of
+ SOME m => m
+ | NONE => print_all
+ val parse_m = case parse_mode of
+ SOME m => m
+ | NONE => parse
+ val entry = {
+ name = name,
+ tvars = tvars,
+ typ_syn_tab = Symtab.empty:((string * typ list * string) Symtab.table),
+ print_mode = print_m,
+ parse_mode = parse_m
+ }
+
+ val base_entry = if name = base_name
+ then
+ {
+ name = "",
+ tvars = [],
+ typ_syn_tab = Symtab.empty:((string * typ list * string) Symtab.table),
+ print_mode = noprint,
+ parse_mode = noparse
+ }
+ else case lookup thy base_name of
+ SOME e => e
+ | NONE => error ("No entry found for "^base_name^
+ " (via "^name^")")
+
+ val base_entry = {
+ name = #name base_entry,
+ tvars = #tvars base_entry,
+ typ_syn_tab = Symtab.update (base_key, (name, base_tvars, base_tvar_key))
+ (#typ_syn_tab (base_entry)),
+ print_mode = #print_mode base_entry,
+ parse_mode = #parse_mode base_entry
+ }
+
+ fun reg tab = let
+ val tab = Symtab.update_new(name, entry) tab
+ val tab = if name = base_name
+ then tab
+ else Symtab.update(base_name, base_entry) tab
+ in
+ tab
+ end
+
+ val thy = Sign.print_translation
+ [(Lexicon.mark_type name, hide_tvar_tr' name)] thy
+
+ in
+ Context.theory_of ( (Data.map reg) (Context.Theory thy))
+ handle Symtab.DUP _ => error("Type shorthand already registered: "^name)
+ end
+
+ fun hide_tvar_subst_ast_tr hole ctx (ast::[]) =
+ let
+
+ val thy = Proof_Context.theory_of ctx
+ val (decorated_name, args) = case ast
+ of (Ast.Appl ((Ast.Constant s)::args)) => (s, args)
+ | _ => error "Error in obtaining type constructor."
+
+ val name = Lexicon.unmark_type decorated_name
+ val default_info = case lookup thy name of
+ NONE => error("No default type vars registered: "^name)
+ | SOME e => e
+ val _ = if #parse_mode default_info = noparse
+ then error("Default type vars disabled (option noparse): "^name)
+ else ()
+ fun name_of_tvar tvar = case tvar of (TFree(n,_)) => n
+ | _ => error("Unsupported type structure.")
+ val type_vars_ast = map (fn n => Ast.Variable(name_of_tvar n)) (#tvars default_info)
+ val type_vars_ast = case hole of
+ right => (List.rev(List.drop(List.rev type_vars_ast, List.length args)))@args
+ | left => args@List.drop(type_vars_ast, List.length args)
+ in
+ Ast.Appl ((Ast.Constant decorated_name)::type_vars_ast)
+ end
+ | hide_tvar_subst_ast_tr _ _ _ = error("hide_tvar_subst_ast_tr: empty AST.")
+
+ fun hide_tvar_subst_return_ast_tr hole ctx (retval::constructor::[]) =
+ hide_tvar_subst_ast_tr hole ctx [Ast.Appl (constructor::retval::[])]
+ | hide_tvar_subst_return_ast_tr _ _ _ =
+ error("hide_tvar_subst_return_ast_tr: error in parsing AST")
+
+
+end
+\<close>
+
+
+
+subsection\<open>Register Parse Translations\<close>
+syntax "_tvars_wildcard" :: "type \<Rightarrow> type" ("'('_') _")
+syntax "_tvars_wildcard_retval" :: "type \<Rightarrow> type \<Rightarrow> type" ("'('_, _') _")
+syntax "_tvars_wildcard_sort" :: "sort \<Rightarrow> type \<Rightarrow> type" ("'('_::_') _")
+syntax "_tvars_wildcard_right" :: "type \<Rightarrow> type" ("_ '_..")
+syntax "_tvars_wildcard_left" :: "type \<Rightarrow> type" ("_ ..'_")
+
+parse_ast_translation\<open>
+ [
+ (@{syntax_const "_tvars_wildcard_sort"}, Hide_Tvar.hide_tvar_ast_tr),
+ (@{syntax_const "_tvars_wildcard"}, Hide_Tvar.hide_tvar_ast_tr),
+ (@{syntax_const "_tvars_wildcard_retval"}, Hide_Tvar.hide_tvar_subst_return_ast_tr Hide_Tvar.right),
+ (@{syntax_const "_tvars_wildcard_right"}, Hide_Tvar.hide_tvar_subst_ast_tr Hide_Tvar.right),
+ (@{syntax_const "_tvars_wildcard_left"}, Hide_Tvar.hide_tvar_subst_ast_tr Hide_Tvar.left)
+ ]
+\<close>
+
+subsection\<open>Register Top-Level Isar Commands\<close>
+ML\<open>
+ val modeP = (Parse.$$$ "("
+ |-- (Parse.name --| Parse.$$$ ","
+ -- Parse.name --|
+ Parse.$$$ ")"))
+ val typ_modeP = Parse.typ -- (Scan.optional modeP ("print_all","parse"))
+
+ val _ = Outer_Syntax.command @{command_keyword "register_default_tvars"}
+ "Register default variables (and hiding mechanims) for a type."
+ (typ_modeP >> (fn (typ,(print_m,parse_m)) =>
+ (Toplevel.theory
+ (Hide_Tvar.register typ
+ (SOME (Hide_Tvar.parse_print_mode print_m))
+ (SOME (Hide_Tvar.parse_parse_mode parse_m))))));
+
+ val _ = Outer_Syntax.command @{command_keyword "update_default_tvars_mode"}
+ "Update print and/or parse mode or the default type variables for a certain type."
+ (typ_modeP >> (fn (typ,(print_m,parse_m)) =>
+ (Toplevel.theory
+ (Hide_Tvar.update_mode typ
+ (SOME (Hide_Tvar.parse_print_mode print_m))
+ (SOME (Hide_Tvar.parse_parse_mode parse_m))))));
+\<close>
+(*
+section\<open>Examples\<close>
+subsection\<open>Print Translation\<close>
+datatype ('a, 'b) hide_tvar_foobar = hide_tvar_foo 'a | hide_tvar_bar 'b
+type_synonym ('a, 'b, 'c, 'd) hide_tvar_baz = "('a+'b, 'a \<times> 'b) hide_tvar_foobar"
+
+definition hide_tvar_f::"('a, 'b) hide_tvar_foobar \<Rightarrow> ('a, 'b) hide_tvar_foobar \<Rightarrow> ('a, 'b) hide_tvar_foobar"
+ where "hide_tvar_f a b = a"
+definition hide_tvar_g::"('a, 'b, 'c, 'd) hide_tvar_baz \<Rightarrow> ('a, 'b, 'c, 'd) hide_tvar_baz \<Rightarrow> ('a, 'b, 'c, 'd) hide_tvar_baz"
+ where "hide_tvar_g a b = a"
+
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_f_def",
+ str="hide_tvar_f (a::('a, 'b) hide_tvar_foobar) (b::('a, 'b) hide_tvar_foobar) = a"]
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_g_def",
+ str="hide_tvar_g (a::('a + 'b, 'a \<times> 'b) hide_tvar_foobar) (b::('a + 'b, 'a \<times> 'b) hide_tvar_foobar) = a"]
+
+register_default_tvars "('alpha, 'beta) hide_tvar_foobar" (print_all,parse)
+register_default_tvars "('alpha, 'beta, 'gamma, 'delta) hide_tvar_baz" (print_all,parse)
+
+update_default_tvars_mode "_ hide_tvar_foobar" (noprint,noparse)
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_f_def",
+ str="hide_tvar_f (a::('a, 'b) hide_tvar_foobar) (b::('a, 'b) hide_tvar_foobar) = a"]
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_g_def",
+ str="hide_tvar_g (a::('a + 'b, 'a \<times> 'b) hide_tvar_foobar) (b::('a + 'b, 'a \<times> 'b) hide_tvar_foobar) = a"]
+
+update_default_tvars_mode "_ hide_tvar_foobar" (print_all,noparse)
+
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_f_def", str="hide_tvar_f (a::(_) hide_tvar_foobar) (b::(_) hide_tvar_foobar) = a"]
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_g_def", str="hide_tvar_g (a::(_) hide_tvar_baz) (b::(_) hide_tvar_baz) = a"]
+
+subsection\<open>Parse Translation\<close>
+update_default_tvars_mode "_ hide_tvar_foobar" (print_all,parse)
+
+declare [[show_types]]
+definition hide_tvar_A :: "'x \<Rightarrow> (('x::linorder) hide_tvar_foobar) .._"
+ where "hide_tvar_A x = hide_tvar_foo x"
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_A_def", str="hide_tvar_A (x::'x) = hide_tvar_foo x"]
+
+definition hide_tvar_A' :: "'x \<Rightarrow> (('x,'b) hide_tvar_foobar) .._"
+ where "hide_tvar_A' x = hide_tvar_foo x"
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_A'_def", str="hide_tvar_A' (x::'x) = hide_tvar_foo x"]
+
+definition hide_tvar_B' :: "(_) hide_tvar_foobar \<Rightarrow> (_) hide_tvar_foobar \<Rightarrow> (_) hide_tvar_foobar"
+ where "hide_tvar_B' x y = x"
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_A'_def", str="hide_tvar_A' (x::'x) = hide_tvar_foo x"]
+
+
+definition hide_tvar_B :: "(_) hide_tvar_foobar \<Rightarrow> (_) hide_tvar_foobar \<Rightarrow> (_) hide_tvar_foobar"
+ where "hide_tvar_B x y = x"
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_B_def", str="hide_tvar_B (x::(_) hide_tvar_foobar) (y::(_) hide_tvar_foobar) = x"]
+
+definition hide_tvar_C :: "(_) hide_tvar_baz \<Rightarrow> (_) hide_tvar_foobar \<Rightarrow> (_) hide_tvar_baz"
+ where "hide_tvar_C x y = x"
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_C_def", str="hide_tvar_C (x::(_) hide_tvar_baz) (y::(_) hide_tvar_foobar) = x"]
+
+definition hide_tvar_E :: "(_::linorder) hide_tvar_baz \<Rightarrow> (_::linorder) hide_tvar_foobar \<Rightarrow> (_::linorder) hide_tvar_baz"
+ where "hide_tvar_E x y = x"
+assert[string_of_thm_equal,
+ thm_def="hide_tvar_C_def", str="hide_tvar_C (x::(_) hide_tvar_baz) (y::(_) hide_tvar_foobar) = x"]
+
+definition hide_tvar_X :: "(_, 'retval::linorder) hide_tvar_baz
+ \<Rightarrow> (_,'retval) hide_tvar_foobar
+ \<Rightarrow> (_,'retval) hide_tvar_baz"
+ where "hide_tvar_X x y = x"
+*)
+(*>*)
+
+subsection\<open>Introduction\<close>
+text\<open>
+ When modelling object-oriented data models in HOL with the goal of preserving \<^emph>\<open>extensibility\<close>
+ (e.g., as described in~\cite{brucker.ea:extensible:2008-b,brucker:interactive:2007}) one needs
+ to define type constructors with a large number of type variables. This can reduce the readability
+ of the overall formalization. Thus, we use a short-hand notation in cases were the names of
+ the type variables are known from the context. In more detail, this theory sets up both
+ configurable print and parse translations that allows for replacing @{emph \<open>all\<close>} type variables
+ by \<open>(_)\<close>, e.g., a five-ary constructor \<open>('a, 'b, 'c, 'd, 'e) hide_tvar_foo\<close> can
+ be shorted to \<open>(_) hide_tvar_foo\<close>. The use of this shorthand in output (printing) and
+ input (parsing) is, on a per-type basis, user-configurable using the top-level commands
+ \<open>register_default_tvars\<close> (for registering the names of the default type variables and
+ the print/parse mode) and \<open>update_default_tvars_mode\<close> (for changing the print/parse mode
+ dynamically).
+
+ The input also supports short-hands for declaring default sorts (e.g., \<open>(_::linorder)\<close>
+ specifies that all default variables need to be instances of the sort (type class)
+ @{class \<open>linorder\<close>} and short-hands of overriding a suffice (or prefix) of the default type
+ variables. For example, \<open>('state) hide_tvar_foo _.\<close> is a short-hand for
+ \<open>('a, 'b, 'c, 'd, 'state) hide_tvar_foo\<close>. In this document, we omit the implementation
+ details (we refer the interested reader to theory file) and continue directly with a few
+ examples.
+\<close>
+
+subsection\<open>Example\<close>
+text\<open>Given the following type definition:\<close>
+datatype ('a, 'b) hide_tvar_foobar = hide_tvar_foo 'a | hide_tvar_bar 'b
+type_synonym ('a, 'b, 'c, 'd) hide_tvar_baz = "('a+'b, 'a \<times> 'b) hide_tvar_foobar"
+text\<open>We can register default values for the type variables for the abstract
+data type as well as the type synonym:\<close>
+register_default_tvars "('alpha, 'beta) hide_tvar_foobar" (print_all,parse)
+register_default_tvars "('alpha, 'beta, 'gamma, 'delta) hide_tvar_baz" (print_all,parse)
+text\<open>This allows us to write\<close>
+definition hide_tvar_f::"(_) hide_tvar_foobar \<Rightarrow> (_) hide_tvar_foobar \<Rightarrow> (_) hide_tvar_foobar"
+ where "hide_tvar_f a b = a"
+definition hide_tvar_g::"(_) hide_tvar_baz \<Rightarrow> (_) hide_tvar_baz \<Rightarrow> (_) hide_tvar_baz"
+ where "hide_tvar_g a b = a"
+
+text\<open>Instead of specifying the type variables explicitely. This makes, in particular
+for type constructors with a large number of type variables, definitions much
+more concise. This syntax is also used in the output of antiquotations, e.g.,
+@{term[show_types] "x = hide_tvar_g"}. Both the print translation and the parse
+translation can be disabled for each type individually:\<close>
+
+update_default_tvars_mode "_ hide_tvar_foobar" (noprint,noparse)
+update_default_tvars_mode "_ hide_tvar_foobar" (noprint,noparse)
+
+text\<open> Now, Isabelle's interactive output and the antiquotations will show
+all type variables, e.g., @{term[show_types] "x = hide_tvar_g"}.\<close>
+
+
+
+end
diff --git a/thys/Core_SC_DOM/common/preliminaries/Testing_Utils.thy b/thys/Core_SC_DOM/common/preliminaries/Testing_Utils.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/preliminaries/Testing_Utils.thy
@@ -0,0 +1,94 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+theory Testing_Utils
+ imports Main
+begin
+ML \<open>
+val _ = Theory.setup
+ (Method.setup @{binding timed_code_simp}
+ (Scan.succeed (SIMPLE_METHOD' o (CHANGED_PROP oo (fn a => fn b => fn tac =>
+ let
+ val start = Time.now ();
+ val result = Code_Simp.dynamic_tac a b tac;
+ val t = Time.now() - start;
+ in
+ (if length (Seq.list_of result) > 0 then Output.information ("Took " ^ (Time.toString t)) else ());
+ result
+ end))))
+ "timed simplification with code equations");
+
+val _ = Theory.setup
+ (Method.setup @{binding timed_eval}
+ (Scan.succeed (SIMPLE_METHOD' o (fn a => fn b => fn tac =>
+ let
+ val eval = CONVERSION (Conv.params_conv ~1 (K (Conv.concl_conv ~1 (Code_Runtime.dynamic_holds_conv a))) a) THEN'
+ resolve_tac a [TrueI];
+ val start = Time.now ();
+ val result = eval b tac
+ val t = Time.now() - start;
+ in
+ (if length (Seq.list_of result) > 0 then Output.information ("Took " ^ (Time.toString t)) else ());
+ result
+ end)))
+ "timed evaluation");
+
+val _ = Theory.setup
+ (Method.setup @{binding timed_eval_and_code_simp}
+ (Scan.succeed (SIMPLE_METHOD' o (fn a => fn b => fn tac =>
+ let
+ val eval = CONVERSION (Conv.params_conv ~1 (K (Conv.concl_conv ~1 (Code_Runtime.dynamic_holds_conv a))) a) THEN'
+ resolve_tac a [TrueI];
+ val start = Time.now ();
+ val result = eval b tac
+ val t = Time.now() - start;
+
+ val start2 = Time.now ();
+ val result2_opt =
+ Timeout.apply (seconds 600.0) (fn _ => SOME (Code_Simp.dynamic_tac a b tac)) ()
+ handle Timeout.TIMEOUT _ => NONE;
+ val t2 = Time.now() - start2;
+ in
+ if length (Seq.list_of result) > 0 then (Output.information ("eval took " ^ (Time.toString t));
+File.append (Path.explode "/tmp/isabellebench") (Time.toString t ^ ",")) else ();
+ (case result2_opt of
+ SOME result2 =>
+ (if length (Seq.list_of result2) > 0 then (Output.information ("code_simp took " ^ (Time.toString t2));
+File.append (Path.explode "/tmp/isabellebench") (Time.toString t2 ^ "\n")) else ())
+ | NONE => (Output.information "code_simp timed out after 600s"; File.append (Path.explode "/tmp/isabellebench") (">600.000\n")));
+ result
+ end)))
+ "timed evaluation and simplification with code equations with file output");
+\<close>
+
+(* To run the DOM test cases with timing information output, simply replace the use *)
+(* of "eval" with either "timed_code_simp", "timed_eval", or, to run both and write the results *)
+(* to /tmp/isabellebench, "timed_eval_and_code_simp". *)
+
+end
diff --git a/thys/Core_SC_DOM/common/tests/Core_DOM_BaseTest.thy b/thys/Core_SC_DOM/common/tests/Core_DOM_BaseTest.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/tests/Core_DOM_BaseTest.thy
@@ -0,0 +1,284 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Common Test Setup\<close>
+text\<open>This theory provides the common test setup that is used by all formalized test cases.\<close>
+
+theory Core_DOM_BaseTest
+ imports
+ (*<*)
+ "../preliminaries/Testing_Utils"
+ (*>*)
+ "../Core_DOM"
+begin
+
+definition "assert_throws e p = do {
+ h \<leftarrow> get_heap;
+ (if (h \<turnstile> p \<rightarrow>\<^sub>e e) then return () else error AssertException)
+}"
+notation assert_throws ("assert'_throws'(_, _')")
+
+definition "test p h \<longleftrightarrow> h \<turnstile> ok p"
+
+
+definition field_access :: "(string \<Rightarrow> (_, (_) object_ptr option) dom_prog) \<Rightarrow> string
+ \<Rightarrow> (_, (_) object_ptr option) dom_prog" (infix "." 80)
+ where
+ "field_access m field = m field"
+
+definition assert_equals :: "'a \<Rightarrow> 'a \<Rightarrow> (_, unit) dom_prog"
+ where
+ "assert_equals l r = (if l = r then return () else error AssertException)"
+definition assert_equals_with_message :: "'a \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> (_, unit) dom_prog"
+ where
+ "assert_equals_with_message l r _ = (if l = r then return () else error AssertException)"
+notation assert_equals ("assert'_equals'(_, _')")
+notation assert_equals_with_message ("assert'_equals'(_, _, _')")
+notation assert_equals ("assert'_array'_equals'(_, _')")
+notation assert_equals_with_message ("assert'_array'_equals'(_, _, _')")
+
+definition assert_not_equals :: "'a \<Rightarrow> 'a \<Rightarrow> (_, unit) dom_prog"
+ where
+ "assert_not_equals l r = (if l \<noteq> r then return () else error AssertException)"
+definition assert_not_equals_with_message :: "'a \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> (_, unit) dom_prog"
+ where
+ "assert_not_equals_with_message l r _ = (if l \<noteq> r then return () else error AssertException)"
+notation assert_not_equals ("assert'_not'_equals'(_, _')")
+notation assert_not_equals_with_message ("assert'_not'_equals'(_, _, _')")
+notation assert_not_equals ("assert'_array'_not'_equals'(_, _')")
+notation assert_not_equals_with_message ("assert'_array'_not'_equals'(_, _, _')")
+
+definition removeWhiteSpaceOnlyTextNodes :: "((_) object_ptr option) \<Rightarrow> (_, unit) dom_prog"
+ where
+ "removeWhiteSpaceOnlyTextNodes _ = return ()"
+
+
+subsection \<open>Making the functions under test compatible with untyped languages such as JavaScript\<close>
+
+fun set_attribute_with_null :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> attr_value \<Rightarrow> (_, unit) dom_prog"
+ where
+ "set_attribute_with_null (Some ptr) k v = (case cast ptr of
+ Some element_ptr \<Rightarrow> set_attribute element_ptr k (Some v))"
+fun set_attribute_with_null2 :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> attr_value option \<Rightarrow> (_, unit) dom_prog"
+ where
+ "set_attribute_with_null2 (Some ptr) k v = (case cast ptr of
+ Some element_ptr \<Rightarrow> set_attribute element_ptr k v)"
+notation set_attribute_with_null ("_ . setAttribute'(_, _')")
+notation set_attribute_with_null2 ("_ . setAttribute'(_, _')")
+
+fun get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_with_null :: "((_) object_ptr option) \<Rightarrow> (_, (_) object_ptr option list) dom_prog"
+ where
+ "get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_with_null (Some ptr) = do {
+ children \<leftarrow> get_child_nodes ptr;
+ return (map (Some \<circ> cast) children)
+ }"
+notation get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_with_null ("_ . childNodes")
+
+fun create_element_with_null :: "((_) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "create_element_with_null (Some owner_document_obj) tag = (case cast owner_document_obj of
+ Some owner_document \<Rightarrow> do {
+ element_ptr \<leftarrow> create_element owner_document tag;
+ return (Some (cast element_ptr))})"
+notation create_element_with_null ("_ . createElement'(_')")
+
+fun create_character_data_with_null :: "((_) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "create_character_data_with_null (Some owner_document_obj) tag = (case cast owner_document_obj of
+ Some owner_document \<Rightarrow> do {
+ character_data_ptr \<leftarrow> create_character_data owner_document tag;
+ return (Some (cast character_data_ptr))})"
+notation create_character_data_with_null ("_ . createTextNode'(_')")
+
+definition create_document_with_null :: "string \<Rightarrow> (_, ((_::linorder) object_ptr option)) dom_prog"
+ where
+ "create_document_with_null title = do {
+ new_document_ptr \<leftarrow> create_document;
+ html \<leftarrow> create_element new_document_ptr ''html'';
+ append_child (cast new_document_ptr) (cast html);
+ heap \<leftarrow> create_element new_document_ptr ''heap'';
+ append_child (cast html) (cast heap);
+ body \<leftarrow> create_element new_document_ptr ''body'';
+ append_child (cast html) (cast body);
+ return (Some (cast new_document_ptr))
+ }"
+abbreviation "create_document_with_null2 _ _ _ \<equiv> create_document_with_null ''''"
+notation create_document_with_null ("createDocument'(_')")
+notation create_document_with_null2 ("createDocument'(_, _, _')")
+
+fun get_element_by_id_with_null :: "((_::linorder) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "get_element_by_id_with_null (Some ptr) id' = do {
+ element_ptr_opt \<leftarrow> get_element_by_id ptr id';
+ (case element_ptr_opt of
+ Some element_ptr \<Rightarrow> return (Some (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr))
+ | None \<Rightarrow> return None)}"
+ | "get_element_by_id_with_null _ _ = error SegmentationFault"
+notation get_element_by_id_with_null ("_ . getElementById'(_')")
+
+fun get_elements_by_class_name_with_null ::
+"((_::linorder) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option) list) dom_prog"
+ where
+ "get_elements_by_class_name_with_null (Some ptr) class_name =
+ get_elements_by_class_name ptr class_name \<bind> map_M (return \<circ> Some \<circ> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r)"
+notation get_elements_by_class_name_with_null ("_ . getElementsByClassName'(_')")
+
+fun get_elements_by_tag_name_with_null ::
+"((_::linorder) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option) list) dom_prog"
+ where
+ "get_elements_by_tag_name_with_null (Some ptr) tag =
+ get_elements_by_tag_name ptr tag \<bind> map_M (return \<circ> Some \<circ> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r)"
+notation get_elements_by_tag_name_with_null ("_ . getElementsByTagName'(_')")
+
+fun insert_before_with_null ::
+"((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow>
+(_, ((_) object_ptr option)) dom_prog"
+ where
+ "insert_before_with_null (Some ptr) (Some child_obj) ref_child_obj_opt = (case cast child_obj of
+ Some child \<Rightarrow> do {
+ (case ref_child_obj_opt of
+ Some ref_child_obj \<Rightarrow> insert_before ptr child (cast ref_child_obj)
+ | None \<Rightarrow> insert_before ptr child None);
+ return (Some child_obj)}
+ | None \<Rightarrow> error HierarchyRequestError)"
+notation insert_before_with_null ("_ . insertBefore'(_, _')")
+
+fun append_child_with_null :: "((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow>
+(_, unit) dom_prog"
+ where
+ "append_child_with_null (Some ptr) (Some child_obj) = (case cast child_obj of
+ Some child \<Rightarrow> append_child ptr child
+ | None \<Rightarrow> error SegmentationFault)"
+notation append_child_with_null ("_ . appendChild'(_')")
+
+fun get_body :: "((_::linorder) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "get_body ptr = do {
+ ptrs \<leftarrow> ptr . getElementsByTagName(''body'');
+ return (hd ptrs)
+ }"
+notation get_body ("_ . body")
+
+fun get_document_element_with_null :: "((_::linorder) object_ptr option) \<Rightarrow>
+(_, ((_) object_ptr option)) dom_prog"
+ where
+ "get_document_element_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some document_ptr \<Rightarrow> do {
+ element_ptr_opt \<leftarrow> get_M document_ptr document_element;
+ return (case element_ptr_opt of
+ Some element_ptr \<Rightarrow> Some (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr)
+ | None \<Rightarrow> None)})"
+notation get_document_element_with_null ("_ . documentElement")
+
+fun get_owner_document_with_null :: "((_::linorder) object_ptr option) \<Rightarrow>
+(_, ((_) object_ptr option)) dom_prog"
+ where
+ "get_owner_document_with_null (Some ptr) = (do {
+ document_ptr \<leftarrow> get_owner_document ptr;
+ return (Some (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr))})"
+notation get_owner_document_with_null ("_ . ownerDocument")
+
+fun remove_with_null :: "((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow>
+(_, ((_) object_ptr option)) dom_prog"
+ where
+ "remove_with_null (Some ptr) (Some child) = (case cast child of
+ Some child_node \<Rightarrow> do {
+ remove child_node;
+ return (Some child)}
+ | None \<Rightarrow> error NotFoundError)"
+ | "remove_with_null None _ = error TypeError"
+ | "remove_with_null _ None = error TypeError"
+notation remove_with_null ("_ . remove'(')")
+
+fun remove_child_with_null :: "((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow>
+(_, ((_) object_ptr option)) dom_prog"
+ where
+ "remove_child_with_null (Some ptr) (Some child) = (case cast child of
+ Some child_node \<Rightarrow> do {
+ remove_child ptr child_node;
+ return (Some child)}
+ | None \<Rightarrow> error NotFoundError)"
+ | "remove_child_with_null None _ = error TypeError"
+ | "remove_child_with_null _ None = error TypeError"
+notation remove_child_with_null ("_ . removeChild")
+
+fun get_tag_name_with_null :: "((_) object_ptr option) \<Rightarrow> (_, attr_value) dom_prog"
+ where
+ "get_tag_name_with_null (Some ptr) = (case cast ptr of
+ Some element_ptr \<Rightarrow> get_M element_ptr tag_name)"
+notation get_tag_name_with_null ("_ . tagName")
+
+abbreviation "remove_attribute_with_null ptr k \<equiv> set_attribute_with_null2 ptr k None"
+notation remove_attribute_with_null ("_ . removeAttribute'(_')")
+
+fun get_attribute_with_null :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> (_, attr_value option) dom_prog"
+ where
+ "get_attribute_with_null (Some ptr) k = (case cast ptr of
+ Some element_ptr \<Rightarrow> get_attribute element_ptr k)"
+fun get_attribute_with_null2 :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> (_, attr_value) dom_prog"
+ where
+ "get_attribute_with_null2 (Some ptr) k = (case cast ptr of
+ Some element_ptr \<Rightarrow> do {
+ a \<leftarrow> get_attribute element_ptr k;
+ return (the a)})"
+notation get_attribute_with_null ("_ . getAttribute'(_')")
+notation get_attribute_with_null2 ("_ . getAttribute'(_')")
+
+fun get_parent_with_null :: "((_::linorder) object_ptr option) \<Rightarrow> (_, (_) object_ptr option) dom_prog"
+ where
+ "get_parent_with_null (Some ptr) = (case cast ptr of
+ Some node_ptr \<Rightarrow> get_parent node_ptr)"
+notation get_parent_with_null ("_ . parentNode")
+
+fun first_child_with_null :: "((_) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "first_child_with_null (Some ptr) = do {
+ child_opt \<leftarrow> first_child ptr;
+ return (case child_opt of
+ Some child \<Rightarrow> Some (cast child)
+ | None \<Rightarrow> None)}"
+notation first_child_with_null ("_ . firstChild")
+
+fun adopt_node_with_null ::
+"((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow>(_, ((_) object_ptr option)) dom_prog"
+ where
+ "adopt_node_with_null (Some ptr) (Some child) = (case cast ptr of
+ Some document_ptr \<Rightarrow> (case cast child of
+ Some child_node \<Rightarrow> do {
+ adopt_node document_ptr child_node;
+ return (Some child)}))"
+notation adopt_node_with_null ("_ . adoptNode'(_')")
+
+
+definition createTestTree ::
+"((_::linorder) object_ptr option) \<Rightarrow> (_, (string \<Rightarrow> (_, ((_) object_ptr option)) dom_prog)) dom_prog"
+ where
+ "createTestTree ref = return (\<lambda>id. get_element_by_id_with_null ref id)"
+
+end
diff --git a/thys/Core_SC_DOM/common/tests/Document-adoptNode.html b/thys/Core_SC_DOM/common/tests/Document-adoptNode.html
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/tests/Document-adoptNode.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Document.adoptNode</title>
+<link rel=help href="https://dom.spec.whatwg.org/#dom-document-adoptnode">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<x<>x</x<>
+<script>
+test(function() {
+ var y = document.getElementsByTagName("x<")[0]
+ var child = y.firstChild
+ assert_equals(y.parentNode, document.body)
+ assert_equals(y.ownerDocument, document)
+ assert_equals(document.adoptNode(y), y)
+ assert_equals(y.parentNode, null)
+ assert_equals(y.firstChild, child)
+ assert_equals(y.ownerDocument, document)
+ assert_equals(child.ownerDocument, document)
+ var doc = document.implementation.createDocument(null, null, null)
+ assert_equals(doc.adoptNode(y), y)
+ assert_equals(y.parentNode, null)
+ assert_equals(y.firstChild, child)
+ assert_equals(y.ownerDocument, doc)
+ assert_equals(child.ownerDocument, doc)
+}, "Adopting an Element called 'x<' should work.")
+
+test(function() {
+ var x = document.createElement(":good:times:")
+ assert_equals(document.adoptNode(x), x);
+ var doc = document.implementation.createDocument(null, null, null)
+ assert_equals(doc.adoptNode(x), x)
+ assert_equals(x.parentNode, null)
+ assert_equals(x.ownerDocument, doc)
+}, "Adopting an Element called ':good:times:' should work.")
+</script>
diff --git a/thys/Core_SC_DOM/common/tests/Document-getElementById.html b/thys/Core_SC_DOM/common/tests/Document-getElementById.html
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/tests/Document-getElementById.html
@@ -0,0 +1,251 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Document.getElementById</title>
+<link rel="author" title="Tetsuharu OHZEKI" href="mailto:saneyuki.snyk@gmail.com">
+<link rel=help href="https://dom.spec.whatwg.org/#dom-document-getelementbyid">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+ <div id="log"></div>
+
+ <div id=""></div>
+
+ <div id="test1"></div>
+
+ <div id="test5" data-name="1st">
+ <p id="test5" data-name="2nd">P</p>
+ <input id="test5" type="submit" value="Submit" data-name="3rd">
+ </div>
+
+ <div id="outer">
+ <div id="middle">
+ <div id="inner"></div>
+ </div>
+ </div>
+
+<script>
+ test(function() {
+ var gBody = document.body;
+
+ var TEST_ID = "test2";
+
+ var test = document.createElement("div");
+ test.setAttribute("id", TEST_ID);
+ gBody.appendChild(test);
+
+ // test: appended element
+ var result = document.getElementById(TEST_ID);
+ assert_not_equals(result, null, "should not be null.");
+ assert_equals(result.tagName, "div", "should have appended element's tag name");
+
+ // test: removed element
+ gBody.removeChild(test);
+ var removed = document.getElementById(TEST_ID);
+ // `document.getElementById()` returns `null` if there is none.
+ // https://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid
+ assert_equals(removed, null, "should not get removed element.");
+ }, "Document.getElementById with a script-inserted element");
+
+
+ test(function() {
+ var gBody = document.body;
+
+ // setup fixtures.
+ var TEST_ID = "test3";
+ var test = document.createElement("div");
+ test.setAttribute("id", TEST_ID);
+ gBody.appendChild(test);
+
+ // update id
+ var UPDATED_ID = "test3-updated";
+ test.setAttribute("id", UPDATED_ID);
+ var e = document.getElementById(UPDATED_ID);
+ assert_equals(e, test, "should get the element with id.");
+
+ var old = document.getElementById(TEST_ID);
+ assert_equals(old, null, "shouldn't get the element by the old id.");
+
+ // remove id.
+ test.removeAttribute("id");
+ var e2 = document.getElementById(UPDATED_ID);
+ assert_equals(e2, null, "should return null when the passed id is none in document.");
+ }, "update `id` attribute via setAttribute/removeAttribute");
+
+
+ test(function() {
+ var TEST_ID = "test4-should-not-exist";
+
+ var e = document.createElement('div');
+ e.setAttribute("id", TEST_ID);
+
+ assert_equals(document.getElementById(TEST_ID), null, "should be null");
+ document.body.appendChild(e);
+ assert_equals(document.getElementById(TEST_ID), e, "should be the appended element");
+ }, "Ensure that the id attribute only affects elements present in a document");
+
+
+ test(function() {
+ var gBody = document.body;
+
+ // the method should return the 1st element.
+ var TEST_ID = "test5";
+ var target = document.getElementById(TEST_ID);
+ assert_not_equals(target, null, "should not be null");
+ assert_equals(target.getAttribute("data-name"), "1st", "should return the 1st");
+
+ // even if after the new element was appended.
+ var element4 = document.createElement("div");
+ element4.setAttribute("id", TEST_ID);
+ element4.setAttribute("data-name", "4th");
+ gBody.appendChild(element4);
+ var target2 = document.getElementById(TEST_ID);
+ assert_not_equals(target2, null, "should not be null");
+ assert_equals(target2.getAttribute("data-name"), "1st", "should be the 1st");
+
+ // should return the next element after removed the subtree including the 1st element.
+ target2.parentNode.removeChild(target2);
+ var target3 = document.getElementById(TEST_ID);
+ assert_not_equals(target3, null, "should not be null");
+ assert_equals(target3.getAttribute("data-name"), "4th", "should be the 4th");
+ }, "in tree order, within the context object's tree");
+
+
+ test(function() {
+ var TEST_ID = "test6";
+ var s = document.createElement("div");
+ s.setAttribute("id", TEST_ID);
+ // append to Element, not Document.
+ document.createElement("div").appendChild(s);
+
+ assert_equals(document.getElementById(TEST_ID), null, "should be null");
+ }, "Modern browsers optimize this method with using internal id cache. This test checks that their optimization should effect only append to `Document`, not append to `Node`.");
+
+
+ test(function() {
+ var gBody = document.body;
+
+ var TEST_ID = "test7"
+ var element = document.createElement("div");
+ element.setAttribute("id", TEST_ID);
+ gBody.appendChild(element);
+
+ var target = document.getElementById(TEST_ID);
+ assert_equals(target, element, "should return the element before changing the value");
+
+ element.setAttribute("id", TEST_ID + "-updated");
+ var target2 = document.getElementById(TEST_ID);
+ assert_equals(target2, null, "should return null after updated id via Attr.value");
+ var target3 = document.getElementById(TEST_ID + "-updated");
+ assert_equals(target3, element, "should be equal to the updated element.");
+ }, "changing attribute's value via `Attr` gotten from `Element.attribute`.");
+
+
+ test(function() {
+ var gBody = document.body;
+
+ // setup fixtures.
+ var TEST_ID = "test12";
+ var test = document.createElement("div");
+ test.setAttribute("id", TEST_ID);
+ gBody.appendChild(test);
+
+ // update id
+ var UPDATED_ID = TEST_ID + "-updated";
+ test.setAttribute("id", UPDATED_ID);
+ var e = document.getElementById(UPDATED_ID);
+ assert_equals(e, test, "should get the element with id.");
+
+ var old = document.getElementById(TEST_ID);
+ assert_equals(old, null, "shouldn't get the element by the old id.");
+
+ // remove id.
+ test.setAttribute("id", "");
+ var e2 = document.getElementById(UPDATED_ID);
+ assert_equals(e2, null, "should return null when the passed id is none in document.");
+ }, "update `id` attribute via element.id");
+
+
+ test(function() {
+ var gBody = document.body;
+
+ var TEST_ID = "test13";
+
+ // create fixture
+ var container = document.createElement("div");
+ container.setAttribute("id", TEST_ID + "-fixture");
+ gBody.appendChild(container);
+
+ var element1 = document.createElement("div");
+ element1.setAttribute("id", TEST_ID);
+ var element2 = document.createElement("div");
+ element2.setAttribute("id", TEST_ID);
+ var element3 = document.createElement("div");
+ element3.setAttribute("id", TEST_ID);
+ var element4 = document.createElement("div");
+ element4.setAttribute("id", TEST_ID);
+
+ // append element: 2 -> 4 -> 3 -> 1
+ container.appendChild(element2);
+ container.appendChild(element4);
+ container.insertBefore(element3, element4);
+ container.insertBefore(element1, element2);
+
+
+ var test = document.getElementById(TEST_ID);
+ assert_equals(test, element1, "should return 1st element");
+ container.removeChild(element1);
+
+ test = document.getElementById(TEST_ID);
+ assert_equals(test, element2, "should return 2nd element");
+ container.removeChild(element2);
+
+ test = document.getElementById(TEST_ID);
+ assert_equals(test, element3, "should return 3rd element");
+ container.removeChild(element3);
+
+ test = document.getElementById(TEST_ID);
+ assert_equals(test, element4, "should return 4th element");
+ container.removeChild(element4);
+
+
+ }, "where insertion order and tree order don't match");
+
+ test(function() {
+ var gBody = document.body;
+
+ var TEST_ID = "test14";
+ var a = document.createElement("a");
+ var b = document.createElement("b");
+ a.appendChild(b);
+ b.setAttribute("id", TEST_ID);
+ assert_equals(document.getElementById(TEST_ID), null);
+
+ gBody.appendChild(a);
+ assert_equals(document.getElementById(TEST_ID), b);
+ }, "Inserting an id by inserting its parent node");
+
+ test(function () {
+ var TEST_ID = "test15"
+ var outer = document.getElementById("outer");
+ var middle = document.getElementById("middle");
+ var inner = document.getElementById("inner");
+ outer.removeChild(middle);
+
+ var new_el = document.createElement("h1");
+ new_el.setAttribute("id", "heading");
+ inner.appendChild(new_el);
+ // the new element is not part of the document since
+ // "middle" element was removed previously
+ assert_equals(document.getElementById("heading"), null);
+ }, "Document.getElementById must not return nodes not present in document");
+
+ // TODO:
+ // id attribute in a namespace
+
+
+ // TODO:
+ // SVG + MathML elements with id attributes
+
+</script>
+</body>
+</html>
diff --git a/thys/Core_SC_DOM/common/tests/Document_adoptNode.thy b/thys/Core_SC_DOM/common/tests/Document_adoptNode.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/tests/Document_adoptNode.thy
@@ -0,0 +1,114 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+(* This file is automatically generated, please do not modify! *)
+
+section\<open>Testing Document\_adoptNode\<close>
+text\<open>This theory contains the test cases for Document\_adoptNode.\<close>
+
+theory Document_adoptNode
+imports
+ "Core_DOM_BaseTest"
+begin
+
+definition Document_adoptNode_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
+ "Document_adoptNode_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
+ (cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 8)] fmempty None)),
+ (cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6), cast (element_ptr.Ref 7)] fmempty None)),
+ (cast (element_ptr.Ref 3), cast (create_element_obj ''meta'' [] (fmap_of_list [(''charset'', ''utf-8'')]) None)),
+ (cast (element_ptr.Ref 4), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
+ (cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Document.adoptNode'')),
+ (cast (element_ptr.Ref 5), cast (create_element_obj ''link'' [] (fmap_of_list [(''rel'', ''help''), (''href'', ''https://dom.spec.whatwg.org/#dom-document-adoptnode'')]) None)),
+ (cast (element_ptr.Ref 6), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
+ (cast (element_ptr.Ref 7), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
+ (cast (element_ptr.Ref 8), cast (create_element_obj ''body'' [cast (element_ptr.Ref 9), cast (element_ptr.Ref 10), cast (element_ptr.Ref 11)] fmempty None)),
+ (cast (element_ptr.Ref 9), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
+ (cast (element_ptr.Ref 10), cast (create_element_obj ''x<'' [cast (character_data_ptr.Ref 2)] fmempty None)),
+ (cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''x'')),
+ (cast (element_ptr.Ref 11), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 3)] fmempty None)),
+ (cast (character_data_ptr.Ref 3), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
+
+definition Document_adoptNode_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Document_adoptNode_document = Some (cast (document_ptr.Ref 1))"
+
+
+text \<open>"Adopting an Element called 'x<' should work."\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> Document_adoptNode_document . getElementsByTagName(''x<'');
+ y \<leftarrow> return (tmp0 ! 0);
+ child \<leftarrow> y . firstChild;
+ tmp1 \<leftarrow> y . parentNode;
+ tmp2 \<leftarrow> Document_adoptNode_document . body;
+ assert_equals(tmp1, tmp2);
+ tmp3 \<leftarrow> y . ownerDocument;
+ assert_equals(tmp3, Document_adoptNode_document);
+ tmp4 \<leftarrow> Document_adoptNode_document . adoptNode(y);
+ assert_equals(tmp4, y);
+ tmp5 \<leftarrow> y . parentNode;
+ assert_equals(tmp5, None);
+ tmp6 \<leftarrow> y . firstChild;
+ assert_equals(tmp6, child);
+ tmp7 \<leftarrow> y . ownerDocument;
+ assert_equals(tmp7, Document_adoptNode_document);
+ tmp8 \<leftarrow> child . ownerDocument;
+ assert_equals(tmp8, Document_adoptNode_document);
+ doc \<leftarrow> createDocument(None, None, None);
+ tmp9 \<leftarrow> doc . adoptNode(y);
+ assert_equals(tmp9, y);
+ tmp10 \<leftarrow> y . parentNode;
+ assert_equals(tmp10, None);
+ tmp11 \<leftarrow> y . firstChild;
+ assert_equals(tmp11, child);
+ tmp12 \<leftarrow> y . ownerDocument;
+ assert_equals(tmp12, doc);
+ tmp13 \<leftarrow> child . ownerDocument;
+ assert_equals(tmp13, doc)
+}) Document_adoptNode_heap"
+ by eval
+
+
+text \<open>"Adopting an Element called ':good:times:' should work."\<close>
+
+lemma "test (do {
+ x \<leftarrow> Document_adoptNode_document . createElement('':good:times:'');
+ tmp0 \<leftarrow> Document_adoptNode_document . adoptNode(x);
+ assert_equals(tmp0, x);
+ doc \<leftarrow> createDocument(None, None, None);
+ tmp1 \<leftarrow> doc . adoptNode(x);
+ assert_equals(tmp1, x);
+ tmp2 \<leftarrow> x . parentNode;
+ assert_equals(tmp2, None);
+ tmp3 \<leftarrow> x . ownerDocument;
+ assert_equals(tmp3, doc)
+}) Document_adoptNode_heap"
+ by eval
+
+
+end
diff --git a/thys/Core_SC_DOM/common/tests/Document_getElementById.thy b/thys/Core_SC_DOM/common/tests/Document_getElementById.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/tests/Document_getElementById.thy
@@ -0,0 +1,278 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+(* This file is automatically generated, please do not modify! *)
+
+section\<open>Testing Document\_getElementById\<close>
+text\<open>This theory contains the test cases for Document\_getElementById.\<close>
+
+theory Document_getElementById
+imports
+ "Core_DOM_BaseTest"
+begin
+
+definition Document_getElementById_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
+ "Document_getElementById_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
+ (cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 9)] fmempty None)),
+ (cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6), cast (element_ptr.Ref 7), cast (element_ptr.Ref 8)] fmempty None)),
+ (cast (element_ptr.Ref 3), cast (create_element_obj ''meta'' [] (fmap_of_list [(''charset'', ''utf-8'')]) None)),
+ (cast (element_ptr.Ref 4), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
+ (cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Document.getElementById'')),
+ (cast (element_ptr.Ref 5), cast (create_element_obj ''link'' [] (fmap_of_list [(''rel'', ''author''), (''title'', ''Tetsuharu OHZEKI''), (''href'', ''mailto:saneyuki.snyk@gmail.com'')]) None)),
+ (cast (element_ptr.Ref 6), cast (create_element_obj ''link'' [] (fmap_of_list [(''rel'', ''help''), (''href'', ''https://dom.spec.whatwg.org/#dom-document-getelementbyid'')]) None)),
+ (cast (element_ptr.Ref 7), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
+ (cast (element_ptr.Ref 8), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
+ (cast (element_ptr.Ref 9), cast (create_element_obj ''body'' [cast (element_ptr.Ref 10), cast (element_ptr.Ref 11), cast (element_ptr.Ref 12), cast (element_ptr.Ref 13), cast (element_ptr.Ref 16), cast (element_ptr.Ref 19)] fmempty None)),
+ (cast (element_ptr.Ref 10), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
+ (cast (element_ptr.Ref 11), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', '''')]) None)),
+ (cast (element_ptr.Ref 12), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''test1'')]) None)),
+ (cast (element_ptr.Ref 13), cast (create_element_obj ''div'' [cast (element_ptr.Ref 14), cast (element_ptr.Ref 15)] (fmap_of_list [(''id'', ''test5''), (''data-name'', ''1st'')]) None)),
+ (cast (element_ptr.Ref 14), cast (create_element_obj ''p'' [cast (character_data_ptr.Ref 2)] (fmap_of_list [(''id'', ''test5''), (''data-name'', ''2nd'')]) None)),
+ (cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''P'')),
+ (cast (element_ptr.Ref 15), cast (create_element_obj ''input'' [] (fmap_of_list [(''id'', ''test5''), (''type'', ''submit''), (''value'', ''Submit''), (''data-name'', ''3rd'')]) None)),
+ (cast (element_ptr.Ref 16), cast (create_element_obj ''div'' [cast (element_ptr.Ref 17)] (fmap_of_list [(''id'', ''outer'')]) None)),
+ (cast (element_ptr.Ref 17), cast (create_element_obj ''div'' [cast (element_ptr.Ref 18)] (fmap_of_list [(''id'', ''middle'')]) None)),
+ (cast (element_ptr.Ref 18), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''inner'')]) None)),
+ (cast (element_ptr.Ref 19), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 3)] fmempty None)),
+ (cast (character_data_ptr.Ref 3), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
+
+definition Document_getElementById_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Document_getElementById_document = Some (cast (document_ptr.Ref 1))"
+
+
+text \<open>"Document.getElementById with a script-inserted element"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test2'';
+ test \<leftarrow> Document_getElementById_document . createElement(''div'');
+ test . setAttribute(''id'', TEST_ID);
+ gBody . appendChild(test);
+ result \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_not_equals(result, None, ''should not be null.'');
+ tmp0 \<leftarrow> result . tagName;
+ assert_equals(tmp0, ''div'', ''should have appended element's tag name'');
+ gBody . removeChild(test);
+ removed \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(removed, None, ''should not get removed element.'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"update `id` attribute via setAttribute/removeAttribute"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test3'';
+ test \<leftarrow> Document_getElementById_document . createElement(''div'');
+ test . setAttribute(''id'', TEST_ID);
+ gBody . appendChild(test);
+ UPDATED_ID \<leftarrow> return ''test3-updated'';
+ test . setAttribute(''id'', UPDATED_ID);
+ e \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
+ assert_equals(e, test, ''should get the element with id.'');
+ old \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(old, None, ''shouldn't get the element by the old id.'');
+ test . removeAttribute(''id'');
+ e2 \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
+ assert_equals(e2, None, ''should return null when the passed id is none in document.'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"Ensure that the id attribute only affects elements present in a document"\<close>
+
+lemma "test (do {
+ TEST_ID \<leftarrow> return ''test4-should-not-exist'';
+ e \<leftarrow> Document_getElementById_document . createElement(''div'');
+ e . setAttribute(''id'', TEST_ID);
+ tmp0 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(tmp0, None, ''should be null'');
+ tmp1 \<leftarrow> Document_getElementById_document . body;
+ tmp1 . appendChild(e);
+ tmp2 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(tmp2, e, ''should be the appended element'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"in tree order, within the context object's tree"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test5'';
+ target \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_not_equals(target, None, ''should not be null'');
+ tmp0 \<leftarrow> target . getAttribute(''data-name'');
+ assert_equals(tmp0, ''1st'', ''should return the 1st'');
+ element4 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element4 . setAttribute(''id'', TEST_ID);
+ element4 . setAttribute(''data-name'', ''4th'');
+ gBody . appendChild(element4);
+ target2 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_not_equals(target2, None, ''should not be null'');
+ tmp1 \<leftarrow> target2 . getAttribute(''data-name'');
+ assert_equals(tmp1, ''1st'', ''should be the 1st'');
+ tmp2 \<leftarrow> target2 . parentNode;
+ tmp2 . removeChild(target2);
+ target3 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_not_equals(target3, None, ''should not be null'');
+ tmp3 \<leftarrow> target3 . getAttribute(''data-name'');
+ assert_equals(tmp3, ''4th'', ''should be the 4th'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"Modern browsers optimize this method with using internal id cache. This test checks that their optimization should effect only append to `Document`, not append to `Node`."\<close>
+
+lemma "test (do {
+ TEST_ID \<leftarrow> return ''test6'';
+ s \<leftarrow> Document_getElementById_document . createElement(''div'');
+ s . setAttribute(''id'', TEST_ID);
+ tmp0 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ tmp0 . appendChild(s);
+ tmp1 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(tmp1, None, ''should be null'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"changing attribute's value via `Attr` gotten from `Element.attribute`."\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test7'';
+ element \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element . setAttribute(''id'', TEST_ID);
+ gBody . appendChild(element);
+ target \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(target, element, ''should return the element before changing the value'');
+ element . setAttribute(''id'', (TEST_ID @ ''-updated''));
+ target2 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(target2, None, ''should return null after updated id via Attr.value'');
+ target3 \<leftarrow> Document_getElementById_document . getElementById((TEST_ID @ ''-updated''));
+ assert_equals(target3, element, ''should be equal to the updated element.'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"update `id` attribute via element.id"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test12'';
+ test \<leftarrow> Document_getElementById_document . createElement(''div'');
+ test . setAttribute(''id'', TEST_ID);
+ gBody . appendChild(test);
+ UPDATED_ID \<leftarrow> return (TEST_ID @ ''-updated'');
+ test . setAttribute(''id'', UPDATED_ID);
+ e \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
+ assert_equals(e, test, ''should get the element with id.'');
+ old \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(old, None, ''shouldn't get the element by the old id.'');
+ test . setAttribute(''id'', '''');
+ e2 \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
+ assert_equals(e2, None, ''should return null when the passed id is none in document.'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"where insertion order and tree order don't match"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test13'';
+ container \<leftarrow> Document_getElementById_document . createElement(''div'');
+ container . setAttribute(''id'', (TEST_ID @ ''-fixture''));
+ gBody . appendChild(container);
+ element1 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element1 . setAttribute(''id'', TEST_ID);
+ element2 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element2 . setAttribute(''id'', TEST_ID);
+ element3 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element3 . setAttribute(''id'', TEST_ID);
+ element4 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element4 . setAttribute(''id'', TEST_ID);
+ container . appendChild(element2);
+ container . appendChild(element4);
+ container . insertBefore(element3, element4);
+ container . insertBefore(element1, element2);
+ test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(test, element1, ''should return 1st element'');
+ container . removeChild(element1);
+ test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(test, element2, ''should return 2nd element'');
+ container . removeChild(element2);
+ test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(test, element3, ''should return 3rd element'');
+ container . removeChild(element3);
+ test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(test, element4, ''should return 4th element'');
+ container . removeChild(element4)
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"Inserting an id by inserting its parent node"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test14'';
+ a \<leftarrow> Document_getElementById_document . createElement(''a'');
+ b \<leftarrow> Document_getElementById_document . createElement(''b'');
+ a . appendChild(b);
+ b . setAttribute(''id'', TEST_ID);
+ tmp0 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(tmp0, None);
+ gBody . appendChild(a);
+ tmp1 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(tmp1, b)
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"Document.getElementById must not return nodes not present in document"\<close>
+
+lemma "test (do {
+ TEST_ID \<leftarrow> return ''test15'';
+ outer \<leftarrow> Document_getElementById_document . getElementById(''outer'');
+ middle \<leftarrow> Document_getElementById_document . getElementById(''middle'');
+ inner \<leftarrow> Document_getElementById_document . getElementById(''inner'');
+ tmp0 \<leftarrow> Document_getElementById_document . getElementById(''middle'');
+ outer . removeChild(tmp0);
+ new_el \<leftarrow> Document_getElementById_document . createElement(''h1'');
+ new_el . setAttribute(''id'', ''heading'');
+ inner . appendChild(new_el);
+ tmp1 \<leftarrow> Document_getElementById_document . getElementById(''heading'');
+ assert_equals(tmp1, None)
+}) Document_getElementById_heap"
+ by eval
+
+
+end
diff --git a/thys/Core_SC_DOM/common/tests/Node-insertBefore.html b/thys/Core_SC_DOM/common/tests/Node-insertBefore.html
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/tests/Node-insertBefore.html
@@ -0,0 +1,288 @@
+<!DOCTYPE html>
+<title>Node.insertBefore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+ <div id="log"></div>
+</body>
+<script>
+test(function() {
+ var node = document.createTextNode("Foo");
+ assert_throws("HIERARCHY_REQUEST_ERR", function() { node.insertBefore(document.createTextNode("fail"), null) })
+
+}, "Calling insertBefore an a leaf node Text must throw HIERARCHY_REQUEST_ERR.")
+
+
+test(function() {
+ // Step 2.
+ assert_throws("HIERARCHY_REQUEST_ERR", function() { document.body.insertBefore(document.body, document.getElementById("log")) })
+ assert_throws("HIERARCHY_REQUEST_ERR", function() { document.body.insertBefore(document.documentElement, document.getElementById("log")) })
+}, "Calling insertBefore with an inclusive ancestor of the context object must throw HIERARCHY_REQUEST_ERR.")
+
+// Step 3.
+test(function() {
+ var a = document.createElement("div");
+ var b = document.createElement("div");
+ var c = document.createElement("div");
+ assert_throws("NotFoundError", function() {
+ a.insertBefore(b, c);
+ });
+}, "Calling insertBefore with a reference child whose parent is not the context node must throw a NotFoundError.")
+
+// Step 4.1.
+test(function() {
+ var doc = document.implementation.createHTMLDocument("title");
+ var doc2 = document.implementation.createHTMLDocument("title2");
+ assert_throws("HierarchyRequestError", function() {
+ doc.insertBefore(doc2, doc.documentElement);
+ });
+
+ assert_throws("HierarchyRequestError", function() {
+ doc.insertBefore(doc.createTextNode("text"), doc.documentElement);
+ });
+}, "If the context node is a document, inserting a document or text node should throw a HierarchyRequestError.")
+//
+// // Step 4.2.1.
+// test(function() {
+// var doc = document.implementation.createHTMLDocument("title");
+// doc.removeChild(doc.documentElement);
+//
+// var df = doc.createDocumentFragment();
+// df.appendChild(doc.createElement("a"));
+// df.appendChild(doc.createElement("b"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, null);
+// });
+//
+// df = doc.createDocumentFragment();
+// df.appendChild(doc.createTextNode("text"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, null);
+// });
+//
+// df = doc.createDocumentFragment();
+// df.appendChild(doc.createComment("comment"));
+// df.appendChild(doc.createTextNode("text"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, null);
+// });
+// }, "If the context node is a document, appending a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.")
+// test(function() {
+// var doc = document.implementation.createHTMLDocument("title");
+// doc.removeChild(doc.documentElement);
+//
+// var df = doc.createDocumentFragment();
+// df.appendChild(doc.createElement("a"));
+// df.appendChild(doc.createElement("b"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.firstChild);
+// });
+//
+// df = doc.createDocumentFragment();
+// df.appendChild(doc.createTextNode("text"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.firstChild);
+// });
+//
+// df = doc.createDocumentFragment();
+// df.appendChild(doc.createComment("comment"));
+// df.appendChild(doc.createTextNode("text"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.firstChild);
+// });
+// }, "If the context node is a document, inserting a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.")
+//
+// // Step 4.2.2.
+// test(function() {
+// // The context node has an element child.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.appendChild(doc.createComment("foo"));
+// assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
+//
+// var df = doc.createDocumentFragment();
+// df.appendChild(doc.createElement("a"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.doctype);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.documentElement);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, comment);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, null);
+// });
+// }, "If the context node is a document, inserting a DocumentFragment with an element if there already is an element child should throw a HierarchyRequestError.")
+// test(function() {
+// // /child/ is a doctype.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
+// doc.removeChild(doc.documentElement);
+// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
+//
+// var df = doc.createDocumentFragment();
+// df.appendChild(doc.createElement("a"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.doctype);
+// });
+// }, "If the context node is a document and a doctype is following the reference child, inserting a DocumentFragment with an element should throw a HierarchyRequestError.")
+// test(function() {
+// // /child/ is not null and a doctype is following /child/.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
+// doc.removeChild(doc.documentElement);
+// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
+//
+// var df = doc.createDocumentFragment();
+// df.appendChild(doc.createElement("a"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, comment);
+// });
+// }, "If the context node is a document, inserting a DocumentFragment with an element before the doctype should throw a HierarchyRequestError.")
+//
+// // Step 4.3.
+// test(function() {
+// // The context node has an element child.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.appendChild(doc.createComment("foo"));
+// assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
+//
+// var a = doc.createElement("a");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, doc.doctype);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, doc.documentElement);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, comment);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, null);
+// });
+// }, "If the context node is a document, inserting an element if there already is an element child should throw a HierarchyRequestError.")
+// test(function() {
+// // /child/ is a doctype.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
+// doc.removeChild(doc.documentElement);
+// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
+//
+// var a = doc.createElement("a");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, doc.doctype);
+// });
+// }, "If the context node is a document, inserting an element before the doctype should throw a HierarchyRequestError.")
+// test(function() {
+// // /child/ is not null and a doctype is following /child/.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
+// doc.removeChild(doc.documentElement);
+// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
+//
+// var a = doc.createElement("a");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, comment);
+// });
+// }, "If the context node is a document and a doctype is following the reference child, inserting an element should throw a HierarchyRequestError.")
+//
+// // Step 4.4.
+// test(function() {
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
+// assert_array_equals(doc.childNodes, [comment, doc.doctype, doc.documentElement]);
+//
+// var doctype = document.implementation.createDocumentType("html", "", "");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, comment);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, doc.doctype);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, doc.documentElement);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, null);
+// });
+// }, "If the context node is a document, inserting a doctype if there already is a doctype child should throw a HierarchyRequestError.")
+// test(function() {
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.appendChild(doc.createComment("foo"));
+// doc.removeChild(doc.doctype);
+// assert_array_equals(doc.childNodes, [doc.documentElement, comment]);
+//
+// var doctype = document.implementation.createDocumentType("html", "", "");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, comment);
+// });
+// }, "If the context node is a document, inserting a doctype after the document element should throw a HierarchyRequestError.")
+// test(function() {
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.appendChild(doc.createComment("foo"));
+// doc.removeChild(doc.doctype);
+// assert_array_equals(doc.childNodes, [doc.documentElement, comment]);
+//
+// var doctype = document.implementation.createDocumentType("html", "", "");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, null);
+// });
+// }, "If the context node is a document with and element child, appending a doctype should throw a HierarchyRequestError.")
+//
+// // Step 5.
+// test(function() {
+// var df = document.createDocumentFragment();
+// var a = df.appendChild(document.createElement("a"));
+//
+// var doc = document.implementation.createHTMLDocument("title");
+// assert_throws("HierarchyRequestError", function() {
+// df.insertBefore(doc, a);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// df.insertBefore(doc, null);
+// });
+//
+// var doctype = document.implementation.createDocumentType("html", "", "");
+// assert_throws("HierarchyRequestError", function() {
+// df.insertBefore(doctype, a);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// df.insertBefore(doctype, null);
+// });
+// }, "If the context node is a DocumentFragment, inserting a document or a doctype should throw a HierarchyRequestError.")
+// test(function() {
+// var el = document.createElement("div");
+// var a = el.appendChild(document.createElement("a"));
+//
+// var doc = document.implementation.createHTMLDocument("title");
+// assert_throws("HierarchyRequestError", function() {
+// el.insertBefore(doc, a);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// el.insertBefore(doc, null);
+// });
+//
+// var doctype = document.implementation.createDocumentType("html", "", "");
+// assert_throws("HierarchyRequestError", function() {
+// el.insertBefore(doctype, a);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// el.insertBefore(doctype, null);
+// });
+// }, "If the context node is an element, inserting a document or a doctype should throw a HierarchyRequestError.")
+//
+// Step 7.
+test(function() {
+ var a = document.createElement("div");
+ var b = document.createElement("div");
+ var c = document.createElement("div");
+ a.appendChild(b);
+ a.appendChild(c);
+ assert_array_equals(a.childNodes, [b, c]);
+ assert_equals(a.insertBefore(b, b), b);
+ assert_array_equals(a.childNodes, [b, c]);
+ assert_equals(a.insertBefore(c, c), c);
+ assert_array_equals(a.childNodes, [b, c]);
+}, "Inserting a node before itself should not move the node");
+</script>
diff --git a/thys/Core_SC_DOM/common/tests/Node-removeChild.html b/thys/Core_SC_DOM/common/tests/Node-removeChild.html
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/tests/Node-removeChild.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<title>Node.removeChild</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="creators.js"></script>
+<body>
+ <div id="log"></div>
+</body>
+<iframe src=about:blank></iframe>
+<script>
+
+test(function() {
+ var doc = document;
+ var s = doc.createElement("div");
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
+ assert_equals(s.ownerDocument, doc)
+}, "Passing a detached Element to removeChild should not affect it.")
+
+test(function() {
+ var doc = document;
+ var s = doc.createElement("div");
+ doc.documentElement.appendChild(s)
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
+ assert_equals(s.ownerDocument, doc)
+}, "Passing a non-detached Element to removeChild should not affect it.")
+
+test(function() {
+ var doc = document;
+ var s = doc.createElement("div");
+ doc.body.appendChild(s)
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { s.removeChild(doc) })
+}, "Calling removeChild on an Element with no children should throw NOT_FOUND_ERR.")
+
+test(function() {
+ var doc = document.implementation.createHTMLDocument("");
+ var s = doc.createElement("div");
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
+ assert_equals(s.ownerDocument, doc)
+}, "Passing a detached Element to removeChild should not affect it.")
+
+test(function() {
+ var doc = document.implementation.createHTMLDocument("");
+ var s = doc.createElement("div");
+ doc.documentElement.appendChild(s)
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
+ assert_equals(s.ownerDocument, doc)
+}, "Passing a non-detached Element to removeChild should not affect it.")
+
+test(function() {
+ var doc = document.implementation.createHTMLDocument("");
+ var s = doc.createElement("div");
+ doc.body.appendChild(s)
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { s.removeChild(doc) })
+}, "Calling removeChild on an Element with no children should throw NOT_FOUND_ERR.")
+
+test(function() {
+ assert_throws(new TypeError(), function() { document.body.removeChild(null) })
+ //assert_throws(new TypeError(), function() { document.body.removeChild({'a':'b'}) })
+}, "Passing a value that is not a Node reference to removeChild should throw TypeError.")
+</script>
diff --git a/thys/Core_SC_DOM/common/tests/Node_insertBefore.thy b/thys/Core_SC_DOM/common/tests/Node_insertBefore.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/tests/Node_insertBefore.thy
@@ -0,0 +1,129 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+(* This file is automatically generated, please do not modify! *)
+
+section\<open>Testing Node\_insertBefore\<close>
+text\<open>This theory contains the test cases for Node\_insertBefore.\<close>
+
+theory Node_insertBefore
+imports
+ "Core_DOM_BaseTest"
+begin
+
+definition Node_insertBefore_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
+ "Node_insertBefore_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
+ (cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 6)] fmempty None)),
+ (cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5)] fmempty None)),
+ (cast (element_ptr.Ref 3), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
+ (cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Node.insertBefore'')),
+ (cast (element_ptr.Ref 4), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
+ (cast (element_ptr.Ref 5), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
+ (cast (element_ptr.Ref 6), cast (create_element_obj ''body'' [cast (element_ptr.Ref 7), cast (element_ptr.Ref 8)] fmempty None)),
+ (cast (element_ptr.Ref 7), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
+ (cast (element_ptr.Ref 8), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 2)] fmempty None)),
+ (cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
+
+definition Node_insertBefore_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Node_insertBefore_document = Some (cast (document_ptr.Ref 1))"
+
+
+text \<open>"Calling insertBefore an a leaf node Text must throw HIERARCHY\_REQUEST\_ERR."\<close>
+
+lemma "test (do {
+ node \<leftarrow> Node_insertBefore_document . createTextNode(''Foo'');
+ tmp0 \<leftarrow> Node_insertBefore_document . createTextNode(''fail'');
+ assert_throws(HierarchyRequestError, node . insertBefore(tmp0, None))
+}) Node_insertBefore_heap"
+ by eval
+
+
+text \<open>"Calling insertBefore with an inclusive ancestor of the context object must throw HIERARCHY\_REQUEST\_ERR."\<close>
+
+lemma "test (do {
+ tmp1 \<leftarrow> Node_insertBefore_document . body;
+ tmp2 \<leftarrow> Node_insertBefore_document . getElementById(''log'');
+ tmp0 \<leftarrow> Node_insertBefore_document . body;
+ assert_throws(HierarchyRequestError, tmp0 . insertBefore(tmp1, tmp2));
+ tmp4 \<leftarrow> Node_insertBefore_document . documentElement;
+ tmp5 \<leftarrow> Node_insertBefore_document . getElementById(''log'');
+ tmp3 \<leftarrow> Node_insertBefore_document . body;
+ assert_throws(HierarchyRequestError, tmp3 . insertBefore(tmp4, tmp5))
+}) Node_insertBefore_heap"
+ by eval
+
+
+text \<open>"Calling insertBefore with a reference child whose parent is not the context node must throw a NotFoundError."\<close>
+
+lemma "test (do {
+ a \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ b \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ c \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ assert_throws(NotFoundError, a . insertBefore(b, c))
+}) Node_insertBefore_heap"
+ by eval
+
+
+text \<open>"If the context node is a document, inserting a document or text node should throw a HierarchyRequestError."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> createDocument(''title'');
+ doc2 \<leftarrow> createDocument(''title2'');
+ tmp0 \<leftarrow> doc . documentElement;
+ assert_throws(HierarchyRequestError, doc . insertBefore(doc2, tmp0));
+ tmp1 \<leftarrow> doc . createTextNode(''text'');
+ tmp2 \<leftarrow> doc . documentElement;
+ assert_throws(HierarchyRequestError, doc . insertBefore(tmp1, tmp2))
+}) Node_insertBefore_heap"
+ by eval
+
+
+text \<open>"Inserting a node before itself should not move the node"\<close>
+
+lemma "test (do {
+ a \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ b \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ c \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ a . appendChild(b);
+ a . appendChild(c);
+ tmp0 \<leftarrow> a . childNodes;
+ assert_array_equals(tmp0, [b, c]);
+ tmp1 \<leftarrow> a . insertBefore(b, b);
+ assert_equals(tmp1, b);
+ tmp2 \<leftarrow> a . childNodes;
+ assert_array_equals(tmp2, [b, c]);
+ tmp3 \<leftarrow> a . insertBefore(c, c);
+ assert_equals(tmp3, c);
+ tmp4 \<leftarrow> a . childNodes;
+ assert_array_equals(tmp4, [b, c])
+}) Node_insertBefore_heap"
+ by eval
+
+
+end
diff --git a/thys/Core_SC_DOM/common/tests/Node_removeChild.thy b/thys/Core_SC_DOM/common/tests/Node_removeChild.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/common/tests/Node_removeChild.thy
@@ -0,0 +1,160 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+(* This file is automatically generated, please do not modify! *)
+
+section\<open>Testing Node\_removeChild\<close>
+text\<open>This theory contains the test cases for Node\_removeChild.\<close>
+
+theory Node_removeChild
+imports
+ "Core_DOM_BaseTest"
+begin
+
+definition Node_removeChild_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
+ "Node_removeChild_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
+ (cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 7)] fmempty None)),
+ (cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6)] fmempty None)),
+ (cast (element_ptr.Ref 3), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
+ (cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Node.removeChild'')),
+ (cast (element_ptr.Ref 4), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
+ (cast (element_ptr.Ref 5), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
+ (cast (element_ptr.Ref 6), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''creators.js'')]) None)),
+ (cast (element_ptr.Ref 7), cast (create_element_obj ''body'' [cast (element_ptr.Ref 8), cast (element_ptr.Ref 9), cast (element_ptr.Ref 10)] fmempty None)),
+ (cast (element_ptr.Ref 8), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
+ (cast (element_ptr.Ref 9), cast (create_element_obj ''iframe'' [] (fmap_of_list [(''src'', ''about:blank'')]) None)),
+ (cast (element_ptr.Ref 10), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 2)] fmempty None)),
+ (cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
+
+definition Node_removeChild_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Node_removeChild_document = Some (cast (document_ptr.Ref 1))"
+
+
+text \<open>"Passing a detached Element to removeChild should not affect it."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> return Node_removeChild_document;
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp0, doc);
+ tmp1 \<leftarrow> Node_removeChild_document . body;
+ assert_throws(NotFoundError, tmp1 . removeChild(s));
+ tmp2 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp2, doc)
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Passing a non-detached Element to removeChild should not affect it."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> return Node_removeChild_document;
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> doc . documentElement;
+ tmp0 . appendChild(s);
+ tmp1 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp1, doc);
+ tmp2 \<leftarrow> Node_removeChild_document . body;
+ assert_throws(NotFoundError, tmp2 . removeChild(s));
+ tmp3 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp3, doc)
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Calling removeChild on an Element with no children should throw NOT\_FOUND\_ERR."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> return Node_removeChild_document;
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> doc . body;
+ tmp0 . appendChild(s);
+ tmp1 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp1, doc);
+ assert_throws(NotFoundError, s . removeChild(doc))
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Passing a detached Element to removeChild should not affect it."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> createDocument('''');
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp0, doc);
+ tmp1 \<leftarrow> Node_removeChild_document . body;
+ assert_throws(NotFoundError, tmp1 . removeChild(s));
+ tmp2 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp2, doc)
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Passing a non-detached Element to removeChild should not affect it."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> createDocument('''');
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> doc . documentElement;
+ tmp0 . appendChild(s);
+ tmp1 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp1, doc);
+ tmp2 \<leftarrow> Node_removeChild_document . body;
+ assert_throws(NotFoundError, tmp2 . removeChild(s));
+ tmp3 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp3, doc)
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Calling removeChild on an Element with no children should throw NOT\_FOUND\_ERR."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> createDocument('''');
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> doc . body;
+ tmp0 . appendChild(s);
+ tmp1 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp1, doc);
+ assert_throws(NotFoundError, s . removeChild(doc))
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Passing a value that is not a Node reference to removeChild should throw TypeError."\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> Node_removeChild_document . body;
+ assert_throws(TypeError, tmp0 . removeChild(None))
+}) Node_removeChild_heap"
+ by eval
+
+
+end
diff --git a/thys/Core_SC_DOM/document/root.bib b/thys/Core_SC_DOM/document/root.bib
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/document/root.bib
@@ -0,0 +1,531 @@
+@STRING{j-fac = "Formal Aspects of Computing" }
+@STRING{pub-springer={Springer-Verlag} }
+@STRING{pub-springer:adr={Heidelberg} }
+@STRING{s-lncs = "Lecture Notes in Computer Science" }
+
+@Book{ nipkow.ea:isabelle:2002,
+ author = {Tobias Nipkow and Lawrence C. Paulson and Markus Wenzel},
+ title = {Isabelle/HOL---A Proof Assistant for Higher-Order Logic},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2283,
+ doi = {10.1007/3-540-45949-9},
+ abstract = {This book is a self-contained introduction to interactive
+ proof in higher-order logic (HOL), using the proof
+ assistant Isabelle2002. It is a tutorial for potential
+ users rather than a monograph for researchers. The book has
+ three parts.
+
+ 1. Elementary Techniques shows how to model functional
+ programs in higher-order logic. Early examples involve
+ lists and the natural numbers. Most proofs are two steps
+ long, consisting of induction on a chosen variable followed
+ by the auto tactic. But even this elementary part covers
+ such advanced topics as nested and mutual recursion. 2.
+ Logic and Sets presents a collection of lower-level tactics
+ that you can use to apply rules selectively. It also
+ describes Isabelle/HOL's treatment of sets, functions and
+ relations and explains how to define sets inductively. One
+ of the examples concerns the theory of model checking, and
+ another is drawn from a classic textbook on formal
+ languages. 3. Advanced Material describes a variety of
+ other topics. Among these are the real numbers, records and
+ overloading. Advanced techniques are described involving
+ induction and recursion. A whole chapter is devoted to an
+ extended example: the verification of a security protocol.
+ },
+ year = 2002,
+ acknowledgement={brucker, 2007-02-19},
+ bibkey = {nipkow.ea:isabelle:2002}
+}
+
+@Misc{ dom-specification,
+ year = 2016,
+ month = {DOM Living Standard -- Last Updated 20 October 2016},
+ day = 20,
+ url = {https://dom.spec.whatwg.org/},
+ organization = {Web Hypertext Application Technology Working Group
+ (WHATWG)},
+ note = {An archived copy of the version from 20 October 2016 is
+ available at
+ \url{https://git.logicalhacking.com/BrowserSecurity/fDOM-idl/}.}
+}
+
+@InProceedings{ brucker.ea:core-dom:2018,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {A Formal Semantics of the Core {DOM} in {Isabelle/HOL}},
+ booktitle = {Proceedings of the Web Programming, Design, Analysis, And
+ Implementation (WPDAI) track at WWW 2018},
+ location = {Lyon, France},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-fdom-2018},
+ year = {2018},
+ abstract = {At its core, the Document Object Model (DOM) defines a
+ tree-like data structure for representing documents in
+ general and HTML documents in particular. It forms the
+ heart of any rendering engine of modern web browsers.
+ Formalizing the key concepts of the DOM is a pre-requisite
+ for the formal reasoning over client-side JavaScript
+ programs as well as for the analysis of security concepts
+ in modern web browsers. In this paper, 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. },
+ keywords = {Document Object Model, DOM, Formal Semantics,
+ Isabelle/HOL},
+ classification= {conference},
+ areas = {formal methods, software},
+ public = {yes}
+}
+@Article{ klein:operating:2009,
+ author = {Gerwin Klein},
+ title = {Operating System Verification --- An Overview},
+ journal = {S\={a}dhan\={a}},
+ publisher = pub-springer,
+ year = 2009,
+ volume = 34,
+ number = 1,
+ month = feb,
+ pages = {27--69},
+ abstract = {This paper gives a high-level introduction to the topic of
+ formal, interactive, machine-checked software verification
+ in general, and the verification of operating systems code
+ in particular. We survey the state of the art, the
+ advantages and limitations of machine-checked code proofs,
+ and describe two specific ongoing larger-scale verification
+ projects in more detail.}
+}
+
+
+@InProceedings{ gardner.ea:securing:2009,
+ author = {Ryan W. Gardner and Sujata Garera and Matthew W. Pagano
+ and Matthew Green and Aviel D. Rubin},
+ title = {Securing medical records on smart phones},
+ booktitle = {ACM workshop on Security and privacy in medical and
+ home-care systems (SPIMACS)},
+ year = 2009,
+ isbn = {978-1-60558-790-5},
+ pages = {31--40},
+ location = {Chicago, Illinois, USA},
+ doi = {10.1145/1655084.1655090},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ abstract = {There is an inherent conflict between the desire to
+ maintain privacy of one's medical records and the need to
+ make those records available during an emergency. To
+ satisfy both objectives, we introduce a flexible
+ architecture for the secure storage of medical records on
+ smart phones. In our system, a person can view her records
+ at any time, and emergency medical personnel can view the
+ records as long as the person is present (even if she is
+ unconscious). Our solution allows for efficient revocation
+ of access rights and is robust against adversaries who can
+ access the phone's storage offline.}
+}
+
+@InProceedings{ raad.ea:dom:2016,
+ author = {Azalea Raad and Jos{\'{e}} Fragoso Santos and Philippa
+ Gardner},
+ title = {{DOM:} Specification and Client Reasoning},
+ booktitle = {Programming Languages and Systems - 14th Asian Symposium,
+ {APLAS} 2016, Hanoi, Vietnam, November 21-23, 2016,
+ Proceedings},
+ pages = {401--422},
+ year = 2016,
+ crossref = {igarashi:programming:2016},
+ doi = {10.1007/978-3-319-47958-3_21},
+ abstract = {We present an axiomatic specification of a key fragment of
+ DOM using structural separation logic. This specification
+ allows us to develop modular reasoning about client
+ programs that call the DOM.}
+}
+
+
+@InProceedings{ bohannon.ea:featherweight:2010,
+ author = {Aaron Bohannon and Benjamin C. Pierce},
+ title = {Featherweight {F}irefox: {F}ormalizing the Core of a Web
+ Browser},
+ booktitle = {Usenix Conference on Web Application Development
+ (WebApps)},
+ year = 2010,
+ month = jun,
+ url = {http://www.cis.upenn.edu/~bohannon/browser-model/},
+ abstract = {We offer a formal specification of the core functionality
+ of a web browser in the form of a small-step operational
+ semantics. The specification accurately models the asyn-
+ chronous nature of web browsers and covers the basic as-
+ pects of windows, DOM trees, cookies, HTTP requests and
+ responses, user input, and a minimal scripting lan- guage
+ with first-class functions, dynamic evaluation, and AJAX
+ requests. No security enforcement mechanisms are
+ included{\^a}instead, the model is intended to serve as a
+ basis for formalizing and experimenting with different
+ security policies and mechanisms. We survey the most
+ interesting design choices and discuss how our model re-
+ lates to real web browsers.}
+}
+
+@Proceedings{ joyce.ea:higher:1994,
+ editor = {Jeffrey J. Joyce and Carl-Johan H. Seger},
+ title = {Higher Order Logic Theorem Proving and Its Applications
+ (HUG)},
+ booktitle = {Higher Order Logic Theorem Proving and Its Applications
+ (HUG)},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ abstract = {Theorem proving based techniques for formal hardware
+ verification have been evolving constantly and researchers
+ are getting able to reason about more complex issues than
+ it was possible or practically feasible in the past. It is
+ often the case that a model of a system is built in a
+ formal logic and then reasoning about this model is carried
+ out in the logic. Concern is growing on how to consistently
+ interface a model built in a formal logic with an informal
+ CAD environment. Researchers have been investigating how to
+ define the formal semantics of hardware description
+ languages so that one can formally reason about models
+ informally dealt with in a CAD environment. At the
+ University of Cambridge, the embedding of hardware
+ description languages in a logic is classified in two
+ categories: deep embedding and shallow embedding. In this
+ paper we argue that there are degrees of formality in
+ shallow embedding a language in a logic. The choice of the
+ degree of formality is a trade-off between the security of
+ the embedding and the amount and complexity of the proof
+ effort in the logic. We also argue that the design of a
+ language could consider this verifiability issue. There are
+ choices in the design of a language that can make it easier
+ to improve the degree of formality, without implying
+ serious drawbacks for the CAD environment.},
+ volume = 780,
+ year = 1994,
+ doi = {10.1007/3-540-57826-9},
+ isbn = {3-540-57826-9},
+ acknowledgement={brucker, 2007-02-19}
+}
+
+
+@Misc{ whatwg:dom:2017,
+ key={whatwg},
+ author={{WHATWG}},
+ url={https://dom.spec.whatwg.org/commit-snapshots/6253e53af2fbfaa6d25ad09fd54280d8083b2a97/},
+ month=mar,
+ year=2017,
+ day=24,
+ title={{DOM} -- Living Standard},
+ note={Last Updated 24 {March} 2017},
+ institution = {WHATWG},
+}
+
+@Misc{ whatwg:html:2017,
+ key={whatwg},
+ author={{WHATWG}},
+ url={https://html.spec.whatwg.org/},
+ month=apr,
+ year=2017,
+ day=13,
+ title={{HTML} -- Living Standard},
+ note={Last Updated 13 {April} 2017},
+ institution = {WHATWG},
+}
+
+
+@Misc{ w3c:dom:2015,
+ key={w3c},
+ author={{W3C}},
+ url={https://www.w3.org/TR/dom/},
+ month=nov,
+ year=2015,
+ day=19,
+ title={{W3C} {DOM4}},
+ institution = {W3C},
+}
+
+
+@Proceedings{ igarashi:programming:2016,
+ editor = {Atsushi Igarashi},
+ title = {Programming Languages and Systems - 14th Asian Symposium,
+ {APLAS} 2016, Hanoi, Vietnam, November 21-23, 2016,
+ Proceedings},
+ series = {Lecture Notes in Computer Science},
+ volume = 10017,
+ year = 2016,
+ doi = {10.1007/978-3-319-47958-3},
+ isbn = {978-3-319-47957-6}
+}
+
+
+
+
+
+
+@InProceedings{ gardner.ea:dom:2008,
+ author = {Philippa Gardner and Gareth Smith and Mark J. Wheelhouse
+ and Uri Zarfaty},
+ title = {{DOM:} Towards a Formal Specification},
+ booktitle = {{PLAN-X} 2008, Programming Language Technologies for XML,
+ An {ACM} {SIGPLAN} Workshop colocated with {POPL} 2008, San
+ Francisco, California, USA, January 9, 2008},
+ year = 2008,
+ crossref = {plan-x:2008},
+ url = {http://gemo.futurs.inria.fr/events/PLANX2008/papers/p18.pdf},
+ abstract = {The W3C Document Object Model (DOM) specifies an XML up-
+ date library. DOM is written in English, and is therefore
+ not compo- sitional and not complete. We provide a first
+ step towards a compo- sitional specification of DOM. Unlike
+ DOM, we are able to work with a minimal set of commands and
+ obtain a complete reason- ing for straight-line code. Our
+ work transfers O{\^a}Hearn, Reynolds and Yang{\^a}s
+ local Hoare reasoning for analysing heaps to XML, viewing
+ XML as an in-place memory store as does DOM. In par-
+ ticular, we apply recent work by Calcagno, Gardner and
+ Zarfaty on local Hoare reasoning about a simple tree-update
+ language to DOM, showing that our reasoning scales to DOM.
+ Our reasoning not only formally specifies a significant
+ subset of DOM Core Level 1, but can also be used to verify
+ e.g. invariant properties of simple Javascript programs.}
+}
+
+
+
+@InProceedings{ jang.ea:establishing:2012,
+ author = {Dongseok Jang and Zachary Tatlock and Sorin Lerner},
+ title = {Establishing Browser Security Guarantees through Formal
+ Shim Verification},
+ booktitle = {Proceedings of the 21th {USENIX} Security Symposium,
+ Bellevue, WA, USA, August 8-10, 2012},
+ pages = {113--128},
+ year = 2012,
+ crossref = {kohno:proceedings:2012},
+ url = {https://www.usenix.org/conference/usenixsecurity12/technical-sessions/presentation/jang},
+ abstract = { Web browsers mediate access to valuable private data in
+ domains ranging from health care to banking. Despite this
+ critical role, attackers routinely exploit browser
+ vulnerabilities to exfiltrate private data and take over
+ the un- derlying system. We present Q UARK , a browser
+ whose kernel has been implemented and verified in Coq. We
+ give a specification of our kernel, show that the
+ implementation satisfies the specification, and finally
+ show that the specification implies several security
+ properties, including tab non-interference, cookie
+ integrity and confidentiality, and address bar integrity.
+ }
+}
+
+@Proceedings{ kohno:proceedings:2012,
+ editor = {Tadayoshi Kohno},
+ title = {Proceedings of the 21th {USENIX} Security Symposium,
+ Bellevue, WA, USA, August 8-10, 2012},
+ publisher = {{USENIX} Association},
+ year = 2012,
+ timestamp = {Thu, 15 May 2014 09:12:27 +0200}
+}
+
+
+
+@Proceedings{ plan-x:2008,
+ title = {{PLAN-X} 2008, Programming Language Technologies for XML,
+ An {ACM} {SIGPLAN} Workshop colocated with {POPL} 2008, San
+ Francisco, California, USA, January 9, 2008},
+ year = 2008,
+ timestamp = {Fri, 18 Jan 2008 13:01:04 +0100}
+}
+
+
+@Article{ brucker.ea:extensible:2008-b,
+ abstract = {We present an extensible encoding of object-oriented data models into HOL. Our encoding is supported by a datatype package that leverages the use of the shallow embedding technique to object-oriented specification and programming languages. The package incrementally compiles an object-oriented data model, i.e., a class model, to a theory containing object-universes, constructors, accessor functions, coercions (casts) between dynamic and static types, characteristic sets, and co-inductive class invariants. The package is conservative, i.e., all properties are derived entirely from constant definitions, including the constraints over object structures. As an application, we use the package for an object-oriented core-language called IMP++, for which we formally prove the correctness of a Hoare-Logic with respect to a denotational semantics.},
+ address = {Heidelberg},
+ author = {Achim D. Brucker and Burkhart Wolff},
+ doi = {10.1007/s10817-008-9108-3},
+ issn = {0168-7433},
+ issue = {3},
+ journal = {Journal of Automated Reasoning},
+ keywords = {object-oriented data models, HOL, theorem proving, verification},
+ language = {USenglish},
+ pages = {219--249},
+ pdf = {https://www.brucker.ch/bibliography/download/2008/brucker.ea-extensible-2008-b.pdf},
+ publisher = {Springer-Verlag},
+ title = {An Extensible Encoding of Object-oriented Data Models in HOL},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-extensible-2008-b},
+ volume = {41},
+ year = {2008},
+}
+
+@PhDThesis{ brucker:interactive:2007,
+ abstract = {We present a semantic framework for object-oriented specification languages. We develop this framework as a conservative shallow embedding in Isabelle/HOL. Using only conservative extensions guarantees by construction the consistency of our formalization. Moreover, we show how our framework can be used to build an interactive proof environment, called HOL-OCL, for object-oriented specifications in general and for UML/OCL in particular.\\\\Our main contributions are an extensible encoding of object-oriented data structures in HOL, a datatype package for object-oriented specifications, and the development of several equational and tableaux calculi for object-oriented specifications. Further, we show that our formal framework can be the basis of a formal machine-checked semantics for OCL that is compliant to the OCL 2.0 standard.},
+ abstract_de = {In dieser Arbeit wird ein semantisches Rahmenwerk f{\"u}r objektorientierte Spezifikationen vorgestellt. Das Rahmenwerk ist als konservative, flache Einbettung in Isabelle/HOL realisiert. Durch die Beschr{\"a}nkung auf konservative Erweiterungen kann die logische Konsistenz der Einbettung garantiert werden. Das semantische Rahmenwerk wird verwendet, um das interaktives Beweissystem HOL-OCL f{\"u}r objektorientierte Spezifikationen im Allgemeinen und insbesondere f{\"u}r UML/OCL zu entwickeln.\\\\Die Hauptbeitr{\"a}ge dieser Arbeit sind die Entwicklung einer erweiterbaren Kodierung objektorientierter Datenstrukturen in HOL, ein Datentyp-Paket f{\"u}r objektorientierte Spezifikationen und die Entwicklung verschiedener Kalk{\"u}le f{\"u}r objektorientierte Spezifikationen. Zudem zeigen wir, wie das formale Rahmenwerk verwendet werden kann, um eine formale, maschinell gepr{\"u}fte Semantik f{\"u}r OCL anzugeben, die konform zum Standard f{\"u}r OCL 2.0 ist.},
+ author = {Achim D. Brucker},
+ keywords = {OCL, UML, formal semantics, theorem proving, Isabelle, HOL-OCL},
+ month = {mar},
+ note = {ETH Dissertation No. 17097.},
+ pdf = {https://www.brucker.ch/bibliography/download/2007/brucker-interactive-2007.pdf},
+ school = {ETH Zurich},
+ title = {An Interactive Proof Environment for Object-oriented Specifications},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker-interactive-2007},
+ year = {2007},
+}
+
+@InCollection{ brucker.ea:standard-compliance-testing:2018,
+ talk = {talk:brucker.ea:standard-compliance-testing:2018},
+ abstract = {Most popular technologies are based on informal or
+ semiformal standards that lack a rigid formal semantics.
+ Typical examples include web technologies such as the DOM
+ or HTML, which are defined by the Web Hypertext Application
+ Technology Working Group (WHATWG) and the World Wide Web
+ Consortium (W3C). While there might be API specifications
+ and test cases meant to assert the compliance of a certain
+ implementation, the actual standard is rarely accompanied
+ by a formal model that would lend itself for, e.g.,
+ verifying the security or safety properties of real
+ systems.
+
+ Even when such a formalization of a standard exists, two
+ important questions arise: first, to what extend does the
+ formal model comply to the standard and, second, to what
+ extend does the implementation comply to the formal model
+ and the assumptions made during the verification? In this
+ paper, we present an approach that brings all three
+ involved artifacts - the (semi-)formal standard, the
+ formalization of the standard, and the implementations -
+ closer together by combining verification, symbolic
+ execution, and specification based testing.},
+ keywords = {standard compliance, compliance tests, DOM},
+ location = {Toulouse, France},
+ author = {Achim D. Brucker and Michael Herzberg},
+ booktitle = {{TAP} 2018: Tests And Proofs},
+ language = {USenglish},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ number = 10889,
+ editor = {Cathrine Dubois and Burkhart Wolff},
+ title = {Formalizing (Web) Standards: An Application of Test and
+ Proof},
+ categories = {holtestgen, websecurity},
+ classification= {conference},
+ areas = {formal methods, software engineering},
+ public = {yes},
+ year = 2018,
+ doi = {10.1007/978-3-319-92994-1_9},
+ pages = {159--166},
+ isbn = {978-3-642-38915-3},
+ pdf = {http://www.brucker.ch/bibliography/download/2018/brucker.ea-standard-compliance-testing-2018.pdf},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-standard-compliance-testing-2018}
+}
+
+
+@InCollection{ brucker.ea:interactive:2005,
+ keywords = {symbolic test case generations, black box testing, white
+ box testing, theorem proving, interactive testing},
+ abstract = {HOL-TestGen is a test environment for specification-based
+ unit testing build upon the proof assistant Isabelle/HOL\@.
+ While there is considerable skepticism with regard to
+ interactive theorem provers in testing communities, we
+ argue that they are a natural choice for (automated)
+ symbolic computations underlying systematic tests. This
+ holds in particular for the development on non-trivial
+ formal test plans of complex software, where some parts of
+ the overall activity require inherently guidance by a test
+ engineer. In this paper, we present the underlying methods
+ for both black box and white box testing in interactive
+ unit test scenarios. HOL-TestGen can also be understood as
+ a unifying technical and conceptual framework for
+ presenting and investigating the variety of unit test
+ techniques in a logically consistent way. },
+ location = {Edinburgh},
+ author = {Achim D. Brucker and Burkhart Wolff},
+ booktitle = {Formal Approaches to Testing of Software},
+ language = {USenglish},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ number = 3997,
+ doi = {10.1007/11759744_7},
+ isbn = {3-540-25109-X},
+ editor = {Wolfgang Grieskamp and Carsten Weise},
+ pdf = {http://www.brucker.ch/bibliography/download/2005/brucker.ea-interactive-2005.pdf},
+ project = {CSFMDOS},
+ title = {Interactive Testing using {HOL}-{TestGen}},
+ classification= {workshop},
+ areas = {formal methods, software},
+ categories = {holtestgen},
+ year = 2005,
+ public = {yes},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-interactive-2005}
+}
+
+
+@Article{ brucker.ea:theorem-prover:2012,
+ author = {Achim D. Brucker and Burkhart Wolff},
+ journal = j-fac,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ language = {USenglish},
+ categories = {holtestgen},
+ title = {On Theorem Prover-based Testing},
+ year = 2013,
+ issn = {0934-5043},
+ pages = {683--721},
+ volume = 25,
+ number = 5,
+ classification= {journal},
+ areas = {formal methods, software},
+ public = {yes},
+ doi = {10.1007/s00165-012-0222-y},
+ keywords = {test case generation, domain partitioning, test sequence,
+ theorem proving, HOL-TestGen},
+ abstract = {HOL-TestGen is a specification and test case generation
+ environment extending the interactive theorem prover
+ Isabelle/HOL. As such, HOL-TestGen allows for an integrated
+ workflow supporting interactive theorem proving, test case
+ generation, and test data generation.
+
+ The HOL-TestGen method is two-staged: first, the original
+ formula is partitioned into test cases by transformation
+ into a normal form called test theorem. Second, the test
+ cases are analyzed for ground instances (the test data)
+ satisfying the constraints of the test cases. Particular
+ emphasis is put on the control of explicit test-hypotheses
+ which can be proven over concrete programs.
+
+ Due to the generality of the underlying framework, our
+ system can be used for black-box unit, sequence, reactive
+ sequence and white-box test scenarios. Although based on
+ particularly clean theoretical foundations, the system can
+ be applied for substantial case-studies. },
+ pdf = {http://www.brucker.ch/bibliography/download/2012/brucker.ea-theorem-prover-2012.pdf},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-theorem-prover-2012}
+}
+
+
+
+@Article{ brucker.ea:afp-core-dom:2018,
+ 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.},
+ author = {Achim D. Brucker and Michael Herzberg},
+ date = {2018-12-26},
+ file = {https://www.brucker.ch/bibliography/download/2018/brucker.ea-afp-core-dom-outline-2018.pdf},
+ filelabel = {Outline},
+ issn = {2150-914x},
+ journal = {Archive of Formal Proofs},
+ month = {dec},
+ note = {\url{http://www.isa-afp.org/entries/Core_DOM.html}, Formal proof development},
+ pdf = {https://www.brucker.ch/bibliography/download/2018/brucker.ea-afp-core-dom-2018.pdf},
+ title = {The {Core} {DOM}},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-afp-core-dom-2018},
+ year = {2018},
+}
+
+@PhdThesis{herzberg:web-components:2020,
+ author = {Michael Herzberg},
+ title = {Formal Foundations for Provably Safe Web Components},
+ school = {The University of Sheffield},
+ year = {2020}
+}
+
diff --git a/thys/Core_SC_DOM/document/root.tex b/thys/Core_SC_DOM/document/root.tex
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/document/root.tex
@@ -0,0 +1,268 @@
+\documentclass[10pt,DIV16,a4paper,abstract=true,twoside=semi,openright]
+{scrreprt}
+\usepackage[USenglish]{babel}
+\usepackage[numbers, sort&compress]{natbib}
+\usepackage{isabelle,isabellesym}
+\usepackage{booktabs}
+\usepackage{paralist}
+\usepackage{graphicx}
+\usepackage{amssymb}
+\usepackage{xspace}
+\usepackage{xcolor}
+\usepackage{listings}
+\lstloadlanguages{HTML}
+\usepackage[]{mathtools}
+\usepackage[pdfpagelabels, pageanchor=false, plainpages=false]{hyperref}
+\lstdefinestyle{html}{language=XML,
+ basicstyle=\ttfamily,
+ commentstyle=\itshape,
+ keywordstyle=\color{blue},
+ ndkeywordstyle=\color{blue},
+}
+\lstdefinestyle{displayhtml}{style=html,
+ floatplacement={tbp},
+ captionpos=b,
+ framexleftmargin=0pt,
+ basicstyle=\ttfamily\scriptsize,
+ backgroundcolor=\color{black!2},
+ frame=lines,
+}
+\lstnewenvironment{html}[1][]{\lstset{style=displayhtml, #1}}{}
+\def\inlinehtml{\lstinline[style=html, columns=fullflexible]}
+
+\pagestyle{headings}
+\isabellestyle{default}
+\setcounter{tocdepth}{1}
+\newcommand{\ie}{i.\,e.\xspace}
+\newcommand{\eg}{e.\,g.\xspace}
+\newcommand{\thy}{\isabellecontext}
+\renewcommand{\isamarkupsection}[1]{%
+ \begingroup%
+ \def\isacharunderscore{\textunderscore}%
+ \section{#1 (\thy)}%
+ \endgroup%
+}
+
+\title{Core SC DOM\\\medskip \Large
+ A Formal Model of the Document Object Model for Safe Components}%
+\author{%
+ \href{https://www.brucker.ch/}{Achim~D.~Brucker}\footnotemark[1]
+ \and
+ \href{https://www.michael-herzberg.de/}{Michael Herzberg}\footnotemark[2]
+}
+
+\publishers{
+ \footnotemark[1]~Department of Computer Science, University of Exeter, Exeter, UK\texorpdfstring{\\}{, }
+ \texttt{a.brucker@exeter.ac.uk}\\[2em]
+ %
+ \footnotemark[2]~ Department of Computer Science, The University of Sheffield, Sheffield, UK\texorpdfstring{\\}{, }
+ \texttt{msherzberg1@sheffield.ac.uk}
+}
+\begin{document}
+ \maketitle
+ \begin{abstract}
+ \begin{quote}
+ In this AFP entry, we formalize the core of the \emph{Safely
+ Composable Document Object Model} (SC DOM). The SC DOM improve
+ the standard 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.
+
+ \bigskip
+ \noindent{\textbf{Keywords:}}
+ Document Object Model, DOM, SC DOM, Safely Composable DOM, Formal Semantics, Isabelle/HOL
+ \end{quote}
+ \end{abstract}
+
+
+\tableofcontents
+\cleardoublepage
+
+\chapter{Introduction}
+In a world in which more and more applications are offered as services
+on the internet, web browsers start to take on a similarly central
+role in our daily IT infrastructure as operating systems. Thus, web
+browsers should be developed as rigidly and formally as operating
+systems. While formal methods are a well-established technique in the
+development of operating systems (see,
+\eg,~\citet{klein:operating:2009} for an overview of formal
+verification of operating systems), there are few proposals for
+improving the development of web browsers using formal
+approaches~\cite{gardner.ea:dom:2008,raad.ea:dom:2016,jang.ea:establishing:2012,bohannon.ea:featherweight:2010}.
+
+As a first step towards a verified client-side web application stack,
+we model and formally verify the Document Object Model (DOM) in
+Isabelle/HOL\@. The DOM~\cite{whatwg:dom:2017,w3c:dom:2015} is
+\emph{the} central data structure of all modern web browsers. At its
+core, the Document Object Model (DOM), defines a tree-like data
+structure for representing documents in general and HTML documents in
+particular. Thus, the correctness of a DOM implementation is crucial
+for ensuring that a web browser displays web pages correctly.
+Moreover, the DOM is the core data structure underlying client-side
+JavaScript programs, \ie, client-side JavaScript programs are mostly
+programs that read, write, and update the DOM.
+
+In more detail, we formalize the core core of the \emph{Safely
+ Composable Document Object Model} (SC DOM) a shallow
+embedding~\cite{joyce.ea:higher:1994} in Isabelle/HOL\@. Our
+formalization is based on a typed data model for the \emph{node-tree},
+\ie, a data structure for representing XML-like documents in a tree
+structure. Furthermore, we formalize a typed heap for storing
+(partial) node-trees together with the necessary consistency
+constraints. Finally, we formalize the operations (as described in the
+DOM standard~\cite{whatwg:dom:2017}) on this heap that allow
+manipulating node-trees.
+
+Our machine-checked formalization of the DOM node
+tree~\cite{whatwg:dom:2017} has the following desirable properties:
+\begin{itemize}
+\item It provides a \emph{consistency guarantee.} Since all
+ definitions in our formal semantics are conservative and all rules
+ are derived, the logical consistency of the DOM node-tree is reduced
+ to the consistency of HOL.
+\item It serves as a \emph{technical basis for a proof system.} Based
+ on the derived rules and specific setup of proof tactics over
+ node-trees, our formalization provides a generic proof environment
+ for the verification of programs manipulating node-trees.
+\item It is \emph{executable}, which allows to validate its compliance
+ to the standard by evaluating the compliance test suite on the
+ formal model and
+\item It is \emph{extensible} in the sense
+ of~\cite{brucker.ea:extensible:2008-b,brucker:interactive:2007},
+ \ie, properties proven over the core DOM do not need to be re-proven
+ for object-oriented extensions such as the HTML document model.
+\end{itemize}
+
+The rest of this document is automatically generated from the
+formalization in Isabelle/HOL, i.e., all content is checked by
+Isabelle.\footnote{For a brief overview of the work, we refer the
+ reader to~\cite{brucker.ea:core-dom:2018,herzberg:web-components:2020}.}
+The structure follows the theory dependencies (see \autoref{fig:session-graph}): we start
+with introducing the technical preliminaries of our formalization
+(\autoref{cha:perliminaries}). Next, we introduce the concepts of
+pointers (\autoref{cha:pointers}) and classes (\autoref{cha:classes}),
+i.e., the core object-oriented datatypes of the DOM. On top of this
+data model, we define the functional behavior of the DOM classes,
+i.e., their methods (\autoref{cha:monads}). In \autoref{cha:dom}, we
+introduce the formalization of the functionality of the core DOM,
+i.e., the \emph{main entry point for users} that want to use this AFP
+entry. Finally, we formalize the relevant compliance test cases in
+\autoref{cha:tests}.
+
+\paragraph{Important Note:} This document describes the formalization
+of the \emph{Safely Composable Document Object Model} (SC DOM), which
+deviated in one important aspect from the official DOM standard: in
+the SC DOM, the shadow root is a sub-class of the document class
+(instead of a base class). This modification results in a stronger
+notion of web components that provide improved safety properties for
+the composition of web components. While the SC DOM still passes the
+compliance test suite as provided by the authors of the DOM standard,
+its data model is different. We refer readers interested in a
+formalisation of the standard compliant DOM to the AFP entry
+``Core\_DOM''~\cite{brucker.ea:afp-core-dom:2018}.
+
+
+\begin{figure}
+ \centering
+ \includegraphics[width=.8\textwidth]{session_graph}
+ \caption{The Dependency Graph of the Isabelle Theories.\label{fig:session-graph}}
+\end{figure}
+
+\clearpage
+
+\chapter{Preliminaries}
+\label{cha:perliminaries}
+In this chapter, we introduce the technical preliminaries of our
+formalization of the core DOM, namely a mechanism for hiding type
+variables and the heap error monad.
+\input{Hiding_Type_Variables}
+\input{Heap_Error_Monad}
+
+\chapter{References and Pointers}
+\label{cha:pointers}
+In this chapter, we introduce a generic type for object-oriented
+references and typed pointers for each class type defined in the DOM
+standard.
+\input{Ref}
+\input{ObjectPointer}
+\input{NodePointer}
+\input{ElementPointer} brucker.ea:afp-core-dom:2018
+\input{CharacterDataPointer}
+\input{DocumentPointer}
+\input{ShadowRootPointer}
+
+\chapter{Classes}
+\label{cha:classes}
+In this chapter, we introduce the classes of our DOM model.
+The definition of the class types follows closely the one of the
+pointer types. Instead of datatypes, we use records for our classes.
+a generic type for object-oriented references and typed pointers for
+each class type defined in the DOM standard.
+\input{BaseClass}
+\input{ObjectClass}
+\input{NodeClass}
+\input{ElementClass}
+\input{CharacterDataClass}
+\input{DocumentClass}
+
+\chapter{Monadic Object Constructors and Accessors}
+\label{cha:monads}
+In this chapter, we introduce the moandic method definitions for the
+classes of our DOM formalization. Again the overall structure follows
+the same structure as for the class types and the pointer types.
+\input{BaseMonad}
+\input{ObjectMonad}
+\input{NodeMonad}
+\input{ElementMonad}
+\input{CharacterDataMonad}
+\input{DocumentMonad}
+
+\chapter{The Core SC DOM}
+\label{cha:dom}
+In this chapter, we introduce the formalization of the core DOM, i.e.,
+the most important algorithms for querying or modifying the DOM, as
+defined in the standard. For more details, we refer the reader to
+\cite{brucker.ea:core-dom:2018}.
+\input{Core_DOM_Basic_Datatypes}
+\input{Core_DOM_Functions}
+\input{Core_DOM_Heap_WF}
+\input{Core_DOM}
+
+\chapter{Test Suite}
+\label{cha:tests}
+In this chapter, we present the formalized compliance test cases for
+the core DOM. As our formalization is executable, we can
+(symbolically) execute the test cases on top of our model. Executing
+these test cases successfully shows that our model is compliant to the
+official DOM standard. As future work, we plan to generate test cases
+from our formal model (e.g.,
+using~\cite{brucker.ea:interactive:2005,brucker.ea:theorem-prover:2012})
+to improve the quality of the official compliance test suite. For more
+details on the relation of test and proof in the context of web
+standards, we refer the reader to
+\cite{brucker.ea:standard-compliance-testing:2018}.
+\input{Core_DOM_BaseTest} \input{Document_adoptNode}
+\input{Document_getElementById} \input{Node_insertBefore}
+\input{Node_removeChild} \input{Core_DOM_Tests}
+
+{\small
+ \bibliographystyle{abbrvnat}
+ \bibliography{root}
+}
+\end{document}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: t
+%%% End:
diff --git a/thys/Core_SC_DOM/safely_composable/Core_DOM_Heap_WF.thy b/thys/Core_SC_DOM/safely_composable/Core_DOM_Heap_WF.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/safely_composable/Core_DOM_Heap_WF.thy
@@ -0,0 +1,6965 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Wellformedness\<close>
+text\<open>In this theory, we discuss the wellformedness of the DOM. First, we define
+wellformedness and, second, we show for all functions for querying and modifying the
+DOM to what extend they preserve wellformendess.\<close>
+
+theory Core_DOM_Heap_WF
+ imports
+ "Core_DOM_Functions"
+begin
+
+locale l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_child_nodes_defs get_child_nodes get_child_nodes_locs +
+ l_get_disconnected_nodes_defs get_disconnected_nodes get_disconnected_nodes_locs
+ for get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+definition a_owner_document_valid :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_owner_document_valid h \<longleftrightarrow> (\<forall>node_ptr \<in> fset (node_ptr_kinds h).
+ ((\<exists>document_ptr. document_ptr |\<in>| document_ptr_kinds h
+ \<and> node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ \<or> (\<exists>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h
+ \<and> node_ptr \<in> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r)))"
+
+lemma a_owner_document_valid_code [code]: "a_owner_document_valid h \<longleftrightarrow> node_ptr_kinds h |\<subseteq>|
+ fset_of_list (concat (map (\<lambda>parent. |h \<turnstile> get_child_nodes parent|\<^sub>r)
+(sorted_list_of_fset (object_ptr_kinds h)) @
+map (\<lambda>parent. |h \<turnstile> get_disconnected_nodes parent|\<^sub>r)
+(sorted_list_of_fset (document_ptr_kinds h))))
+"
+ apply(auto simp add: a_owner_document_valid_def l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_owner_document_valid_def)[1]
+proof -
+ fix x
+ assume 1: " \<forall>node_ptr\<in>fset (node_ptr_kinds h).
+ (\<exists>document_ptr. document_ptr |\<in>| document_ptr_kinds h \<and>
+node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r) \<or>
+ (\<exists>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h \<and> node_ptr \<in> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r)"
+ assume 2: "x |\<in>| node_ptr_kinds h"
+ assume 3: "x |\<notin>| fset_of_list (concat (map (\<lambda>parent. |h \<turnstile> get_disconnected_nodes parent|\<^sub>r)
+(sorted_list_of_fset (document_ptr_kinds h))))"
+ have "\<not>(\<exists>document_ptr. document_ptr |\<in>| document_ptr_kinds h \<and> x \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)"
+ using 1 2 3
+ by (smt UN_I fset_of_list_elem image_eqI notin_fset set_concat set_map sorted_list_of_fset_simps(1))
+ then
+ have "(\<exists>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h \<and> x \<in> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r)"
+ using 1 2
+ by auto
+ then obtain parent_ptr where parent_ptr: "parent_ptr |\<in>| object_ptr_kinds h \<and>
+x \<in> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r"
+ by auto
+ moreover have "parent_ptr \<in> set (sorted_list_of_fset (object_ptr_kinds h))"
+ using parent_ptr by auto
+ moreover have "|h \<turnstile> get_child_nodes parent_ptr|\<^sub>r \<in> set (map (\<lambda>parent. |h \<turnstile> get_child_nodes parent|\<^sub>r)
+(sorted_list_of_fset (object_ptr_kinds h)))"
+ using calculation(2) by auto
+ ultimately
+ show "x |\<in>| fset_of_list (concat (map (\<lambda>parent. |h \<turnstile> get_child_nodes parent|\<^sub>r)
+(sorted_list_of_fset (object_ptr_kinds h))))"
+ using fset_of_list_elem by fastforce
+next
+ fix node_ptr
+ assume 1: "node_ptr_kinds h |\<subseteq>| fset_of_list (concat (map (\<lambda>parent. |h \<turnstile> get_child_nodes parent|\<^sub>r)
+(sorted_list_of_fset (object_ptr_kinds h)))) |\<union>|
+fset_of_list (concat (map (\<lambda>parent. |h \<turnstile> get_disconnected_nodes parent|\<^sub>r)
+(sorted_list_of_fset (document_ptr_kinds h))))"
+ assume 2: "node_ptr |\<in>| node_ptr_kinds h"
+ assume 3: "\<forall>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h \<longrightarrow> node_ptr \<notin> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r"
+ have "node_ptr \<in> set (concat (map (\<lambda>parent. |h \<turnstile> get_child_nodes parent|\<^sub>r)
+(sorted_list_of_fset (object_ptr_kinds h)))) \<or>
+node_ptr \<in> set (concat (map (\<lambda>parent. |h \<turnstile> get_disconnected_nodes parent|\<^sub>r)
+(sorted_list_of_fset (document_ptr_kinds h))))"
+ using 1 2
+ by (meson fin_mono fset_of_list_elem funion_iff)
+ then
+ show "\<exists>document_ptr. document_ptr |\<in>| document_ptr_kinds h \<and>
+node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ using 3
+ by auto
+qed
+
+definition a_parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ where
+ "a_parent_child_rel h = {(parent, child). parent |\<in>| object_ptr_kinds h
+ \<and> child \<in> cast ` set |h \<turnstile> get_child_nodes parent|\<^sub>r}"
+
+lemma a_parent_child_rel_code [code]: "a_parent_child_rel h = set (concat (map
+ (\<lambda>parent. map
+ (\<lambda>child. (parent, cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child))
+ |h \<turnstile> get_child_nodes parent|\<^sub>r)
+ (sorted_list_of_fset (object_ptr_kinds h)))
+)"
+ by(auto simp add: a_parent_child_rel_def)
+
+definition a_acyclic_heap :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_acyclic_heap h = acyclic (a_parent_child_rel h)"
+
+definition a_all_ptrs_in_heap :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_all_ptrs_in_heap h \<longleftrightarrow>
+ (\<forall>ptr \<in> fset (object_ptr_kinds h). set |h \<turnstile> get_child_nodes ptr|\<^sub>r \<subseteq> fset (node_ptr_kinds h)) \<and>
+ (\<forall>document_ptr \<in> fset (document_ptr_kinds h).
+set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r \<subseteq> fset (node_ptr_kinds h))"
+
+definition a_distinct_lists :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_distinct_lists h = distinct (concat (
+ (map (\<lambda>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r) |h \<turnstile> object_ptr_kinds_M|\<^sub>r)
+ @ (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r) |h \<turnstile> document_ptr_kinds_M|\<^sub>r)
+ ))"
+
+definition a_heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_heap_is_wellformed h \<longleftrightarrow>
+ a_acyclic_heap h \<and> a_all_ptrs_in_heap h \<and> a_distinct_lists h \<and> a_owner_document_valid h"
+end
+
+locale l_heap_is_wellformed_defs =
+ fixes heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ fixes parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+
+global_interpretation l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs
+ defines heap_is_wellformed = "l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_heap_is_wellformed get_child_nodes
+ get_disconnected_nodes"
+ and parent_child_rel = "l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_parent_child_rel get_child_nodes"
+ and acyclic_heap = a_acyclic_heap
+ and all_ptrs_in_heap = a_all_ptrs_in_heap
+ and distinct_lists = a_distinct_lists
+ and owner_document_valid = a_owner_document_valid
+ .
+
+locale l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs
+ + l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs
+ + l_heap_is_wellformed_defs heap_is_wellformed parent_child_rel
+ + l_get_disconnected_nodes type_wf get_disconnected_nodes get_disconnected_nodes_locs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set" +
+ assumes heap_is_wellformed_impl: "heap_is_wellformed = a_heap_is_wellformed"
+ assumes parent_child_rel_impl: "parent_child_rel = a_parent_child_rel"
+begin
+lemmas heap_is_wellformed_def = heap_is_wellformed_impl[unfolded a_heap_is_wellformed_def]
+lemmas parent_child_rel_def = parent_child_rel_impl[unfolded a_parent_child_rel_def]
+lemmas acyclic_heap_def = a_acyclic_heap_def[folded parent_child_rel_impl]
+
+lemma parent_child_rel_node_ptr:
+ "(parent, child) \<in> parent_child_rel h \<Longrightarrow> is_node_ptr_kind child"
+ by(auto simp add: parent_child_rel_def)
+
+lemma parent_child_rel_child_nodes:
+ assumes "known_ptr parent"
+ and "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children"
+ and "child \<in> set children"
+ shows "(parent, cast child) \<in> parent_child_rel h"
+ using assms
+ apply(auto simp add: parent_child_rel_def is_OK_returns_result_I )[1]
+ using get_child_nodes_ptr_in_heap by blast
+
+lemma parent_child_rel_child_nodes2:
+ assumes "known_ptr parent"
+ and "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children"
+ and "child \<in> set children"
+ and "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child = child_obj"
+ shows "(parent, child_obj) \<in> parent_child_rel h"
+ using assms parent_child_rel_child_nodes by blast
+
+
+lemma parent_child_rel_finite: "finite (parent_child_rel h)"
+proof -
+ have "parent_child_rel h = (\<Union>ptr \<in> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r.
+ (\<Union>child \<in> set |h \<turnstile> get_child_nodes ptr|\<^sub>r. {(ptr, cast child)}))"
+ by(auto simp add: parent_child_rel_def)
+ moreover have "finite (\<Union>ptr \<in> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r.
+ (\<Union>child \<in> set |h \<turnstile> get_child_nodes ptr|\<^sub>r. {(ptr, cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child)}))"
+ by simp
+ ultimately show ?thesis
+ by simp
+qed
+
+lemma distinct_lists_no_parent:
+ assumes "a_distinct_lists h"
+ assumes "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes"
+ assumes "node_ptr \<in> set disc_nodes"
+ shows "\<not>(\<exists>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h
+ \<and> node_ptr \<in> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r)"
+ using assms
+ apply(auto simp add: a_distinct_lists_def)[1]
+proof -
+ fix parent_ptr :: "(_) object_ptr"
+ assume a1: "parent_ptr |\<in>| object_ptr_kinds h"
+ assume a2: "(\<Union>x\<in>fset (object_ptr_kinds h).
+ set |h \<turnstile> get_child_nodes x|\<^sub>r) \<inter> (\<Union>x\<in>fset (document_ptr_kinds h).
+ set |h \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ assume a3: "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes"
+ assume a4: "node_ptr \<in> set disc_nodes"
+ assume a5: "node_ptr \<in> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r"
+ have f6: "parent_ptr \<in> fset (object_ptr_kinds h)"
+ using a1 by auto
+ have f7: "document_ptr \<in> fset (document_ptr_kinds h)"
+ using a3 by (meson fmember.rep_eq get_disconnected_nodes_ptr_in_heap is_OK_returns_result_I)
+ have "|h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r = disc_nodes"
+ using a3 by simp
+ then show False
+ using f7 f6 a5 a4 a2 by blast
+qed
+
+
+lemma distinct_lists_disconnected_nodes:
+ assumes "a_distinct_lists h"
+ and "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes"
+ shows "distinct disc_nodes"
+proof -
+ have h1: "distinct (concat (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ |h \<turnstile> document_ptr_kinds_M|\<^sub>r))"
+ using assms(1)
+ by(simp add: a_distinct_lists_def)
+ then show ?thesis
+ using concat_map_all_distinct[OF h1] assms(2) is_OK_returns_result_I get_disconnected_nodes_ok
+ by (metis (no_types, lifting) DocumentMonad.ptr_kinds_ptr_kinds_M
+ l_get_disconnected_nodes.get_disconnected_nodes_ptr_in_heap
+ l_get_disconnected_nodes_axioms select_result_I2)
+qed
+
+lemma distinct_lists_children:
+ assumes "a_distinct_lists h"
+ and "known_ptr ptr"
+ and "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ shows "distinct children"
+proof (cases "children = []", simp)
+ assume "children \<noteq> []"
+ have h1: "distinct (concat ((map (\<lambda>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r) |h \<turnstile> object_ptr_kinds_M|\<^sub>r)))"
+ using assms(1)
+ by(simp add: a_distinct_lists_def)
+ show ?thesis
+ using concat_map_all_distinct[OF h1] assms(2) assms(3)
+ by (metis (no_types, lifting) ObjectMonad.ptr_kinds_ptr_kinds_M get_child_nodes_ptr_in_heap
+ is_OK_returns_result_I select_result_I2)
+qed
+
+lemma heap_is_wellformed_children_in_heap:
+ assumes "heap_is_wellformed h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assumes "child \<in> set children"
+ shows "child |\<in>| node_ptr_kinds h"
+ using assms
+ apply(auto simp add: heap_is_wellformed_def a_all_ptrs_in_heap_def)[1]
+ by (metis (no_types, lifting) finite_set_in is_OK_returns_result_I
+ local.get_child_nodes_ptr_in_heap select_result_I2 subsetD)
+
+lemma heap_is_wellformed_one_parent:
+ assumes "heap_is_wellformed h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assumes "h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children'"
+ assumes "set children \<inter> set children' \<noteq> {}"
+ shows "ptr = ptr'"
+ using assms
+proof (auto simp add: heap_is_wellformed_def a_distinct_lists_def)[1]
+ fix x :: "(_) node_ptr"
+ assume a1: "ptr \<noteq> ptr'"
+ assume a2: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assume a3: "h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children'"
+ assume a4: "distinct (concat (map (\<lambda>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h)))))"
+ have f5: "|h \<turnstile> get_child_nodes ptr|\<^sub>r = children"
+ using a2 by simp
+ have "|h \<turnstile> get_child_nodes ptr'|\<^sub>r = children'"
+ using a3 by (meson select_result_I2)
+ then have "ptr \<notin> set (sorted_list_of_set (fset (object_ptr_kinds h)))
+ \<or> ptr' \<notin> set (sorted_list_of_set (fset (object_ptr_kinds h)))
+ \<or> set children \<inter> set children' = {}"
+ using f5 a4 a1 by (meson distinct_concat_map_E(1))
+ then show False
+ using a3 a2 by (metis (no_types) assms(4) finite_fset fmember.rep_eq is_OK_returns_result_I
+ local.get_child_nodes_ptr_in_heap set_sorted_list_of_set)
+qed
+
+lemma parent_child_rel_child:
+ "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> child \<in> set children \<longleftrightarrow> (ptr, cast child) \<in> parent_child_rel h"
+ by (simp add: is_OK_returns_result_I get_child_nodes_ptr_in_heap parent_child_rel_def)
+
+lemma parent_child_rel_acyclic: "heap_is_wellformed h \<Longrightarrow> acyclic (parent_child_rel h)"
+ by (simp add: acyclic_heap_def local.heap_is_wellformed_def)
+
+lemma heap_is_wellformed_disconnected_nodes_distinct:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes \<Longrightarrow> distinct disc_nodes"
+ using distinct_lists_disconnected_nodes local.heap_is_wellformed_def by blast
+
+lemma parent_child_rel_parent_in_heap:
+ "(parent, child_ptr) \<in> parent_child_rel h \<Longrightarrow> parent |\<in>| object_ptr_kinds h"
+ using local.parent_child_rel_def by blast
+
+lemma parent_child_rel_child_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptr parent
+ \<Longrightarrow> (parent, child_ptr) \<in> parent_child_rel h \<Longrightarrow> child_ptr |\<in>| object_ptr_kinds h"
+ apply(auto simp add: heap_is_wellformed_def parent_child_rel_def a_all_ptrs_in_heap_def)[1]
+ using get_child_nodes_ok
+ by (meson finite_set_in subsetD)
+
+lemma heap_is_wellformed_disc_nodes_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes
+ \<Longrightarrow> node \<in> set disc_nodes \<Longrightarrow> node |\<in>| node_ptr_kinds h"
+ by (metis (no_types, lifting) finite_set_in is_OK_returns_result_I local.a_all_ptrs_in_heap_def
+ local.get_disconnected_nodes_ptr_in_heap local.heap_is_wellformed_def select_result_I2 subsetD)
+
+lemma heap_is_wellformed_one_disc_parent:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes
+ \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr' \<rightarrow>\<^sub>r disc_nodes'
+ \<Longrightarrow> set disc_nodes \<inter> set disc_nodes' \<noteq> {} \<Longrightarrow> document_ptr = document_ptr'"
+ using DocumentMonad.ptr_kinds_ptr_kinds_M concat_append distinct_append distinct_concat_map_E(1)
+ is_OK_returns_result_I local.a_distinct_lists_def local.get_disconnected_nodes_ptr_in_heap
+ local.heap_is_wellformed_def select_result_I2
+proof -
+ assume a1: "heap_is_wellformed h"
+ assume a2: "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes"
+ assume a3: "h \<turnstile> get_disconnected_nodes document_ptr' \<rightarrow>\<^sub>r disc_nodes'"
+ assume a4: "set disc_nodes \<inter> set disc_nodes' \<noteq> {}"
+ have f5: "|h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r = disc_nodes"
+ using a2 by (meson select_result_I2)
+ have f6: "|h \<turnstile> get_disconnected_nodes document_ptr'|\<^sub>r = disc_nodes'"
+ using a3 by (meson select_result_I2)
+ have "\<And>nss nssa. \<not> distinct (concat (nss @ nssa)) \<or> distinct (concat nssa::(_) node_ptr list)"
+ by (metis (no_types) concat_append distinct_append)
+ then have "distinct (concat (map (\<lambda>d. |h \<turnstile> get_disconnected_nodes d|\<^sub>r) |h \<turnstile> document_ptr_kinds_M|\<^sub>r))"
+ using a1 local.a_distinct_lists_def local.heap_is_wellformed_def by blast
+ then show ?thesis
+ using f6 f5 a4 a3 a2 by (meson DocumentMonad.ptr_kinds_ptr_kinds_M distinct_concat_map_E(1)
+ is_OK_returns_result_I local.get_disconnected_nodes_ptr_in_heap)
+qed
+
+lemma heap_is_wellformed_children_disc_nodes_different:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes
+ \<Longrightarrow> set children \<inter> set disc_nodes = {}"
+ by (metis (no_types, hide_lams) disjoint_iff_not_equal distinct_lists_no_parent
+ is_OK_returns_result_I local.get_child_nodes_ptr_in_heap
+ local.heap_is_wellformed_def select_result_I2)
+
+lemma heap_is_wellformed_children_disc_nodes:
+ "heap_is_wellformed h \<Longrightarrow> node_ptr |\<in>| node_ptr_kinds h
+ \<Longrightarrow> \<not>(\<exists>parent \<in> fset (object_ptr_kinds h). node_ptr \<in> set |h \<turnstile> get_child_nodes parent|\<^sub>r)
+ \<Longrightarrow> (\<exists>document_ptr \<in> fset (document_ptr_kinds h). node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)"
+ apply(auto simp add: heap_is_wellformed_def a_distinct_lists_def a_owner_document_valid_def)[1]
+ by (meson fmember.rep_eq)
+lemma heap_is_wellformed_children_distinct:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> distinct children"
+ by (metis (no_types, lifting) ObjectMonad.ptr_kinds_ptr_kinds_M concat_append distinct_append
+ distinct_concat_map_E(2) is_OK_returns_result_I local.a_distinct_lists_def
+ local.get_child_nodes_ptr_in_heap local.heap_is_wellformed_def
+ select_result_I2)
+end
+
+locale l_heap_is_wellformed = l_type_wf + l_known_ptr + l_heap_is_wellformed_defs
+ + l_get_child_nodes_defs + l_get_disconnected_nodes_defs +
+ assumes heap_is_wellformed_children_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> child \<in> set children
+ \<Longrightarrow> child |\<in>| node_ptr_kinds h"
+ assumes heap_is_wellformed_disc_nodes_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes
+ \<Longrightarrow> node \<in> set disc_nodes \<Longrightarrow> node |\<in>| node_ptr_kinds h"
+ assumes heap_is_wellformed_one_parent:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children'
+ \<Longrightarrow> set children \<inter> set children' \<noteq> {} \<Longrightarrow> ptr = ptr'"
+ assumes heap_is_wellformed_one_disc_parent:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes
+ \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr' \<rightarrow>\<^sub>r disc_nodes'
+ \<Longrightarrow> set disc_nodes \<inter> set disc_nodes' \<noteq> {} \<Longrightarrow> document_ptr = document_ptr'"
+ assumes heap_is_wellformed_children_disc_nodes_different:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes
+ \<Longrightarrow> set children \<inter> set disc_nodes = {}"
+ assumes heap_is_wellformed_disconnected_nodes_distinct:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes
+ \<Longrightarrow> distinct disc_nodes"
+ assumes heap_is_wellformed_children_distinct:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> distinct children"
+ assumes heap_is_wellformed_children_disc_nodes:
+ "heap_is_wellformed h \<Longrightarrow> node_ptr |\<in>| node_ptr_kinds h
+ \<Longrightarrow> \<not>(\<exists>parent \<in> fset (object_ptr_kinds h). node_ptr \<in> set |h \<turnstile> get_child_nodes parent|\<^sub>r)
+ \<Longrightarrow> (\<exists>document_ptr \<in> fset (document_ptr_kinds h). node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)"
+ assumes parent_child_rel_child:
+ "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> child \<in> set children \<longleftrightarrow> (ptr, cast child) \<in> parent_child_rel h"
+ assumes parent_child_rel_finite:
+ "heap_is_wellformed h \<Longrightarrow> finite (parent_child_rel h)"
+ assumes parent_child_rel_acyclic:
+ "heap_is_wellformed h \<Longrightarrow> acyclic (parent_child_rel h)"
+ assumes parent_child_rel_node_ptr:
+ "(parent, child_ptr) \<in> parent_child_rel h \<Longrightarrow> is_node_ptr_kind child_ptr"
+ assumes parent_child_rel_parent_in_heap:
+ "(parent, child_ptr) \<in> parent_child_rel h \<Longrightarrow> parent |\<in>| object_ptr_kinds h"
+ assumes parent_child_rel_child_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptr parent
+ \<Longrightarrow> (parent, child_ptr) \<in> parent_child_rel h \<Longrightarrow> child_ptr |\<in>| object_ptr_kinds h"
+
+interpretation i_heap_is_wellformed?: l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes
+ get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ heap_is_wellformed parent_child_rel
+ apply(unfold_locales)
+ by(auto simp add: heap_is_wellformed_def parent_child_rel_def)
+declare l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+lemma heap_is_wellformed_is_l_heap_is_wellformed [instances]:
+ "l_heap_is_wellformed type_wf known_ptr heap_is_wellformed parent_child_rel get_child_nodes
+ get_disconnected_nodes"
+ apply(auto simp add: l_heap_is_wellformed_def)[1]
+ using heap_is_wellformed_children_in_heap
+ apply blast
+ using heap_is_wellformed_disc_nodes_in_heap
+ apply blast
+ using heap_is_wellformed_one_parent
+ apply blast
+ using heap_is_wellformed_one_disc_parent
+ apply blast
+ using heap_is_wellformed_children_disc_nodes_different
+ apply blast
+ using heap_is_wellformed_disconnected_nodes_distinct
+ apply blast
+ using heap_is_wellformed_children_distinct
+ apply blast
+ using heap_is_wellformed_children_disc_nodes
+ apply blast
+ using parent_child_rel_child
+ apply (blast)
+ using parent_child_rel_child
+ apply(blast)
+ using parent_child_rel_finite
+ apply blast
+ using parent_child_rel_acyclic
+ apply blast
+ using parent_child_rel_node_ptr
+ apply blast
+ using parent_child_rel_parent_in_heap
+ apply blast
+ using parent_child_rel_child_in_heap
+ apply blast
+ done
+
+subsection \<open>get\_parent\<close>
+
+locale l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf get_child_nodes get_child_nodes_locs known_ptrs get_parent get_parent_locs
+ + l_heap_is_wellformed
+ type_wf known_ptr heap_is_wellformed parent_child_rel get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma child_parent_dual:
+ assumes heap_is_wellformed: "heap_is_wellformed h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assumes "child \<in> set children"
+ assumes "known_ptrs h"
+ assumes type_wf: "type_wf h"
+ shows "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some ptr"
+proof -
+ obtain ptrs where ptrs: "h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have h1: "ptr \<in> set ptrs"
+ using get_child_nodes_ok assms(2) is_OK_returns_result_I
+ by (metis (no_types, hide_lams) ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>\<And>thesis. (\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs \<Longrightarrow> thesis) \<Longrightarrow> thesis\<close>
+ get_child_nodes_ptr_in_heap returns_result_eq select_result_I2)
+
+ let ?P = "(\<lambda>ptr. get_child_nodes ptr \<bind> (\<lambda>children. return (child \<in> set children)))"
+ let ?filter = "filter_M ?P ptrs"
+
+ have "h \<turnstile> ok ?filter"
+ using ptrs type_wf
+ using get_child_nodes_ok
+ apply(auto intro!: filter_M_is_OK_I bind_is_OK_pure_I get_child_nodes_ok simp add: bind_pure_I)[1]
+ using assms(4) local.known_ptrs_known_ptr by blast
+ then obtain parent_ptrs where parent_ptrs: "h \<turnstile> ?filter \<rightarrow>\<^sub>r parent_ptrs"
+ by auto
+
+ have h5: "\<exists>!x. x \<in> set ptrs \<and> h \<turnstile> Heap_Error_Monad.bind (get_child_nodes x)
+ (\<lambda>children. return (child \<in> set children)) \<rightarrow>\<^sub>r True"
+ apply(auto intro!: bind_pure_returns_result_I)[1]
+ using heap_is_wellformed_one_parent
+ proof -
+ have "h \<turnstile> (return (child \<in> set children)::((_) heap, exception, bool) prog) \<rightarrow>\<^sub>r True"
+ by (simp add: assms(3))
+ then show
+ "\<exists>z. z \<in> set ptrs \<and> h \<turnstile> Heap_Error_Monad.bind (get_child_nodes z)
+ (\<lambda>ns. return (child \<in> set ns)) \<rightarrow>\<^sub>r True"
+ by (metis (no_types) assms(2) bind_pure_returns_result_I2 h1 is_OK_returns_result_I
+ local.get_child_nodes_pure select_result_I2)
+ next
+ fix x y
+ assume 0: "x \<in> set ptrs"
+ and 1: "h \<turnstile> Heap_Error_Monad.bind (get_child_nodes x)
+ (\<lambda>children. return (child \<in> set children)) \<rightarrow>\<^sub>r True"
+ and 2: "y \<in> set ptrs"
+ and 3: "h \<turnstile> Heap_Error_Monad.bind (get_child_nodes y)
+ (\<lambda>children. return (child \<in> set children)) \<rightarrow>\<^sub>r True"
+ and 4: "(\<And>h ptr children ptr' children'. heap_is_wellformed h
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children'
+ \<Longrightarrow> set children \<inter> set children' \<noteq> {} \<Longrightarrow> ptr = ptr')"
+ then show "x = y"
+ by (metis (no_types, lifting) bind_returns_result_E disjoint_iff_not_equal heap_is_wellformed
+ return_returns_result)
+ qed
+
+ have "child |\<in>| node_ptr_kinds h"
+ using heap_is_wellformed_children_in_heap heap_is_wellformed assms(2) assms(3)
+ by fast
+ moreover have "parent_ptrs = [ptr]"
+ apply(rule filter_M_ex1[OF parent_ptrs h1 h5])
+ using ptrs assms(2) assms(3)
+ by(auto simp add: object_ptr_kinds_M_defs bind_pure_I intro!: bind_pure_returns_result_I)
+ ultimately show ?thesis
+ using ptrs parent_ptrs
+ by(auto simp add: bind_pure_I get_parent_def
+ elim!: bind_returns_result_E2
+ intro!: bind_pure_returns_result_I filter_M_pure_I) (*slow, ca 1min *)
+qed
+
+lemma parent_child_rel_parent:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent"
+ shows "(parent, cast child_node) \<in> parent_child_rel h"
+ using assms parent_child_rel_child get_parent_child_dual by auto
+
+lemma heap_wellformed_induct [consumes 1, case_names step]:
+ assumes "heap_is_wellformed h"
+ and step: "\<And>parent. (\<And>children child. h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children
+ \<Longrightarrow> child \<in> set children \<Longrightarrow> P (cast child)) \<Longrightarrow> P parent"
+ shows "P ptr"
+proof -
+ fix ptr
+ have "wf ((parent_child_rel h)\<inverse>)"
+ by (simp add: assms(1) finite_acyclic_wf_converse parent_child_rel_acyclic parent_child_rel_finite)
+ then show "?thesis"
+ proof (induct rule: wf_induct_rule)
+ case (less parent)
+ then show ?case
+ using assms parent_child_rel_child
+ by (meson converse_iff)
+ qed
+qed
+
+lemma heap_wellformed_induct2 [consumes 3, case_names not_in_heap empty_children step]:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ and not_in_heap: "\<And>parent. parent |\<notin>| object_ptr_kinds h \<Longrightarrow> P parent"
+ and empty_children: "\<And>parent. h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r [] \<Longrightarrow> P parent"
+ and step: "\<And>parent children child. h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children
+ \<Longrightarrow> child \<in> set children \<Longrightarrow> P (cast child) \<Longrightarrow> P parent"
+ shows "P ptr"
+proof(insert assms(1), induct rule: heap_wellformed_induct)
+ case (step parent)
+ then show ?case
+ proof(cases "parent |\<in>| object_ptr_kinds h")
+ case True
+ then obtain children where children: "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children"
+ using get_child_nodes_ok assms(2) assms(3)
+ by (meson is_OK_returns_result_E local.known_ptrs_known_ptr)
+ then show ?thesis
+ proof (cases "children = []")
+ case True
+ then show ?thesis
+ using children empty_children
+ by simp
+ next
+ case False
+ then show ?thesis
+ using assms(6) children last_in_set step.hyps by blast
+ qed
+ next
+ case False
+ then show ?thesis
+ by (simp add: not_in_heap)
+ qed
+qed
+
+lemma heap_wellformed_induct_rev [consumes 1, case_names step]:
+ assumes "heap_is_wellformed h"
+ and step: "\<And>child. (\<And>parent child_node. cast child_node = child
+ \<Longrightarrow> h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent \<Longrightarrow> P parent) \<Longrightarrow> P child"
+ shows "P ptr"
+proof -
+ fix ptr
+ have "wf ((parent_child_rel h))"
+ by (simp add: assms(1) local.parent_child_rel_acyclic local.parent_child_rel_finite
+ wf_iff_acyclic_if_finite)
+
+ then show "?thesis"
+ proof (induct rule: wf_induct_rule)
+ case (less child)
+ show ?case
+ using assms get_parent_child_dual
+ by (metis less.hyps parent_child_rel_parent)
+ qed
+qed
+end
+
+interpretation i_get_parent_wf?: l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes
+ get_child_nodes_locs known_ptrs get_parent get_parent_locs heap_is_wellformed
+ parent_child_rel get_disconnected_nodes
+ using instances
+ by(simp add: l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+locale l_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf get_child_nodes get_child_nodes_locs known_ptrs get_parent get_parent_locs
+ heap_is_wellformed parent_child_rel get_disconnected_nodes get_disconnected_nodes_locs
+ + l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs heap_is_wellformed parent_child_rel
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma preserves_wellformedness_writes_needed:
+ assumes heap_is_wellformed: "heap_is_wellformed h"
+ and "h \<turnstile> f \<rightarrow>\<^sub>h h'"
+ and "writes SW f h h'"
+ and preserved_get_child_nodes:
+ "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>object_ptr. \<forall>r \<in> get_child_nodes_locs object_ptr. r h h'"
+ and preserved_get_disconnected_nodes:
+ "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>document_ptr. \<forall>r \<in> get_disconnected_nodes_locs document_ptr. r h h'"
+ and preserved_object_pointers:
+ "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> \<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ shows "heap_is_wellformed h'"
+proof -
+ have object_ptr_kinds_eq3: "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms(2) assms(3) object_ptr_kinds_preserved preserved_object_pointers by blast
+ then have object_ptr_kinds_eq:
+ "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ unfolding object_ptr_kinds_M_defs by simp
+ then have object_ptr_kinds_eq2: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ using select_result_eq by force
+ then have node_ptr_kinds_eq2: "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by auto
+ then have node_ptr_kinds_eq3: "node_ptr_kinds h = node_ptr_kinds h'"
+ by auto
+ have document_ptr_kinds_eq2: "|h \<turnstile> document_ptr_kinds_M|\<^sub>r = |h' \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq2 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3: "document_ptr_kinds h = document_ptr_kinds h'"
+ by auto
+ have children_eq:
+ "\<And>ptr children. h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ apply(rule reads_writes_preserved[OF get_child_nodes_reads assms(3) assms(2)])
+ using preserved_get_child_nodes by fast
+ then have children_eq2: "\<And>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r = |h' \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq:
+ "\<And>document_ptr disconnected_nodes.
+ h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disconnected_nodes
+ = h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disconnected_nodes"
+ apply(rule reads_writes_preserved[OF get_disconnected_nodes_reads assms(3) assms(2)])
+ using preserved_get_disconnected_nodes by fast
+ then have disconnected_nodes_eq2:
+ "\<And>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r
+ = |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ using select_result_eq by force
+ have get_parent_eq: "\<And>ptr parent. h \<turnstile> get_parent ptr \<rightarrow>\<^sub>r parent = h' \<turnstile> get_parent ptr \<rightarrow>\<^sub>r parent"
+ apply(rule reads_writes_preserved[OF get_parent_reads assms(3) assms(2)])
+ using preserved_get_child_nodes preserved_object_pointers unfolding get_parent_locs_def by fast
+ have "a_acyclic_heap h"
+ using heap_is_wellformed by (simp add: heap_is_wellformed_def)
+ have "parent_child_rel h' \<subseteq> parent_child_rel h"
+ proof
+ fix x
+ assume "x \<in> parent_child_rel h'"
+ then show "x \<in> parent_child_rel h"
+ by(simp add: parent_child_rel_def children_eq2 object_ptr_kinds_eq3)
+ qed
+ then have "a_acyclic_heap h'"
+ using \<open>a_acyclic_heap h\<close> acyclic_heap_def acyclic_subset by blast
+
+ moreover have "a_all_ptrs_in_heap h"
+ using heap_is_wellformed by (simp add: heap_is_wellformed_def)
+ then have "a_all_ptrs_in_heap h'"
+ by (simp add: children_eq2 disconnected_nodes_eq2 document_ptr_kinds_eq3
+ l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_all_ptrs_in_heap_def node_ptr_kinds_eq3 object_ptr_kinds_eq3)
+
+ moreover have h0: "a_distinct_lists h"
+ using heap_is_wellformed by (simp add: heap_is_wellformed_def)
+ have h1: "map (\<lambda>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r) (sorted_list_of_set (fset (object_ptr_kinds h)))
+ = map (\<lambda>ptr. |h' \<turnstile> get_child_nodes ptr|\<^sub>r) (sorted_list_of_set (fset (object_ptr_kinds h')))"
+ by (simp add: children_eq2 object_ptr_kinds_eq3)
+ have h2: "map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h)))
+ = map (\<lambda>document_ptr. |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ using disconnected_nodes_eq document_ptr_kinds_eq2 select_result_eq by force
+ have "a_distinct_lists h'"
+ using h0
+ by(simp add: a_distinct_lists_def h1 h2)
+
+ moreover have "a_owner_document_valid h"
+ using heap_is_wellformed by (simp add: heap_is_wellformed_def)
+ then have "a_owner_document_valid h'"
+ by(auto simp add: a_owner_document_valid_def children_eq2 disconnected_nodes_eq2
+ object_ptr_kinds_eq3 node_ptr_kinds_eq3 document_ptr_kinds_eq3)
+ ultimately show ?thesis
+ by (simp add: heap_is_wellformed_def)
+qed
+end
+
+interpretation i_get_parent_wf2?: l_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes
+ get_child_nodes_locs known_ptrs get_parent get_parent_locs
+ heap_is_wellformed parent_child_rel get_disconnected_nodes
+ get_disconnected_nodes_locs
+ using l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms
+ by (simp add: l_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+
+declare l_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+locale l_get_parent_wf = l_type_wf + l_known_ptrs + l_heap_is_wellformed_defs
+ + l_get_child_nodes_defs + l_get_parent_defs +
+ assumes child_parent_dual:
+ "heap_is_wellformed h
+ \<Longrightarrow> type_wf h
+ \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> child \<in> set children
+ \<Longrightarrow> h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some ptr"
+ assumes heap_wellformed_induct [consumes 1, case_names step]:
+ "heap_is_wellformed h
+ \<Longrightarrow> (\<And>parent. (\<And>children child. h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children
+ \<Longrightarrow> child \<in> set children \<Longrightarrow> P (cast child)) \<Longrightarrow> P parent)
+ \<Longrightarrow> P ptr"
+ assumes heap_wellformed_induct_rev [consumes 1, case_names step]:
+ "heap_is_wellformed h
+ \<Longrightarrow> (\<And>child. (\<And>parent child_node. cast child_node = child
+ \<Longrightarrow> h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent \<Longrightarrow> P parent) \<Longrightarrow> P child)
+ \<Longrightarrow> P ptr"
+ assumes parent_child_rel_parent: "heap_is_wellformed h
+ \<Longrightarrow> h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent
+ \<Longrightarrow> (parent, cast child_node) \<in> parent_child_rel h"
+
+lemma get_parent_wf_is_l_get_parent_wf [instances]:
+ "l_get_parent_wf type_wf known_ptr known_ptrs heap_is_wellformed parent_child_rel
+ get_child_nodes get_parent"
+ using known_ptrs_is_l_known_ptrs
+ apply(auto simp add: l_get_parent_wf_def l_get_parent_wf_axioms_def)[1]
+ using child_parent_dual heap_wellformed_induct heap_wellformed_induct_rev parent_child_rel_parent
+ by metis+
+
+
+
+subsection \<open>get\_disconnected\_nodes\<close>
+
+
+
+subsection \<open>set\_disconnected\_nodes\<close>
+
+
+subsubsection \<open>get\_disconnected\_nodes\<close>
+
+locale l_set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes_get_disconnected_nodes
+ type_wf get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs
+ + l_heap_is_wellformed
+ type_wf known_ptr heap_is_wellformed parent_child_rel get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs
+ for known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+
+lemma remove_from_disconnected_nodes_removes:
+ assumes "heap_is_wellformed h"
+ assumes "h \<turnstile> get_disconnected_nodes ptr \<rightarrow>\<^sub>r disc_nodes"
+ assumes "h \<turnstile> set_disconnected_nodes ptr (remove1 node_ptr disc_nodes) \<rightarrow>\<^sub>h h'"
+ assumes "h' \<turnstile> get_disconnected_nodes ptr \<rightarrow>\<^sub>r disc_nodes'"
+ shows "node_ptr \<notin> set disc_nodes'"
+ using assms
+ by (metis distinct_remove1_removeAll heap_is_wellformed_disconnected_nodes_distinct
+ set_disconnected_nodes_get_disconnected_nodes member_remove remove_code(1)
+ returns_result_eq)
+end
+
+locale l_set_disconnected_nodes_get_disconnected_nodes_wf = l_heap_is_wellformed
+ + l_set_disconnected_nodes_get_disconnected_nodes +
+ assumes remove_from_disconnected_nodes_removes:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_disconnected_nodes ptr \<rightarrow>\<^sub>r disc_nodes
+ \<Longrightarrow> h \<turnstile> set_disconnected_nodes ptr (remove1 node_ptr disc_nodes) \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_disconnected_nodes ptr \<rightarrow>\<^sub>r disc_nodes'
+ \<Longrightarrow> node_ptr \<notin> set disc_nodes'"
+
+interpretation i_set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M?:
+ l_set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs heap_is_wellformed
+ parent_child_rel get_child_nodes
+ using instances
+ by (simp add: l_set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_disconnected_nodes_get_disconnected_nodes_wf_is_l_set_disconnected_nodes_get_disconnected_nodes_wf [instances]:
+ "l_set_disconnected_nodes_get_disconnected_nodes_wf type_wf known_ptr heap_is_wellformed parent_child_rel
+ get_child_nodes get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs"
+ apply(auto simp add: l_set_disconnected_nodes_get_disconnected_nodes_wf_def
+ l_set_disconnected_nodes_get_disconnected_nodes_wf_axioms_def instances)[1]
+ using remove_from_disconnected_nodes_removes apply fast
+ done
+
+
+subsection \<open>get\_root\_node\<close>
+
+locale l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_heap_is_wellformed
+ type_wf known_ptr heap_is_wellformed parent_child_rel get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs
+ + l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf get_child_nodes get_child_nodes_locs known_ptrs get_parent get_parent_locs
+ + l_get_parent_wf
+ type_wf known_ptr known_ptrs heap_is_wellformed parent_child_rel get_child_nodes
+ get_child_nodes_locs get_parent get_parent_locs
+ + l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_ancestors get_ancestors_locs get_root_node get_root_node_locs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_ancestors :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_ancestors_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_root_node :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+begin
+lemma get_ancestors_reads:
+ assumes "heap_is_wellformed h"
+ shows "reads get_ancestors_locs (get_ancestors node_ptr) h h'"
+proof (insert assms(1), induct rule: heap_wellformed_induct_rev)
+ case (step child)
+ then show ?case
+ using [[simproc del: Product_Type.unit_eq]] get_parent_reads[unfolded reads_def]
+ apply(simp (no_asm) add: get_ancestors_def)
+ by(auto simp add: get_ancestors_locs_def reads_subset[OF return_reads] get_parent_reads_pointers
+ intro!: reads_bind_pure reads_subset[OF check_in_heap_reads]
+ reads_subset[OF get_parent_reads] reads_subset[OF get_child_nodes_reads]
+ split: option.splits)
+qed
+
+lemma get_ancestors_ok:
+ assumes "heap_is_wellformed h"
+ and "ptr |\<in>| object_ptr_kinds h"
+ and "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "h \<turnstile> ok (get_ancestors ptr)"
+proof (insert assms(1) assms(2), induct rule: heap_wellformed_induct_rev)
+ case (step child)
+ then show ?case
+ using assms(3) assms(4)
+ apply(simp (no_asm) add: get_ancestors_def)
+ apply(simp add: assms(1) get_parent_parent_in_heap)
+ by(auto intro!: bind_is_OK_pure_I bind_pure_I get_parent_ok split: option.splits)
+qed
+
+lemma get_root_node_ptr_in_heap:
+ assumes "h \<turnstile> ok (get_root_node ptr)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ unfolding get_root_node_def
+ using get_ancestors_ptr_in_heap
+ by auto
+
+
+lemma get_root_node_ok:
+ assumes "heap_is_wellformed h" "known_ptrs h" "type_wf h"
+ and "ptr |\<in>| object_ptr_kinds h"
+ shows "h \<turnstile> ok (get_root_node ptr)"
+ unfolding get_root_node_def
+ using assms get_ancestors_ok
+ by auto
+
+
+lemma get_ancestors_parent:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some parent"
+ shows "h \<turnstile> get_ancestors (cast child) \<rightarrow>\<^sub>r (cast child) # parent # ancestors
+ \<longleftrightarrow> h \<turnstile> get_ancestors parent \<rightarrow>\<^sub>r parent # ancestors"
+proof
+ assume a1: "h \<turnstile> get_ancestors (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child # parent # ancestors"
+ then have "h \<turnstile> Heap_Error_Monad.bind (check_in_heap (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child))
+ (\<lambda>_. Heap_Error_Monad.bind (get_parent child)
+ (\<lambda>x. Heap_Error_Monad.bind (case x of None \<Rightarrow> return [] | Some x \<Rightarrow> get_ancestors x)
+ (\<lambda>ancestors. return (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child # ancestors))))
+ \<rightarrow>\<^sub>r cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child # parent # ancestors"
+ by(simp add: get_ancestors_def)
+ then show "h \<turnstile> get_ancestors parent \<rightarrow>\<^sub>r parent # ancestors"
+ using assms(2) apply(auto elim!: bind_returns_result_E2 split: option.splits)[1]
+ using returns_result_eq by fastforce
+next
+ assume "h \<turnstile> get_ancestors parent \<rightarrow>\<^sub>r parent # ancestors"
+ then show "h \<turnstile> get_ancestors (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child # parent # ancestors"
+ using assms(2)
+ apply(simp (no_asm) add: get_ancestors_def)
+ apply(auto intro!: bind_pure_returns_result_I split: option.splits)[1]
+ by (metis (full_types) assms(2) check_in_heap_ptr_in_heap is_OK_returns_result_I
+ local.get_parent_ptr_in_heap node_ptr_kinds_commutes old.unit.exhaust
+ select_result_I)
+qed
+
+
+lemma get_ancestors_never_empty:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_ancestors child \<rightarrow>\<^sub>r ancestors"
+ shows "ancestors \<noteq> []"
+proof(insert assms(2), induct arbitrary: ancestors rule: heap_wellformed_induct_rev[OF assms(1)])
+ case (1 child)
+ then show ?case
+ proof (induct "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child")
+ case None
+ then show ?case
+ apply(simp add: get_ancestors_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits)
+ next
+ case (Some child_node)
+ then obtain parent_opt where parent_opt: "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r parent_opt"
+ apply(simp add: get_ancestors_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits)
+ with Some show ?case
+ proof(induct parent_opt)
+ case None
+ then show ?case
+ apply(simp add: get_ancestors_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits)
+ next
+ case (Some option)
+ then show ?case
+ apply(simp add: get_ancestors_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits)
+ qed
+ qed
+qed
+
+
+
+lemma get_ancestors_subset:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors"
+ and "ancestor \<in> set ancestors"
+ and "h \<turnstile> get_ancestors ancestor \<rightarrow>\<^sub>r ancestor_ancestors"
+ and type_wf: "type_wf h"
+ and known_ptrs: "known_ptrs h"
+ shows "set ancestor_ancestors \<subseteq> set ancestors"
+proof (insert assms(1) assms(2) assms(3), induct ptr arbitrary: ancestors
+ rule: heap_wellformed_induct_rev)
+ case (step child)
+ have "child |\<in>| object_ptr_kinds h"
+ using get_ancestors_ptr_in_heap step(2) by auto
+ (* then have "h \<turnstile> check_in_heap child \<rightarrow>\<^sub>r ()"
+ using returns_result_select_result by force *)
+ show ?case
+ proof (induct "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child")
+ case None
+ then have "ancestors = [child]"
+ using step(2) step(3)
+ by(auto simp add: get_ancestors_def elim!: bind_returns_result_E2)
+ show ?case
+ using step(2) step(3)
+ apply(auto simp add: \<open>ancestors = [child]\<close>)[1]
+ using assms(4) returns_result_eq by fastforce
+ next
+ case (Some child_node)
+ note s1 = Some
+ obtain parent_opt where parent_opt: "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r parent_opt"
+ using \<open>child |\<in>| object_ptr_kinds h\<close> assms(1) Some[symmetric] get_parent_ok[OF type_wf known_ptrs]
+ by (metis (no_types, lifting) is_OK_returns_result_E known_ptrs get_parent_ok
+ l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms node_ptr_casts_commute node_ptr_kinds_commutes)
+ then show ?case
+ proof (induct parent_opt)
+ case None
+ then have "ancestors = [child]"
+ using step(2) step(3) s1
+ apply(simp add: get_ancestors_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits dest: returns_result_eq)
+ show ?case
+ using step(2) step(3)
+ apply(auto simp add: \<open>ancestors = [child]\<close>)[1]
+ using assms(4) returns_result_eq by fastforce
+ next
+ case (Some parent)
+ have "h \<turnstile> Heap_Error_Monad.bind (check_in_heap child)
+ (\<lambda>_. Heap_Error_Monad.bind
+ (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child of None \<Rightarrow> return []
+ | Some node_ptr \<Rightarrow> Heap_Error_Monad.bind (get_parent node_ptr)
+ (\<lambda>parent_ptr_opt. case parent_ptr_opt of None \<Rightarrow> return []
+ | Some x \<Rightarrow> get_ancestors x))
+ (\<lambda>ancestors. return (child # ancestors)))
+ \<rightarrow>\<^sub>r ancestors"
+ using step(2)
+ by(simp add: get_ancestors_def)
+ moreover obtain tl_ancestors where tl_ancestors: "ancestors = child # tl_ancestors"
+ using calculation
+ by(auto elim!: bind_returns_result_E2 split: option.splits)
+ ultimately have "h \<turnstile> get_ancestors parent \<rightarrow>\<^sub>r tl_ancestors"
+ using s1 Some
+ by(auto elim!: bind_returns_result_E2 split: option.splits dest: returns_result_eq)
+ show ?case
+ using step(1)[OF s1[symmetric, simplified] Some \<open>h \<turnstile> get_ancestors parent \<rightarrow>\<^sub>r tl_ancestors\<close>]
+ step(3)
+ apply(auto simp add: tl_ancestors)[1]
+ by (metis assms(4) insert_iff list.simps(15) local.step(2) returns_result_eq tl_ancestors)
+ qed
+ qed
+qed
+
+lemma get_ancestors_also_parent:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_ancestors some_ptr \<rightarrow>\<^sub>r ancestors"
+ and "cast child \<in> set ancestors"
+ and "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some parent"
+ and type_wf: "type_wf h"
+ and known_ptrs: "known_ptrs h"
+ shows "parent \<in> set ancestors"
+proof -
+ obtain child_ancestors where child_ancestors: "h \<turnstile> get_ancestors (cast child) \<rightarrow>\<^sub>r child_ancestors"
+ by (meson assms(1) assms(4) get_ancestors_ok is_OK_returns_result_I known_ptrs
+ local.get_parent_ptr_in_heap node_ptr_kinds_commutes returns_result_select_result
+ type_wf)
+ then have "parent \<in> set child_ancestors"
+ apply(simp add: get_ancestors_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits dest!: returns_result_eq[OF assms(4)]
+ get_ancestors_ptr)
+ then show ?thesis
+ using assms child_ancestors get_ancestors_subset by blast
+qed
+
+lemma get_ancestors_obtains_children:
+ assumes "heap_is_wellformed h"
+ and "ancestor \<noteq> ptr"
+ and "ancestor \<in> set ancestors"
+ and "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors"
+ and type_wf: "type_wf h"
+ and known_ptrs: "known_ptrs h"
+ obtains children ancestor_child where "h \<turnstile> get_child_nodes ancestor \<rightarrow>\<^sub>r children"
+ and "ancestor_child \<in> set children" and "cast ancestor_child \<in> set ancestors"
+proof -
+ assume 0: "(\<And>children ancestor_child.
+ h \<turnstile> get_child_nodes ancestor \<rightarrow>\<^sub>r children \<Longrightarrow>
+ ancestor_child \<in> set children \<Longrightarrow> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_child \<in> set ancestors
+ \<Longrightarrow> thesis)"
+ have "\<exists>child. h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some ancestor \<and> cast child \<in> set ancestors"
+ proof (insert assms(1) assms(2) assms(3) assms(4), induct ptr arbitrary: ancestors
+ rule: heap_wellformed_induct_rev)
+ case (step child)
+ have "child |\<in>| object_ptr_kinds h"
+ using get_ancestors_ptr_in_heap step(4) by auto
+ show ?case
+ proof (induct "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child")
+ case None
+ then have "ancestors = [child]"
+ using step(3) step(4)
+ by(auto simp add: get_ancestors_def elim!: bind_returns_result_E2)
+ show ?case
+ using step(2) step(3) step(4)
+ by(auto simp add: \<open>ancestors = [child]\<close>)
+ next
+ case (Some child_node)
+ note s1 = Some
+ obtain parent_opt where parent_opt: "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r parent_opt"
+ using \<open>child |\<in>| object_ptr_kinds h\<close> assms(1) Some[symmetric]
+ using get_parent_ok known_ptrs type_wf
+ by (metis (no_types, lifting) is_OK_returns_result_E node_ptr_casts_commute
+ node_ptr_kinds_commutes)
+ then show ?case
+ proof (induct parent_opt)
+ case None
+ then have "ancestors = [child]"
+ using step(2) step(3) step(4) s1
+ apply(simp add: get_ancestors_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits dest: returns_result_eq)
+ show ?case
+ using step(2) step(3) step(4)
+ by(auto simp add: \<open>ancestors = [child]\<close>)
+ next
+ case (Some parent)
+ have "h \<turnstile> Heap_Error_Monad.bind (check_in_heap child)
+ (\<lambda>_. Heap_Error_Monad.bind
+ (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child of None \<Rightarrow> return []
+ | Some node_ptr \<Rightarrow> Heap_Error_Monad.bind (get_parent node_ptr)
+ (\<lambda>parent_ptr_opt. case parent_ptr_opt of None \<Rightarrow> return []
+ | Some x \<Rightarrow> get_ancestors x))
+ (\<lambda>ancestors. return (child # ancestors)))
+ \<rightarrow>\<^sub>r ancestors"
+ using step(4)
+ by(simp add: get_ancestors_def)
+ moreover obtain tl_ancestors where tl_ancestors: "ancestors = child # tl_ancestors"
+ using calculation
+ by(auto elim!: bind_returns_result_E2 split: option.splits)
+ ultimately have "h \<turnstile> get_ancestors parent \<rightarrow>\<^sub>r tl_ancestors"
+ using s1 Some
+ by(auto elim!: bind_returns_result_E2 split: option.splits dest: returns_result_eq)
+ (* have "ancestor \<noteq> parent" *)
+ have "ancestor \<in> set tl_ancestors"
+ using tl_ancestors step(2) step(3) by auto
+ show ?case
+ proof (cases "ancestor \<noteq> parent")
+ case True
+ show ?thesis
+ using step(1)[OF s1[symmetric, simplified] Some True
+ \<open>ancestor \<in> set tl_ancestors\<close> \<open>h \<turnstile> get_ancestors parent \<rightarrow>\<^sub>r tl_ancestors\<close>]
+ using tl_ancestors by auto
+ next
+ case False
+ have "child \<in> set ancestors"
+ using step(4) get_ancestors_ptr by simp
+ then show ?thesis
+ using Some False s1[symmetric] by(auto)
+ qed
+ qed
+ qed
+ qed
+ then obtain child where child: "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some ancestor"
+ and in_ancestors: "cast child \<in> set ancestors"
+ by auto
+ then obtain children where
+ children: "h \<turnstile> get_child_nodes ancestor \<rightarrow>\<^sub>r children" and
+ child_in_children: "child \<in> set children"
+ using get_parent_child_dual by blast
+ show thesis
+ using 0[OF children child_in_children] child assms(3) in_ancestors by blast
+qed
+
+lemma get_ancestors_parent_child_rel:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_ancestors child \<rightarrow>\<^sub>r ancestors"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "(ptr, child) \<in> (parent_child_rel h)\<^sup>* \<longleftrightarrow> ptr \<in> set ancestors"
+proof (safe)
+ assume 3: "(ptr, child) \<in> (parent_child_rel h)\<^sup>*"
+ show "ptr \<in> set ancestors"
+ proof (insert 3, induct ptr rule: heap_wellformed_induct[OF assms(1)])
+ case (1 ptr)
+ then show ?case
+ proof (cases "ptr = child")
+ case True
+ then show ?thesis
+ by (metis (no_types, lifting) assms(2) bind_returns_result_E get_ancestors_def
+ in_set_member member_rec(1) return_returns_result)
+ next
+ case False
+ obtain ptr_child where
+ ptr_child: "(ptr, ptr_child) \<in> (parent_child_rel h) \<and> (ptr_child, child) \<in> (parent_child_rel h)\<^sup>*"
+ using converse_rtranclE[OF 1(2)] \<open>ptr \<noteq> child\<close>
+ by metis
+ then obtain ptr_child_node
+ where ptr_child_ptr_child_node: "ptr_child = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr_child_node"
+ using ptr_child node_ptr_casts_commute3 parent_child_rel_node_ptr
+ by (metis )
+ then obtain children where
+ children: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children" and
+ ptr_child_node: "ptr_child_node \<in> set children"
+ proof -
+ assume a1: "\<And>children. \<lbrakk>h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children; ptr_child_node \<in> set children\<rbrakk>
+ \<Longrightarrow> thesis"
+
+ have "ptr |\<in>| object_ptr_kinds h"
+ using local.parent_child_rel_parent_in_heap ptr_child by blast
+ moreover have "ptr_child_node \<in> set |h \<turnstile> get_child_nodes ptr|\<^sub>r"
+ by (metis calculation known_ptrs local.get_child_nodes_ok local.known_ptrs_known_ptr
+ local.parent_child_rel_child ptr_child ptr_child_ptr_child_node
+ returns_result_select_result type_wf)
+ ultimately show ?thesis
+ using a1 get_child_nodes_ok type_wf known_ptrs
+ by (meson local.known_ptrs_known_ptr returns_result_select_result)
+ qed
+ moreover have "(cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr_child_node, child) \<in> (parent_child_rel h)\<^sup>*"
+ using ptr_child ptr_child_ptr_child_node by auto
+ ultimately have "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr_child_node \<in> set ancestors"
+ using 1 by auto
+ moreover have "h \<turnstile> get_parent ptr_child_node \<rightarrow>\<^sub>r Some ptr"
+ using assms(1) children ptr_child_node child_parent_dual
+ using known_ptrs type_wf by blast
+ ultimately show ?thesis
+ using get_ancestors_also_parent assms type_wf by blast
+ qed
+ qed
+next
+ assume 3: "ptr \<in> set ancestors"
+ show "(ptr, child) \<in> (parent_child_rel h)\<^sup>*"
+ proof (insert 3, induct ptr rule: heap_wellformed_induct[OF assms(1)])
+ case (1 ptr)
+ then show ?case
+ proof (cases "ptr = child")
+ case True
+ then show ?thesis
+ by simp
+ next
+ case False
+ then obtain children ptr_child_node where
+ children: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children" and
+ ptr_child_node: "ptr_child_node \<in> set children" and
+ ptr_child_node_in_ancestors: "cast ptr_child_node \<in> set ancestors"
+ using 1(2) assms(2) get_ancestors_obtains_children assms(1)
+ using known_ptrs type_wf by blast
+ then have "(cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr_child_node, child) \<in> (parent_child_rel h)\<^sup>*"
+ using 1(1) by blast
+
+ moreover have "(ptr, cast ptr_child_node) \<in> parent_child_rel h"
+ using children ptr_child_node assms(1) parent_child_rel_child_nodes2
+ using child_parent_dual known_ptrs parent_child_rel_parent type_wf
+ by blast
+
+ ultimately show ?thesis
+ by auto
+ qed
+ qed
+qed
+
+lemma get_root_node_parent_child_rel:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_root_node child \<rightarrow>\<^sub>r root"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "(root, child) \<in> (parent_child_rel h)\<^sup>*"
+ using assms get_ancestors_parent_child_rel
+ apply(auto simp add: get_root_node_def elim!: bind_returns_result_E2)[1]
+ using get_ancestors_never_empty last_in_set by blast
+
+
+lemma get_ancestors_eq:
+ assumes "heap_is_wellformed h"
+ and "heap_is_wellformed h'"
+ and "\<And>object_ptr w. object_ptr \<noteq> ptr \<Longrightarrow> w \<in> get_child_nodes_locs object_ptr \<Longrightarrow> w h h'"
+ and pointers_preserved: "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ and known_ptrs: "known_ptrs h"
+ and known_ptrs': "known_ptrs h'"
+ and "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors"
+ and type_wf: "type_wf h"
+ and type_wf': "type_wf h'"
+ shows "h' \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors"
+proof -
+ have object_ptr_kinds_eq3: "object_ptr_kinds h = object_ptr_kinds h'"
+ using pointers_preserved object_ptr_kinds_preserved_small by blast
+ then have object_ptr_kinds_M_eq:
+ "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+ have "h' \<turnstile> ok (get_ancestors ptr)"
+ using get_ancestors_ok get_ancestors_ptr_in_heap object_ptr_kinds_eq3 assms(1) known_ptrs
+ known_ptrs' assms(2) assms(7) type_wf'
+ by blast
+ then obtain ancestors' where ancestors': "h' \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors'"
+ by auto
+
+ obtain root where root: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ proof -
+ assume 0: "(\<And>root. h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root \<Longrightarrow> thesis)"
+ show thesis
+ apply(rule 0)
+ using assms(7)
+ by(auto simp add: get_root_node_def elim!: bind_returns_result_E2 split: option.splits)
+ qed
+
+ have children_eq:
+ "\<And>p children. p \<noteq> ptr \<Longrightarrow> h \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads assms(3)
+ apply(simp add: reads_def reflp_def transp_def preserved_def)
+ by blast
+
+ have "acyclic (parent_child_rel h)"
+ using assms(1) local.parent_child_rel_acyclic by auto
+ have "acyclic (parent_child_rel h')"
+ using assms(2) local.parent_child_rel_acyclic by blast
+ have 2: "\<And>c parent_opt. cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c \<in> set ancestors \<inter> set ancestors'
+ \<Longrightarrow> h \<turnstile> get_parent c \<rightarrow>\<^sub>r parent_opt = h' \<turnstile> get_parent c \<rightarrow>\<^sub>r parent_opt"
+ proof -
+ fix c parent_opt
+ assume 1: " cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c \<in> set ancestors \<inter> set ancestors'"
+
+ obtain ptrs where ptrs: "h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by simp
+
+ let ?P = "(\<lambda>ptr. Heap_Error_Monad.bind (get_child_nodes ptr) (\<lambda>children. return (c \<in> set children)))"
+ have children_eq_True: "\<And>p. p \<in> set ptrs \<Longrightarrow> h \<turnstile> ?P p \<rightarrow>\<^sub>r True \<longleftrightarrow> h' \<turnstile> ?P p \<rightarrow>\<^sub>r True"
+ proof -
+ fix p
+ assume "p \<in> set ptrs"
+ then show "h \<turnstile> ?P p \<rightarrow>\<^sub>r True \<longleftrightarrow> h' \<turnstile> ?P p \<rightarrow>\<^sub>r True"
+ proof (cases "p = ptr")
+ case True
+ have "(cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c, ptr) \<in> (parent_child_rel h)\<^sup>*"
+ using get_ancestors_parent_child_rel 1 assms by blast
+ then have "(ptr, cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c) \<notin> (parent_child_rel h)"
+ proof (cases "cast c = ptr")
+ case True
+ then show ?thesis
+ using \<open>acyclic (parent_child_rel h)\<close> by(auto simp add: acyclic_def)
+ next
+ case False
+ then have "(ptr, cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c) \<notin> (parent_child_rel h)\<^sup>*"
+ using \<open>acyclic (parent_child_rel h)\<close> False rtrancl_eq_or_trancl rtrancl_trancl_trancl
+ \<open>(cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c, ptr) \<in> (parent_child_rel h)\<^sup>*\<close>
+ by (metis acyclic_def)
+ then show ?thesis
+ using r_into_rtrancl by auto
+ qed
+ obtain children where children: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using type_wf
+ by (metis \<open>h' \<turnstile> ok get_ancestors ptr\<close> assms(1) get_ancestors_ptr_in_heap get_child_nodes_ok
+ heap_is_wellformed_def is_OK_returns_result_E known_ptrs local.known_ptrs_known_ptr
+ object_ptr_kinds_eq3)
+ then have "c \<notin> set children"
+ using \<open>(ptr, cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c) \<notin> (parent_child_rel h)\<close> assms(1)
+ using parent_child_rel_child_nodes2
+ using child_parent_dual known_ptrs parent_child_rel_parent
+ type_wf by blast
+ with children have "h \<turnstile> ?P p \<rightarrow>\<^sub>r False"
+ by(auto simp add: True)
+
+ moreover have "(cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c, ptr) \<in> (parent_child_rel h')\<^sup>*"
+ using get_ancestors_parent_child_rel assms(2) ancestors' 1 known_ptrs' type_wf
+ type_wf' by blast
+ then have "(ptr, cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c) \<notin> (parent_child_rel h')"
+ proof (cases "cast c = ptr")
+ case True
+ then show ?thesis
+ using \<open>acyclic (parent_child_rel h')\<close> by(auto simp add: acyclic_def)
+ next
+ case False
+ then have "(ptr, cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c) \<notin> (parent_child_rel h')\<^sup>*"
+ using \<open>acyclic (parent_child_rel h')\<close> False rtrancl_eq_or_trancl rtrancl_trancl_trancl
+ \<open>(cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c, ptr) \<in> (parent_child_rel h')\<^sup>*\<close>
+ by (metis acyclic_def)
+ then show ?thesis
+ using r_into_rtrancl by auto
+ qed
+ then have "(ptr, cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c) \<notin> (parent_child_rel h')"
+ using r_into_rtrancl by auto
+ obtain children' where children': "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'"
+ using type_wf type_wf'
+ by (meson \<open>h' \<turnstile> ok (get_ancestors ptr)\<close> assms(2) get_ancestors_ptr_in_heap
+ get_child_nodes_ok is_OK_returns_result_E known_ptrs'
+ local.known_ptrs_known_ptr)
+ then have "c \<notin> set children'"
+ using \<open>(ptr, cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c) \<notin> (parent_child_rel h')\<close> assms(2) type_wf type_wf'
+ using parent_child_rel_child_nodes2 child_parent_dual known_ptrs' parent_child_rel_parent
+ by auto
+ with children' have "h' \<turnstile> ?P p \<rightarrow>\<^sub>r False"
+ by(auto simp add: True)
+
+ ultimately show ?thesis
+ by (metis returns_result_eq)
+ next
+ case False
+ then show ?thesis
+ using children_eq ptrs
+ by (metis (no_types, lifting) bind_pure_returns_result_I bind_returns_result_E
+ get_child_nodes_pure return_returns_result)
+ qed
+ qed
+ have "\<And>pa. pa \<in> set ptrs \<Longrightarrow> h \<turnstile> ok (get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children))) = h' \<turnstile> ok ( get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children)))"
+ using assms(1) assms(2) object_ptr_kinds_eq ptrs type_wf type_wf'
+ by (metis (no_types, lifting) ObjectMonad.ptr_kinds_ptr_kinds_M bind_is_OK_pure_I
+ get_child_nodes_ok get_child_nodes_pure known_ptrs'
+ local.known_ptrs_known_ptr return_ok select_result_I2)
+ have children_eq_False:
+ "\<And>pa. pa \<in> set ptrs \<Longrightarrow> h \<turnstile> get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False = h' \<turnstile> get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False"
+ proof
+ fix pa
+ assume "pa \<in> set ptrs"
+ and "h \<turnstile> get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False"
+ have "h \<turnstile> ok (get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)))
+ \<Longrightarrow> h' \<turnstile> ok ( get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)))"
+ using \<open>pa \<in> set ptrs\<close> \<open>\<And>pa. pa \<in> set ptrs \<Longrightarrow> h \<turnstile> ok (get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children))) = h' \<turnstile> ok ( get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children)))\<close>
+ by auto
+ moreover have "h \<turnstile> get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False
+ \<Longrightarrow> h' \<turnstile> get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False"
+ by (metis (mono_tags, lifting) \<open>\<And>pa. pa \<in> set ptrs
+ \<Longrightarrow> h \<turnstile> get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r True = h' \<turnstile> get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r True\<close> \<open>pa \<in> set ptrs\<close>
+ calculation is_OK_returns_result_I returns_result_eq returns_result_select_result)
+ ultimately show "h' \<turnstile> get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False"
+ using \<open>h \<turnstile> get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False\<close>
+ by auto
+ next
+ fix pa
+ assume "pa \<in> set ptrs"
+ and "h' \<turnstile> get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False"
+ have "h' \<turnstile> ok (get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)))
+ \<Longrightarrow> h \<turnstile> ok ( get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)))"
+ using \<open>pa \<in> set ptrs\<close> \<open>\<And>pa. pa \<in> set ptrs
+ \<Longrightarrow> h \<turnstile> ok (get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children))) = h' \<turnstile> ok ( get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children)))\<close>
+ by auto
+ moreover have "h' \<turnstile> get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False
+ \<Longrightarrow> h \<turnstile> get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False"
+ by (metis (mono_tags, lifting)
+ \<open>\<And>pa. pa \<in> set ptrs \<Longrightarrow> h \<turnstile> get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r True = h' \<turnstile> get_child_nodes pa
+ \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r True\<close> \<open>pa \<in> set ptrs\<close>
+ calculation is_OK_returns_result_I returns_result_eq returns_result_select_result)
+ ultimately show "h \<turnstile> get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False"
+ using \<open>h' \<turnstile> get_child_nodes pa \<bind> (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r False\<close> by blast
+ qed
+
+ have filter_eq: "\<And>xs. h \<turnstile> filter_M ?P ptrs \<rightarrow>\<^sub>r xs = h' \<turnstile> filter_M ?P ptrs \<rightarrow>\<^sub>r xs"
+ proof (rule filter_M_eq)
+ show
+ "\<And>xs x. pure (Heap_Error_Monad.bind (get_child_nodes x) (\<lambda>children. return (c \<in> set children))) h"
+ by(auto intro!: bind_pure_I)
+ next
+ show
+ "\<And>xs x. pure (Heap_Error_Monad.bind (get_child_nodes x) (\<lambda>children. return (c \<in> set children))) h'"
+ by(auto intro!: bind_pure_I)
+ next
+ fix xs b x
+ assume 0: "x \<in> set ptrs"
+ then show "h \<turnstile> Heap_Error_Monad.bind (get_child_nodes x) (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r b
+ = h' \<turnstile> Heap_Error_Monad.bind (get_child_nodes x) (\<lambda>children. return (c \<in> set children)) \<rightarrow>\<^sub>r b"
+ apply(induct b)
+ using children_eq_True apply blast
+ using children_eq_False apply blast
+ done
+ qed
+
+ show "h \<turnstile> get_parent c \<rightarrow>\<^sub>r parent_opt = h' \<turnstile> get_parent c \<rightarrow>\<^sub>r parent_opt"
+ apply(simp add: get_parent_def)
+ apply(rule bind_cong_2)
+ apply(simp)
+ apply(simp)
+ apply(simp add: check_in_heap_def node_ptr_kinds_def object_ptr_kinds_eq3)
+ apply(rule bind_cong_2)
+ apply(auto simp add: object_ptr_kinds_M_eq object_ptr_kinds_eq3)[1]
+ apply(auto simp add: object_ptr_kinds_M_eq object_ptr_kinds_eq3)[1]
+ apply(auto simp add: object_ptr_kinds_M_eq object_ptr_kinds_eq3)[1]
+ apply(rule bind_cong_2)
+ apply(auto intro!: filter_M_pure_I bind_pure_I)[1]
+ apply(auto intro!: filter_M_pure_I bind_pure_I)[1]
+ apply(auto simp add: filter_eq (* dest!: returns_result_eq[OF ptrs] *))[1]
+ using filter_eq ptrs apply auto[1]
+ using filter_eq ptrs by auto
+ qed
+
+ have "ancestors = ancestors'"
+ proof(insert assms(1) assms(7) ancestors' 2, induct ptr arbitrary: ancestors ancestors'
+ rule: heap_wellformed_induct_rev)
+ case (step child)
+ show ?case
+ using step(2) step(3) step(4)
+ apply(simp add: get_ancestors_def)
+ apply(auto intro!: elim!: bind_returns_result_E2 split: option.splits)[1]
+ using returns_result_eq apply fastforce
+ apply (meson option.simps(3) returns_result_eq)
+ by (metis IntD1 IntD2 option.inject returns_result_eq step.hyps)
+ qed
+ then show ?thesis
+ using assms(5) ancestors'
+ by simp
+qed
+
+lemma get_ancestors_remains_not_in_ancestors:
+ assumes "heap_is_wellformed h"
+ and "heap_is_wellformed h'"
+ and "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors"
+ and "h' \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors'"
+ and "\<And>p children children'. h \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children
+ \<Longrightarrow> h' \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children' \<Longrightarrow> set children' \<subseteq> set children"
+ and "node \<notin> set ancestors"
+ and object_ptr_kinds_eq3: "object_ptr_kinds h = object_ptr_kinds h'"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ and type_wf': "type_wf h'"
+ shows "node \<notin> set ancestors'"
+proof -
+ have object_ptr_kinds_M_eq:
+ "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ using object_ptr_kinds_eq3
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+
+ show ?thesis
+ proof (insert assms(1) assms(3) assms(4) assms(6), induct ptr arbitrary: ancestors ancestors'
+ rule: heap_wellformed_induct_rev)
+ case (step child)
+ have 1: "\<And>p parent. h' \<turnstile> get_parent p \<rightarrow>\<^sub>r Some parent \<Longrightarrow> h \<turnstile> get_parent p \<rightarrow>\<^sub>r Some parent"
+ proof -
+ fix p parent
+ assume "h' \<turnstile> get_parent p \<rightarrow>\<^sub>r Some parent"
+ then obtain children' where
+ children': "h' \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children'" and
+ p_in_children': "p \<in> set children'"
+ using get_parent_child_dual by blast
+ obtain children where children: "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children"
+ using get_child_nodes_ok assms(1) get_child_nodes_ptr_in_heap object_ptr_kinds_eq children'
+ known_ptrs
+ using type_wf type_wf'
+ by (metis \<open>h' \<turnstile> get_parent p \<rightarrow>\<^sub>r Some parent\<close> get_parent_parent_in_heap is_OK_returns_result_E
+ local.known_ptrs_known_ptr object_ptr_kinds_eq3)
+ have "p \<in> set children"
+ using assms(5) children children' p_in_children'
+ by blast
+ then show "h \<turnstile> get_parent p \<rightarrow>\<^sub>r Some parent"
+ using child_parent_dual assms(1) children known_ptrs type_wf by blast
+ qed
+ have "node \<noteq> child"
+ using assms(1) get_ancestors_parent_child_rel step.prems(1) step.prems(3) known_ptrs
+ using type_wf type_wf'
+ by blast
+ then show ?case
+ using step(2) step(3)
+ apply(simp add: get_ancestors_def)
+ using step(4)
+ apply(auto elim!: bind_returns_result_E2 split: option.splits)[1]
+ using 1
+ apply (meson option.distinct(1) returns_result_eq)
+ by (metis "1" option.inject returns_result_eq step.hyps)
+ qed
+qed
+
+lemma get_ancestors_ptrs_in_heap:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors"
+ assumes "ptr' \<in> set ancestors"
+ shows "ptr' |\<in>| object_ptr_kinds h"
+proof (insert assms(4) assms(5), induct ancestors arbitrary: ptr)
+ case Nil
+ then show ?case
+ by(auto)
+next
+ case (Cons a ancestors)
+ then obtain x where x: "h \<turnstile> get_ancestors x \<rightarrow>\<^sub>r a # ancestors"
+ by(auto simp add: get_ancestors_def[of a] elim!: bind_returns_result_E2 split: option.splits)
+ then have "x = a"
+ by(auto simp add: get_ancestors_def[of x] elim!: bind_returns_result_E2 split: option.splits)
+ then show ?case
+ using Cons.hyps Cons.prems(2) get_ancestors_ptr_in_heap x
+ by (metis assms(1) assms(2) assms(3) get_ancestors_obtains_children get_child_nodes_ptr_in_heap
+ is_OK_returns_result_I)
+qed
+
+
+lemma get_ancestors_prefix:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors"
+ assumes "ptr' \<in> set ancestors"
+ assumes "h \<turnstile> get_ancestors ptr' \<rightarrow>\<^sub>r ancestors'"
+ shows "\<exists>pre. ancestors = pre @ ancestors'"
+proof (insert assms(1) assms(5) assms(6), induct ptr' arbitrary: ancestors'
+ rule: heap_wellformed_induct)
+ case (step parent)
+ then show ?case
+ proof (cases "parent \<noteq> ptr" )
+ case True
+
+ then obtain children ancestor_child where "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children"
+ and "ancestor_child \<in> set children" and "cast ancestor_child \<in> set ancestors"
+ using assms(1) assms(2) assms(3) assms(4) get_ancestors_obtains_children step.prems(1) by blast
+ then have "h \<turnstile> get_parent ancestor_child \<rightarrow>\<^sub>r Some parent"
+ using assms(1) assms(2) assms(3) child_parent_dual by blast
+ then have "h \<turnstile> get_ancestors (cast ancestor_child) \<rightarrow>\<^sub>r cast ancestor_child # ancestors'"
+ apply(simp add: get_ancestors_def)
+ using \<open>h \<turnstile> get_ancestors parent \<rightarrow>\<^sub>r ancestors'\<close> get_parent_ptr_in_heap
+ by(auto simp add: check_in_heap_def is_OK_returns_result_I intro!: bind_pure_returns_result_I)
+ then show ?thesis
+ using step(1) \<open>h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children\<close> \<open>ancestor_child \<in> set children\<close>
+ \<open>cast ancestor_child \<in> set ancestors\<close> \<open>h \<turnstile> get_ancestors (cast ancestor_child) \<rightarrow>\<^sub>r cast ancestor_child # ancestors'\<close>
+ by fastforce
+ next
+ case False
+ then show ?thesis
+ by (metis append_Nil assms(4) returns_result_eq step.prems(2))
+ qed
+qed
+
+
+lemma get_ancestors_same_root_node:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors"
+ assumes "ptr' \<in> set ancestors"
+ assumes "ptr'' \<in> set ancestors"
+ shows "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr \<longleftrightarrow> h \<turnstile> get_root_node ptr'' \<rightarrow>\<^sub>r root_ptr"
+proof -
+ have "ptr' |\<in>| object_ptr_kinds h"
+ by (metis assms(1) assms(2) assms(3) assms(4) assms(5) get_ancestors_obtains_children
+ get_ancestors_ptr_in_heap get_child_nodes_ptr_in_heap is_OK_returns_result_I)
+ then obtain ancestors' where ancestors': "h \<turnstile> get_ancestors ptr' \<rightarrow>\<^sub>r ancestors'"
+ by (meson assms(1) assms(2) assms(3) get_ancestors_ok is_OK_returns_result_E)
+ then have "\<exists>pre. ancestors = pre @ ancestors'"
+ using get_ancestors_prefix assms by blast
+ moreover have "ptr'' |\<in>| object_ptr_kinds h"
+ by (metis assms(1) assms(2) assms(3) assms(4) assms(6) get_ancestors_obtains_children
+ get_ancestors_ptr_in_heap get_child_nodes_ptr_in_heap is_OK_returns_result_I)
+ then obtain ancestors'' where ancestors'': "h \<turnstile> get_ancestors ptr'' \<rightarrow>\<^sub>r ancestors''"
+ by (meson assms(1) assms(2) assms(3) get_ancestors_ok is_OK_returns_result_E)
+ then have "\<exists>pre. ancestors = pre @ ancestors''"
+ using get_ancestors_prefix assms by blast
+ ultimately show ?thesis
+ using ancestors' ancestors''
+ apply(auto simp add: get_root_node_def elim!: bind_returns_result_E2
+ intro!: bind_pure_returns_result_I)[1]
+ apply (metis (no_types, lifting) assms(1) get_ancestors_never_empty last_appendR
+ returns_result_eq)
+ by (metis assms(1) get_ancestors_never_empty last_appendR returns_result_eq)
+qed
+
+lemma get_root_node_parent_same:
+ assumes "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some ptr"
+ shows "h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root \<longleftrightarrow> h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+proof
+ assume 1: " h \<turnstile> get_root_node (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r root"
+ show "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ using 1[unfolded get_root_node_def] assms
+ apply(simp add: get_ancestors_def)
+ apply(auto simp add: get_root_node_def dest: returns_result_eq elim!: bind_returns_result_E2
+ intro!: bind_pure_returns_result_I split: option.splits)[1]
+ using returns_result_eq apply fastforce
+ using get_ancestors_ptr by fastforce
+next
+ assume 1: " h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ show "h \<turnstile> get_root_node (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r root"
+ apply(simp add: get_root_node_def)
+ using assms 1
+ apply(simp add: get_ancestors_def)
+ apply(auto simp add: get_root_node_def dest: returns_result_eq elim!: bind_returns_result_E2
+ intro!: bind_pure_returns_result_I split: option.splits)[1]
+ apply (simp add: check_in_heap_def is_OK_returns_result_I)
+ using get_ancestors_ptr get_parent_ptr_in_heap
+ apply (simp add: is_OK_returns_result_I)
+ by (meson list.distinct(1) list.set_cases local.get_ancestors_ptr)
+qed
+
+lemma get_root_node_same_no_parent:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r cast child"
+ shows "h \<turnstile> get_parent child \<rightarrow>\<^sub>r None"
+proof (insert assms(1) assms(4), induct ptr rule: heap_wellformed_induct_rev)
+ case (step c)
+ then show ?case
+ proof (cases "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r c")
+ case None
+ then have "c = cast child"
+ using step(2)
+ by(auto simp add: get_root_node_def get_ancestors_def[of c] elim!: bind_returns_result_E2)
+ then show ?thesis
+ using None by auto
+ next
+ case (Some child_node)
+ note s = this
+ then obtain parent_opt where parent_opt: "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r parent_opt"
+ by (metis (no_types, lifting) assms(2) assms(3) get_root_node_ptr_in_heap
+ is_OK_returns_result_I local.get_parent_ok node_ptr_casts_commute
+ node_ptr_kinds_commutes returns_result_select_result step.prems)
+ then show ?thesis
+ proof(induct parent_opt)
+ case None
+ then show ?case
+ using Some get_root_node_no_parent returns_result_eq step.prems by fastforce
+ next
+ case (Some parent)
+ then show ?case
+ using step s
+ apply(auto simp add: get_root_node_def get_ancestors_def[of c]
+ elim!: bind_returns_result_E2 split: option.splits list.splits)[1]
+ using get_root_node_parent_same step.hyps step.prems by auto
+ qed
+ qed
+qed
+
+lemma get_root_node_not_node_same:
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ assumes "\<not>is_node_ptr_kind ptr"
+ shows "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r ptr"
+ using assms
+ apply(simp add: get_root_node_def get_ancestors_def)
+ by(auto simp add: get_root_node_def dest: returns_result_eq elim!: bind_returns_result_E2
+ intro!: bind_pure_returns_result_I split: option.splits)
+
+
+lemma get_root_node_root_in_heap:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ shows "root |\<in>| object_ptr_kinds h"
+ using assms
+ apply(auto simp add: get_root_node_def elim!: bind_returns_result_E2)[1]
+ by (simp add: get_ancestors_never_empty get_ancestors_ptrs_in_heap)
+
+
+lemma get_root_node_same_no_parent_parent_child_rel:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r ptr'"
+ shows "\<not>(\<exists>p. (p, ptr') \<in> (parent_child_rel h))"
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) assms(4) get_root_node_same_no_parent
+ l_heap_is_wellformed.parent_child_rel_child local.child_parent_dual local.get_child_nodes_ok
+ local.known_ptrs_known_ptr local.l_heap_is_wellformed_axioms local.parent_child_rel_node_ptr
+ local.parent_child_rel_parent_in_heap node_ptr_casts_commute3 option.simps(3) returns_result_eq
+ returns_result_select_result)
+
+end
+
+
+locale l_get_ancestors_wf = l_heap_is_wellformed_defs + l_known_ptrs + l_type_wf + l_get_ancestors_defs
+ + l_get_child_nodes_defs + l_get_parent_defs +
+ assumes get_ancestors_never_empty:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_ancestors child \<rightarrow>\<^sub>r ancestors \<Longrightarrow> ancestors \<noteq> []"
+ assumes get_ancestors_ok:
+ "heap_is_wellformed h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h
+ \<Longrightarrow> h \<turnstile> ok (get_ancestors ptr)"
+ assumes get_ancestors_reads:
+ "heap_is_wellformed h \<Longrightarrow> reads get_ancestors_locs (get_ancestors node_ptr) h h'"
+ assumes get_ancestors_ptrs_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors \<Longrightarrow> ptr' \<in> set ancestors
+ \<Longrightarrow> ptr' |\<in>| object_ptr_kinds h"
+ assumes get_ancestors_remains_not_in_ancestors:
+ "heap_is_wellformed h \<Longrightarrow> heap_is_wellformed h' \<Longrightarrow> h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors
+ \<Longrightarrow> h' \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors'
+ \<Longrightarrow> (\<And>p children children'. h \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children
+ \<Longrightarrow> h' \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children'
+ \<Longrightarrow> set children' \<subseteq> set children)
+ \<Longrightarrow> node \<notin> set ancestors
+ \<Longrightarrow> object_ptr_kinds h = object_ptr_kinds h' \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> type_wf h \<Longrightarrow> type_wf h' \<Longrightarrow> node \<notin> set ancestors'"
+ assumes get_ancestors_also_parent:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_ancestors some_ptr \<rightarrow>\<^sub>r ancestors
+ \<Longrightarrow> cast child_node \<in> set ancestors
+ \<Longrightarrow> h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent \<Longrightarrow> type_wf h
+ \<Longrightarrow> known_ptrs h \<Longrightarrow> parent \<in> set ancestors"
+ assumes get_ancestors_obtains_children:
+ "heap_is_wellformed h \<Longrightarrow> ancestor \<noteq> ptr \<Longrightarrow> ancestor \<in> set ancestors
+ \<Longrightarrow> h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> (\<And>children ancestor_child . h \<turnstile> get_child_nodes ancestor \<rightarrow>\<^sub>r children
+ \<Longrightarrow> ancestor_child \<in> set children
+ \<Longrightarrow> cast ancestor_child \<in> set ancestors
+ \<Longrightarrow> thesis)
+ \<Longrightarrow> thesis"
+ assumes get_ancestors_parent_child_rel:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_ancestors child \<rightarrow>\<^sub>r ancestors \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h
+ \<Longrightarrow> (ptr, child) \<in> (parent_child_rel h)\<^sup>* \<longleftrightarrow> ptr \<in> set ancestors"
+
+locale l_get_root_node_wf = l_heap_is_wellformed_defs + l_get_root_node_defs + l_type_wf
+ + l_known_ptrs + l_get_ancestors_defs + l_get_parent_defs +
+ assumes get_root_node_ok:
+ "heap_is_wellformed h \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h
+ \<Longrightarrow> h \<turnstile> ok (get_root_node ptr)"
+ assumes get_root_node_ptr_in_heap:
+ "h \<turnstile> ok (get_root_node ptr) \<Longrightarrow> ptr |\<in>| object_ptr_kinds h"
+ assumes get_root_node_root_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root \<Longrightarrow> root |\<in>| object_ptr_kinds h"
+ assumes get_ancestors_same_root_node:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors \<Longrightarrow> ptr' \<in> set ancestors
+ \<Longrightarrow> ptr'' \<in> set ancestors
+ \<Longrightarrow> h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr \<longleftrightarrow> h \<turnstile> get_root_node ptr'' \<rightarrow>\<^sub>r root_ptr"
+ assumes get_root_node_same_no_parent:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r cast child \<Longrightarrow> h \<turnstile> get_parent child \<rightarrow>\<^sub>r None"
+ assumes get_root_node_parent_same:
+ "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some ptr
+ \<Longrightarrow> h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root \<longleftrightarrow> h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+
+interpretation i_get_root_node_wf?:
+ l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf known_ptrs heap_is_wellformed parent_child_rel
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ get_parent get_parent_locs get_ancestors get_ancestors_locs get_root_node get_root_node_locs
+ using instances
+ by(simp add: l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_ancestors_wf_is_l_get_ancestors_wf [instances]:
+ "l_get_ancestors_wf heap_is_wellformed parent_child_rel known_ptr known_ptrs type_wf get_ancestors
+ get_ancestors_locs get_child_nodes get_parent"
+ using known_ptrs_is_l_known_ptrs
+ apply(auto simp add: l_get_ancestors_wf_def l_get_ancestors_wf_axioms_def)[1]
+ using get_ancestors_never_empty apply blast
+ using get_ancestors_ok apply blast
+ using get_ancestors_reads apply blast
+ using get_ancestors_ptrs_in_heap apply blast
+ using get_ancestors_remains_not_in_ancestors apply blast
+ using get_ancestors_also_parent apply blast
+ using get_ancestors_obtains_children apply blast
+ using get_ancestors_parent_child_rel apply blast
+ using get_ancestors_parent_child_rel apply blast
+ done
+
+lemma get_root_node_wf_is_l_get_root_node_wf [instances]:
+ "l_get_root_node_wf heap_is_wellformed get_root_node type_wf known_ptr known_ptrs
+ get_ancestors get_parent"
+ using known_ptrs_is_l_known_ptrs
+ apply(auto simp add: l_get_root_node_wf_def l_get_root_node_wf_axioms_def)[1]
+ using get_root_node_ok apply blast
+ using get_root_node_ptr_in_heap apply blast
+ using get_root_node_root_in_heap apply blast
+ using get_ancestors_same_root_node apply(blast, blast)
+ using get_root_node_same_no_parent apply blast
+ using get_root_node_parent_same apply (blast, blast)
+ done
+
+
+subsection \<open>to\_tree\_order\<close>
+
+locale l_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent +
+ l_get_parent_wf +
+ l_heap_is_wellformed
+ (* l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M *)
+begin
+
+lemma to_tree_order_ptr_in_heap:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ assumes "h \<turnstile> ok (to_tree_order ptr)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+proof(insert assms(1) assms(4), induct rule: heap_wellformed_induct)
+ case (step parent)
+ then show ?case
+ apply(auto simp add: to_tree_order_def[of parent] map_M_pure_I elim!: bind_is_OK_E3)[1]
+ using get_child_nodes_ptr_in_heap by blast
+qed
+
+lemma to_tree_order_either_ptr_or_in_children:
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes"
+ and "node \<in> set nodes"
+ and "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ and "node \<noteq> ptr"
+ obtains child child_to where "child \<in> set children"
+ and "h \<turnstile> to_tree_order (cast child) \<rightarrow>\<^sub>r child_to" and "node \<in> set child_to"
+proof -
+ obtain treeorders where treeorders: "h \<turnstile> map_M to_tree_order (map cast children) \<rightarrow>\<^sub>r treeorders"
+ using assms
+ apply(auto simp add: to_tree_order_def elim!: bind_returns_result_E)[1]
+ using pure_returns_heap_eq returns_result_eq by fastforce
+ then have "node \<in> set (concat treeorders)"
+ using assms[simplified to_tree_order_def]
+ by(auto elim!: bind_returns_result_E4 dest: pure_returns_heap_eq)
+ then obtain treeorder where "treeorder \<in> set treeorders"
+ and node_in_treeorder: "node \<in> set treeorder"
+ by auto
+ then obtain child where "h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r treeorder"
+ and "child \<in> set children"
+ using assms[simplified to_tree_order_def] treeorders
+ by(auto elim!: map_M_pure_E2)
+ then show ?thesis
+ using node_in_treeorder returns_result_eq that by auto
+qed
+
+
+lemma to_tree_order_ptrs_in_heap:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ assumes "ptr' \<in> set to"
+ shows "ptr' |\<in>| object_ptr_kinds h"
+proof(insert assms(1) assms(4) assms(5), induct ptr arbitrary: to rule: heap_wellformed_induct)
+ case (step parent)
+ have "parent |\<in>| object_ptr_kinds h"
+ using assms(1) assms(2) assms(3) step.prems(1) to_tree_order_ptr_in_heap by blast
+ then obtain children where children: "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children"
+ by (meson assms(2) assms(3) get_child_nodes_ok is_OK_returns_result_E local.known_ptrs_known_ptr)
+ then show ?case
+ proof (cases "children = []")
+ case True
+ then have "to = [parent]"
+ using step(2) children
+ apply(auto simp add: to_tree_order_def[of parent] map_M_pure_I elim!: bind_returns_result_E2)[1]
+ by (metis list.distinct(1) list.map_disc_iff list.set_cases map_M_pure_E2 returns_result_eq)
+ then show ?thesis
+ using \<open>parent |\<in>| object_ptr_kinds h\<close> step.prems(2) by auto
+ next
+ case False
+ note f = this
+ then show ?thesis
+ using children step to_tree_order_either_ptr_or_in_children
+ proof (cases "ptr' = parent")
+ case True
+ then show ?thesis
+ using \<open>parent |\<in>| object_ptr_kinds h\<close> by blast
+ next
+ case False
+ then show ?thesis
+ using children step.hyps to_tree_order_either_ptr_or_in_children
+ by (metis step.prems(1) step.prems(2))
+ qed
+ qed
+qed
+
+lemma to_tree_order_ok:
+ assumes wellformed: "heap_is_wellformed h"
+ and "ptr |\<in>| object_ptr_kinds h"
+ and "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "h \<turnstile> ok (to_tree_order ptr)"
+proof(insert assms(1) assms(2), induct rule: heap_wellformed_induct)
+ case (step parent)
+ then show ?case
+ using assms(3) type_wf
+ apply(simp add: to_tree_order_def)
+ apply(auto simp add: heap_is_wellformed_def intro!: map_M_ok_I bind_is_OK_pure_I map_M_pure_I)[1]
+ using get_child_nodes_ok known_ptrs_known_ptr apply blast
+ by (simp add: local.heap_is_wellformed_children_in_heap local.to_tree_order_def wellformed)
+qed
+
+lemma to_tree_order_child_subset:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes"
+ and "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ and "node \<in> set children"
+ and "h \<turnstile> to_tree_order (cast node) \<rightarrow>\<^sub>r nodes'"
+ shows "set nodes' \<subseteq> set nodes"
+proof
+ fix x
+ assume a1: "x \<in> set nodes'"
+ moreover obtain treeorders
+ where treeorders: "h \<turnstile> map_M to_tree_order (map cast children) \<rightarrow>\<^sub>r treeorders"
+ using assms(2) assms(3)
+ apply(auto simp add: to_tree_order_def elim!: bind_returns_result_E)[1]
+ using pure_returns_heap_eq returns_result_eq by fastforce
+ then have "nodes' \<in> set treeorders"
+ using assms(4) assms(5)
+ by(auto elim!: map_M_pure_E dest: returns_result_eq)
+ moreover have "set (concat treeorders) \<subseteq> set nodes"
+ using treeorders assms(2) assms(3)
+ by(auto simp add: to_tree_order_def elim!: bind_returns_result_E4 dest: pure_returns_heap_eq)
+ ultimately show "x \<in> set nodes"
+ by auto
+qed
+
+lemma to_tree_order_ptr_in_result:
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes"
+ shows "ptr \<in> set nodes"
+ using assms
+ apply(simp add: to_tree_order_def)
+ by(auto elim!: bind_returns_result_E2 intro!: map_M_pure_I bind_pure_I)
+
+lemma to_tree_order_subset:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes"
+ and "node \<in> set nodes"
+ and "h \<turnstile> to_tree_order node \<rightarrow>\<^sub>r nodes'"
+ and "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "set nodes' \<subseteq> set nodes"
+proof -
+ have "\<forall>nodes. h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes \<longrightarrow> (\<forall>node. node \<in> set nodes
+ \<longrightarrow> (\<forall>nodes'. h \<turnstile> to_tree_order node \<rightarrow>\<^sub>r nodes' \<longrightarrow> set nodes' \<subseteq> set nodes))"
+ proof(insert assms(1), induct ptr rule: heap_wellformed_induct)
+ case (step parent)
+ then show ?case
+ proof safe
+ fix nodes node nodes' x
+ assume 1: "(\<And>children child.
+ h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children \<Longrightarrow>
+ child \<in> set children \<Longrightarrow> \<forall>nodes. h \<turnstile> to_tree_order (cast child) \<rightarrow>\<^sub>r nodes
+ \<longrightarrow> (\<forall>node. node \<in> set nodes \<longrightarrow> (\<forall>nodes'. h \<turnstile> to_tree_order node \<rightarrow>\<^sub>r nodes'
+ \<longrightarrow> set nodes' \<subseteq> set nodes)))"
+ and 2: "h \<turnstile> to_tree_order parent \<rightarrow>\<^sub>r nodes"
+ and 3: "node \<in> set nodes"
+ and "h \<turnstile> to_tree_order node \<rightarrow>\<^sub>r nodes'"
+ and "x \<in> set nodes'"
+ have h1: "(\<And>children child nodes node nodes'.
+ h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children \<Longrightarrow>
+ child \<in> set children \<Longrightarrow> h \<turnstile> to_tree_order (cast child) \<rightarrow>\<^sub>r nodes
+ \<longrightarrow> (node \<in> set nodes \<longrightarrow> (h \<turnstile> to_tree_order node \<rightarrow>\<^sub>r nodes' \<longrightarrow> set nodes' \<subseteq> set nodes)))"
+ using 1
+ by blast
+ obtain children where children: "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children"
+ using 2
+ by(auto simp add: to_tree_order_def elim!: bind_returns_result_E)
+ then have "set nodes' \<subseteq> set nodes"
+ proof (cases "children = []")
+ case True
+ then show ?thesis
+ by (metis "2" "3" \<open>h \<turnstile> to_tree_order node \<rightarrow>\<^sub>r nodes'\<close> children empty_iff list.set(1)
+ subsetI to_tree_order_either_ptr_or_in_children)
+ next
+ case False
+ then show ?thesis
+ proof (cases "node = parent")
+ case True
+ then show ?thesis
+ using "2" \<open>h \<turnstile> to_tree_order node \<rightarrow>\<^sub>r nodes'\<close> returns_result_eq by fastforce
+ next
+ case False
+ then obtain child nodes_of_child where
+ "child \<in> set children" and
+ "h \<turnstile> to_tree_order (cast child) \<rightarrow>\<^sub>r nodes_of_child" and
+ "node \<in> set nodes_of_child"
+ using 2[simplified to_tree_order_def] 3
+ to_tree_order_either_ptr_or_in_children[where node=node and ptr=parent] children
+ apply(auto elim!: bind_returns_result_E2 intro: map_M_pure_I)[1]
+ using is_OK_returns_result_E 2 a_all_ptrs_in_heap_def assms(1) heap_is_wellformed_def
+ using "3" by blast
+ then have "set nodes' \<subseteq> set nodes_of_child"
+ using h1
+ using \<open>h \<turnstile> to_tree_order node \<rightarrow>\<^sub>r nodes'\<close> children by blast
+ moreover have "set nodes_of_child \<subseteq> set nodes"
+ using "2" \<open>child \<in> set children\<close> \<open>h \<turnstile> to_tree_order (cast child) \<rightarrow>\<^sub>r nodes_of_child\<close>
+ assms children to_tree_order_child_subset by auto
+ ultimately show ?thesis
+ by blast
+ qed
+ qed
+ then show "x \<in> set nodes"
+ using \<open>x \<in> set nodes'\<close> by blast
+ qed
+ qed
+ then show ?thesis
+ using assms by blast
+qed
+
+lemma to_tree_order_parent:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes"
+ assumes "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some parent"
+ assumes "parent \<in> set nodes"
+ shows "cast child \<in> set nodes"
+proof -
+ obtain nodes' where nodes': "h \<turnstile> to_tree_order parent \<rightarrow>\<^sub>r nodes'"
+ using assms to_tree_order_ok get_parent_parent_in_heap
+ by (meson get_parent_parent_in_heap is_OK_returns_result_E)
+
+ then have "set nodes' \<subseteq> set nodes"
+ using to_tree_order_subset assms
+ by blast
+ moreover obtain children where
+ children: "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children" and
+ child: "child \<in> set children"
+ using assms get_parent_child_dual by blast
+ then obtain child_to where child_to: "h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r child_to"
+ by (meson assms(1) assms(2) assms(3) assms(5) is_OK_returns_result_E is_OK_returns_result_I
+ get_parent_ptr_in_heap node_ptr_kinds_commutes to_tree_order_ok)
+ then have "cast child \<in> set child_to"
+ apply(simp add: to_tree_order_def)
+ by(auto elim!: bind_returns_result_E2 map_M_pure_E
+ dest!: bind_returns_result_E3[rotated, OF children, rotated] intro!: map_M_pure_I)
+
+ have "cast child \<in> set nodes'"
+ using nodes' child
+ apply(simp add: to_tree_order_def)
+ apply(auto elim!: bind_returns_result_E2 map_M_pure_E
+ dest!: bind_returns_result_E3[rotated, OF children, rotated] intro!: map_M_pure_I)[1]
+ using child_to \<open>cast child \<in> set child_to\<close> returns_result_eq by fastforce
+ ultimately show ?thesis
+ by auto
+qed
+
+lemma to_tree_order_child:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes"
+ assumes "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children"
+ assumes "cast child \<noteq> ptr"
+ assumes "child \<in> set children"
+ assumes "cast child \<in> set nodes"
+ shows "parent \<in> set nodes"
+proof(insert assms(1) assms(4) assms(6) assms(8), induct ptr arbitrary: nodes
+ rule: heap_wellformed_induct)
+ case (step p)
+ have "p |\<in>| object_ptr_kinds h"
+ using \<open>h \<turnstile> to_tree_order p \<rightarrow>\<^sub>r nodes\<close> to_tree_order_ptr_in_heap
+ using assms(1) assms(2) assms(3) by blast
+ then obtain children where children: "h \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children"
+ by (meson assms(2) assms(3) get_child_nodes_ok is_OK_returns_result_E local.known_ptrs_known_ptr)
+ then show ?case
+ proof (cases "children = []")
+ case True
+ then show ?thesis
+ using step(2) step(3) step(4) children
+ by(auto simp add: to_tree_order_def[of p] map_M_pure_I elim!: bind_returns_result_E2
+ dest!: bind_returns_result_E3[rotated, OF children, rotated])
+ next
+ case False
+ then obtain c child_to where
+ child: "c \<in> set children" and
+ child_to: "h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c) \<rightarrow>\<^sub>r child_to" and
+ "cast child \<in> set child_to"
+ using step(2) children
+ apply(auto simp add: to_tree_order_def[of p] map_M_pure_I elim!: bind_returns_result_E2
+ dest!: bind_returns_result_E3[rotated, OF children, rotated])[1]
+ by (metis (full_types) assms(1) assms(2) assms(3) get_parent_ptr_in_heap
+ is_OK_returns_result_I l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.child_parent_dual
+ l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms node_ptr_kinds_commutes
+ returns_result_select_result step.prems(1) step.prems(2) step.prems(3)
+ to_tree_order_either_ptr_or_in_children to_tree_order_ok)
+ then have "set child_to \<subseteq> set nodes"
+ using assms(1) child children step.prems(1) to_tree_order_child_subset by auto
+
+ show ?thesis
+ proof (cases "c = child")
+ case True
+ then have "parent = p"
+ using step(3) children child assms(5) assms(7)
+ by (meson assms(1) assms(2) assms(3) child_parent_dual option.inject returns_result_eq)
+
+ then show ?thesis
+ using step.prems(1) to_tree_order_ptr_in_result by blast
+ next
+ case False
+ then show ?thesis
+ using step(1)[OF children child child_to] step(3) step(4)
+ using \<open>set child_to \<subseteq> set nodes\<close>
+ using \<open>cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child \<in> set child_to\<close> by auto
+ qed
+ qed
+qed
+
+lemma to_tree_order_node_ptrs:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes"
+ assumes "ptr' \<noteq> ptr"
+ assumes "ptr' \<in> set nodes"
+ shows "is_node_ptr_kind ptr'"
+proof(insert assms(1) assms(4) assms(5) assms(6), induct ptr arbitrary: nodes
+ rule: heap_wellformed_induct)
+ case (step p)
+ have "p |\<in>| object_ptr_kinds h"
+ using \<open>h \<turnstile> to_tree_order p \<rightarrow>\<^sub>r nodes\<close> to_tree_order_ptr_in_heap
+ using assms(1) assms(2) assms(3) by blast
+ then obtain children where children: "h \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children"
+ by (meson assms(2) assms(3) get_child_nodes_ok is_OK_returns_result_E local.known_ptrs_known_ptr)
+ then show ?case
+ proof (cases "children = []")
+ case True
+ then show ?thesis
+ using step(2) step(3) step(4) children
+ by(auto simp add: to_tree_order_def[of p] map_M_pure_I elim!: bind_returns_result_E2
+ dest!: bind_returns_result_E3[rotated, OF children, rotated])[1]
+ next
+ case False
+ then obtain c child_to where
+ child: "c \<in> set children" and
+ child_to: "h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c) \<rightarrow>\<^sub>r child_to" and
+ "ptr' \<in> set child_to"
+ using step(2) children
+ apply(auto simp add: to_tree_order_def[of p] map_M_pure_I elim!: bind_returns_result_E2
+ dest!: bind_returns_result_E3[rotated, OF children, rotated])[1]
+ using step.prems(1) step.prems(2) step.prems(3) to_tree_order_either_ptr_or_in_children by blast
+ then have "set child_to \<subseteq> set nodes"
+ using assms(1) child children step.prems(1) to_tree_order_child_subset by auto
+
+ show ?thesis
+ proof (cases "cast c = ptr")
+ case True
+ then show ?thesis
+ using step \<open>ptr' \<in> set child_to\<close> assms(5) child child_to children by blast
+ next
+ case False
+ then show ?thesis
+ using \<open>ptr' \<in> set child_to\<close> child child_to children is_node_ptr_kind_cast step.hyps by blast
+ qed
+ qed
+qed
+
+lemma to_tree_order_child2:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes"
+ assumes "cast child \<noteq> ptr"
+ assumes "cast child \<in> set nodes"
+ obtains parent where "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some parent" and "parent \<in> set nodes"
+proof -
+ assume 1: "(\<And>parent. h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some parent \<Longrightarrow> parent \<in> set nodes \<Longrightarrow> thesis)"
+ show thesis
+ proof(insert assms(1) assms(4) assms(5) assms(6) 1, induct ptr arbitrary: nodes
+ rule: heap_wellformed_induct)
+ case (step p)
+ have "p |\<in>| object_ptr_kinds h"
+ using \<open>h \<turnstile> to_tree_order p \<rightarrow>\<^sub>r nodes\<close> to_tree_order_ptr_in_heap
+ using assms(1) assms(2) assms(3) by blast
+ then obtain children where children: "h \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children"
+ by (meson assms(2) assms(3) get_child_nodes_ok is_OK_returns_result_E local.known_ptrs_known_ptr)
+ then show ?case
+ proof (cases "children = []")
+ case True
+ then show ?thesis
+ using step(2) step(3) step(4) children
+ by(auto simp add: to_tree_order_def[of p] map_M_pure_I elim!: bind_returns_result_E2
+ dest!: bind_returns_result_E3[rotated, OF children, rotated])
+ next
+ case False
+ then obtain c child_to where
+ child: "c \<in> set children" and
+ child_to: "h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r c) \<rightarrow>\<^sub>r child_to" and
+ "cast child \<in> set child_to"
+ using step(2) children
+ apply(auto simp add: to_tree_order_def[of p] map_M_pure_I elim!: bind_returns_result_E2
+ dest!: bind_returns_result_E3[rotated, OF children, rotated])[1]
+ using step.prems(1) step.prems(2) step.prems(3) to_tree_order_either_ptr_or_in_children
+ by blast
+ then have "set child_to \<subseteq> set nodes"
+ using assms(1) child children step.prems(1) to_tree_order_child_subset by auto
+
+ have "cast child |\<in>| object_ptr_kinds h"
+ using assms(1) assms(2) assms(3) assms(4) assms(6) to_tree_order_ptrs_in_heap by blast
+ then obtain parent_opt where parent_opt: "h \<turnstile> get_parent child \<rightarrow>\<^sub>r parent_opt"
+ by (meson assms(2) assms(3) is_OK_returns_result_E get_parent_ok node_ptr_kinds_commutes)
+ then show ?thesis
+ proof (induct parent_opt)
+ case None
+ then show ?case
+ by (metis \<open>cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child \<in> set child_to\<close> assms(1) assms(2) assms(3)
+ cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject child child_parent_dual child_to children
+ option.distinct(1) returns_result_eq step.hyps)
+ next
+ case (Some option)
+ then show ?case
+ by (meson assms(1) assms(2) assms(3) get_parent_child_dual step.prems(1) step.prems(2)
+ step.prems(3) step.prems(4) to_tree_order_child)
+ qed
+ qed
+ qed
+qed
+
+lemma to_tree_order_parent_child_rel:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ shows "(ptr, child) \<in> (parent_child_rel h)\<^sup>* \<longleftrightarrow> child \<in> set to"
+proof
+ assume 3: "(ptr, child) \<in> (parent_child_rel h)\<^sup>*"
+ show "child \<in> set to"
+ proof (insert 3, induct child rule: heap_wellformed_induct_rev[OF assms(1)])
+ case (1 child)
+ then show ?case
+ proof (cases "ptr = child")
+ case True
+ then show ?thesis
+ using assms(4)
+ apply(simp add: to_tree_order_def)
+ by(auto simp add: map_M_pure_I elim!: bind_returns_result_E2)
+ next
+ case False
+ obtain child_parent where
+ "(ptr, child_parent) \<in> (parent_child_rel h)\<^sup>*" and
+ "(child_parent, child) \<in> (parent_child_rel h)"
+ using \<open>ptr \<noteq> child\<close>
+ by (metis "1.prems" rtranclE)
+ obtain child_node where child_node: "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node = child"
+ using \<open>(child_parent, child) \<in> parent_child_rel h\<close> node_ptr_casts_commute3
+ parent_child_rel_node_ptr
+ by blast
+ then have "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some child_parent"
+ using \<open>(child_parent, child) \<in> (parent_child_rel h)\<close>
+ by (meson assms(1) assms(2) assms(3) is_OK_returns_result_E l_get_parent_wf.child_parent_dual
+ l_heap_is_wellformed.parent_child_rel_child local.get_child_nodes_ok
+ local.known_ptrs_known_ptr local.l_get_parent_wf_axioms
+ local.l_heap_is_wellformed_axioms local.parent_child_rel_parent_in_heap)
+ then show ?thesis
+ using 1(1) child_node \<open>(ptr, child_parent) \<in> (parent_child_rel h)\<^sup>*\<close>
+ using assms(1) assms(2) assms(3) assms(4) to_tree_order_parent by blast
+ qed
+ qed
+next
+ assume "child \<in> set to"
+ then show "(ptr, child) \<in> (parent_child_rel h)\<^sup>*"
+ proof (induct child rule: heap_wellformed_induct_rev[OF assms(1)])
+ case (1 child)
+ then show ?case
+ proof (cases "ptr = child")
+ case True
+ then show ?thesis
+ by simp
+ next
+ case False
+ then have "\<exists>parent. (parent, child) \<in> (parent_child_rel h)"
+ using 1(2) assms(4) to_tree_order_child2[OF assms(1) assms(2) assms(3) assms(4)]
+ to_tree_order_node_ptrs
+ by (metis assms(1) assms(2) assms(3) node_ptr_casts_commute3 parent_child_rel_parent)
+ then obtain child_node where child_node: "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node = child"
+ using node_ptr_casts_commute3 parent_child_rel_node_ptr by blast
+ then obtain child_parent where child_parent: "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some child_parent"
+ using \<open>\<exists>parent. (parent, child) \<in> (parent_child_rel h)\<close>
+ by (metis "1.prems" False assms(1) assms(2) assms(3) assms(4) to_tree_order_child2)
+ then have "(child_parent, child) \<in> (parent_child_rel h)"
+ using assms(1) child_node parent_child_rel_parent by blast
+ moreover have "child_parent \<in> set to"
+ by (metis "1.prems" False assms(1) assms(2) assms(3) assms(4) child_node child_parent
+ get_parent_child_dual to_tree_order_child)
+ then have "(ptr, child_parent) \<in> (parent_child_rel h)\<^sup>*"
+ using 1 child_node child_parent by blast
+ ultimately show ?thesis
+ by auto
+ qed
+ qed
+qed
+end
+
+interpretation i_to_tree_order_wf?: l_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes
+ get_child_nodes_locs to_tree_order known_ptrs get_parent
+ get_parent_locs heap_is_wellformed parent_child_rel
+ get_disconnected_nodes get_disconnected_nodes_locs
+ using instances
+ apply(simp add: l_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+ done
+declare l_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+locale l_to_tree_order_wf = l_heap_is_wellformed_defs + l_type_wf + l_known_ptrs
+ + l_to_tree_order_defs
+ + l_get_parent_defs + l_get_child_nodes_defs +
+ assumes to_tree_order_ok:
+ "heap_is_wellformed h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h
+ \<Longrightarrow> h \<turnstile> ok (to_tree_order ptr)"
+ assumes to_tree_order_ptrs_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to
+ \<Longrightarrow> ptr' \<in> set to \<Longrightarrow> ptr' |\<in>| object_ptr_kinds h"
+ assumes to_tree_order_parent_child_rel:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to
+ \<Longrightarrow> (ptr, child_ptr) \<in> (parent_child_rel h)\<^sup>* \<longleftrightarrow> child_ptr \<in> set to"
+ assumes to_tree_order_child2:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes
+ \<Longrightarrow> cast child \<noteq> ptr \<Longrightarrow> cast child \<in> set nodes
+ \<Longrightarrow> (\<And>parent. h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some parent
+ \<Longrightarrow> parent \<in> set nodes \<Longrightarrow> thesis)
+ \<Longrightarrow> thesis"
+ assumes to_tree_order_node_ptrs:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes
+ \<Longrightarrow> ptr' \<noteq> ptr \<Longrightarrow> ptr' \<in> set nodes \<Longrightarrow> is_node_ptr_kind ptr'"
+ assumes to_tree_order_child:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes
+ \<Longrightarrow> h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children \<Longrightarrow> cast child \<noteq> ptr
+ \<Longrightarrow> child \<in> set children \<Longrightarrow> cast child \<in> set nodes
+ \<Longrightarrow> parent \<in> set nodes"
+ assumes to_tree_order_ptr_in_result:
+ "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes \<Longrightarrow> ptr \<in> set nodes"
+ assumes to_tree_order_parent:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes
+ \<Longrightarrow> h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some parent \<Longrightarrow> parent \<in> set nodes
+ \<Longrightarrow> cast child \<in> set nodes"
+ assumes to_tree_order_subset:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes \<Longrightarrow> node \<in> set nodes
+ \<Longrightarrow> h \<turnstile> to_tree_order node \<rightarrow>\<^sub>r nodes' \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> type_wf h \<Longrightarrow> set nodes' \<subseteq> set nodes"
+
+lemma to_tree_order_wf_is_l_to_tree_order_wf [instances]:
+ "l_to_tree_order_wf heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ to_tree_order get_parent get_child_nodes"
+ using instances
+ apply(auto simp add: l_to_tree_order_wf_def l_to_tree_order_wf_axioms_def)[1]
+ using to_tree_order_ok
+ apply blast
+ using to_tree_order_ptrs_in_heap
+ apply blast
+ using to_tree_order_parent_child_rel
+ apply(blast, blast)
+ using to_tree_order_child2
+ apply blast
+ using to_tree_order_node_ptrs
+ apply blast
+ using to_tree_order_child
+ apply blast
+ using to_tree_order_ptr_in_result
+ apply blast
+ using to_tree_order_parent
+ apply blast
+ using to_tree_order_subset
+ apply blast
+ done
+
+
+subsubsection \<open>get\_root\_node\<close>
+
+locale l_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + l_to_tree_order_wf
+begin
+lemma to_tree_order_get_root_node:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ assumes "ptr' \<in> set to"
+ assumes "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr"
+ assumes "ptr'' \<in> set to"
+ shows "h \<turnstile> get_root_node ptr'' \<rightarrow>\<^sub>r root_ptr"
+proof -
+ obtain ancestors' where ancestors': "h \<turnstile> get_ancestors ptr' \<rightarrow>\<^sub>r ancestors'"
+ by (meson assms(1) assms(2) assms(3) assms(4) assms(5) get_ancestors_ok is_OK_returns_result_E
+ to_tree_order_ptrs_in_heap )
+ moreover have "ptr \<in> set ancestors'"
+ using \<open>h \<turnstile> get_ancestors ptr' \<rightarrow>\<^sub>r ancestors'\<close>
+ using assms(1) assms(2) assms(3) assms(4) assms(5) get_ancestors_parent_child_rel
+ to_tree_order_parent_child_rel by blast
+
+ ultimately have "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ using \<open>h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr\<close>
+ using assms(1) assms(2) assms(3) get_ancestors_ptr get_ancestors_same_root_node by blast
+
+ obtain ancestors'' where ancestors'': "h \<turnstile> get_ancestors ptr'' \<rightarrow>\<^sub>r ancestors''"
+ by (meson assms(1) assms(2) assms(3) assms(4) assms(7) get_ancestors_ok is_OK_returns_result_E
+ to_tree_order_ptrs_in_heap)
+ moreover have "ptr \<in> set ancestors''"
+ using \<open>h \<turnstile> get_ancestors ptr'' \<rightarrow>\<^sub>r ancestors''\<close>
+ using assms(1) assms(2) assms(3) assms(4) assms(7) get_ancestors_parent_child_rel
+ to_tree_order_parent_child_rel by blast
+ ultimately show ?thesis
+ using \<open>h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr\<close> assms(1) assms(2) assms(3) get_ancestors_ptr
+ get_ancestors_same_root_node by blast
+qed
+
+lemma to_tree_order_same_root:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ assumes "h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r to"
+ assumes "ptr' \<in> set to"
+ shows "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr"
+proof (insert assms(1)(* assms(4) assms(5) *) assms(6), induct ptr' rule: heap_wellformed_induct_rev)
+ case (step child)
+ then show ?case
+ proof (cases "h \<turnstile> get_root_node child \<rightarrow>\<^sub>r child")
+ case True
+ then have "child = root_ptr"
+ using assms(1) assms(2) assms(3) assms(5) step.prems
+ by (metis (no_types, lifting) get_root_node_same_no_parent node_ptr_casts_commute3
+ option.simps(3) returns_result_eq to_tree_order_child2 to_tree_order_node_ptrs)
+ then show ?thesis
+ using True by blast
+ next
+ case False
+ then obtain child_node parent where "cast child_node = child"
+ and "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent"
+ by (metis assms(1) assms(2) assms(3) assms(4) assms(5) local.get_root_node_no_parent
+ local.get_root_node_not_node_same local.get_root_node_same_no_parent
+ local.to_tree_order_child2 local.to_tree_order_ptrs_in_heap node_ptr_casts_commute3
+ step.prems)
+ then show ?thesis
+ proof (cases "child = root_ptr")
+ case True
+ then have "h \<turnstile> get_root_node root_ptr \<rightarrow>\<^sub>r root_ptr"
+ using assms(4)
+ using \<open>cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node = child\<close> assms(1) assms(2) assms(3)
+ get_root_node_no_parent get_root_node_same_no_parent
+ by blast
+ then show ?thesis
+ using step assms(4)
+ using True by blast
+ next
+ case False
+ then have "parent \<in> set to"
+ using assms(5) step(2) to_tree_order_child \<open>h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent\<close>
+ \<open>cast child_node = child\<close>
+ by (metis False assms(1) assms(2) assms(3) get_parent_child_dual)
+ then show ?thesis
+ using \<open>cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node = child\<close> \<open>h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent\<close>
+ get_root_node_parent_same
+ using step.hyps by blast
+ qed
+
+ qed
+qed
+end
+
+interpretation i_to_tree_order_wf_get_root_node_wf?: l_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf known_ptrs heap_is_wellformed parent_child_rel get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_parent get_parent_locs get_ancestors
+ get_ancestors_locs get_root_node get_root_node_locs to_tree_order
+ using instances
+ by(simp add: l_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+
+locale l_to_tree_order_wf_get_root_node_wf = l_type_wf + l_known_ptrs + l_to_tree_order_defs
+ + l_get_root_node_defs + l_heap_is_wellformed_defs +
+ assumes to_tree_order_get_root_node:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to
+ \<Longrightarrow> ptr' \<in> set to \<Longrightarrow> h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr
+ \<Longrightarrow> ptr'' \<in> set to \<Longrightarrow> h \<turnstile> get_root_node ptr'' \<rightarrow>\<^sub>r root_ptr"
+ assumes to_tree_order_same_root:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr
+ \<Longrightarrow> h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r to \<Longrightarrow> ptr' \<in> set to
+ \<Longrightarrow> h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr"
+
+lemma to_tree_order_wf_get_root_node_wf_is_l_to_tree_order_wf_get_root_node_wf [instances]:
+ "l_to_tree_order_wf_get_root_node_wf type_wf known_ptr known_ptrs to_tree_order
+ get_root_node heap_is_wellformed"
+ using instances
+ apply(auto simp add: l_to_tree_order_wf_get_root_node_wf_def
+ l_to_tree_order_wf_get_root_node_wf_axioms_def)[1]
+ using to_tree_order_get_root_node apply blast
+ using to_tree_order_same_root apply blast
+ done
+
+
+subsection \<open>get\_owner\_document\<close>
+
+locale l_get_owner_document_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_known_ptrs
+ + l_heap_is_wellformed
+ + l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + l_get_ancestors
+ + l_get_ancestors_wf
+ + l_get_parent
+ + l_get_parent_wf
+ + l_get_root_node_wf
+ + l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_owner_document_disconnected_nodes:
+ assumes "heap_is_wellformed h"
+ assumes "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes"
+ assumes "node_ptr \<in> set disc_nodes"
+ assumes known_ptrs: "known_ptrs h"
+ assumes type_wf: "type_wf h"
+ shows "h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r document_ptr"
+proof -
+ have 2: "node_ptr |\<in>| node_ptr_kinds h"
+ using assms heap_is_wellformed_disc_nodes_in_heap
+ by blast
+ have 3: "document_ptr |\<in>| document_ptr_kinds h"
+ using assms(2) get_disconnected_nodes_ptr_in_heap by blast
+ have 0:
+ "\<exists>!document_ptr\<in>set |h \<turnstile> document_ptr_kinds_M|\<^sub>r. node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ by (metis (no_types, lifting) "3" DocumentMonad.ptr_kinds_ptr_kinds_M assms(1) assms(2) assms(3)
+ disjoint_iff_not_equal l_heap_is_wellformed.heap_is_wellformed_one_disc_parent
+ local.get_disconnected_nodes_ok local.l_heap_is_wellformed_axioms
+ returns_result_select_result select_result_I2 type_wf)
+
+ have "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r None"
+ using heap_is_wellformed_children_disc_nodes_different child_parent_dual assms
+ using "2" disjoint_iff_not_equal local.get_parent_child_dual local.get_parent_ok
+ returns_result_select_result split_option_ex
+ by (metis (no_types, lifting))
+
+ then have 4: "h \<turnstile> get_root_node (cast node_ptr) \<rightarrow>\<^sub>r cast node_ptr"
+ using 2 get_root_node_no_parent
+ by blast
+ obtain document_ptrs where document_ptrs: "h \<turnstile> document_ptr_kinds_M \<rightarrow>\<^sub>r document_ptrs"
+ by simp
+
+ then
+ have "h \<turnstile> ok (filter_M (\<lambda>document_ptr. do {
+ disconnected_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ return (((cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)) \<in> cast ` set disconnected_nodes)
+ }) document_ptrs)"
+ using assms(1) get_disconnected_nodes_ok type_wf unfolding heap_is_wellformed_def
+ by(auto intro!: bind_is_OK_I2 filter_M_is_OK_I bind_pure_I)
+ then obtain candidates where
+ candidates: "h \<turnstile> filter_M (\<lambda>document_ptr. do {
+ disconnected_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ return (((cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)) \<in> cast ` set disconnected_nodes)
+ }) document_ptrs \<rightarrow>\<^sub>r candidates"
+ by auto
+
+
+ have eq: "\<And>document_ptr. document_ptr |\<in>| document_ptr_kinds h
+ \<Longrightarrow> node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r \<longleftrightarrow> |h \<turnstile> do {
+ disconnected_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ return (((cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)) \<in> cast ` set disconnected_nodes)
+ }|\<^sub>r"
+ apply(auto dest!: get_disconnected_nodes_ok[OF type_wf]
+ intro!: select_result_I[where P=id, simplified] elim!: bind_returns_result_E2)[1]
+ apply(drule select_result_E[where P=id, simplified])
+ by(auto elim!: bind_returns_result_E2)
+
+ have filter: "filter (\<lambda>document_ptr. |h \<turnstile> do {
+ disconnected_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ return (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr \<in> cast ` set disconnected_nodes)
+ }|\<^sub>r) document_ptrs = [document_ptr]"
+ apply(rule filter_ex1)
+ using 0 document_ptrs apply(simp)[1]
+ using eq
+ using local.get_disconnected_nodes_ok apply auto[1]
+ using assms(2) assms(3)
+ apply(auto intro!: intro!: select_result_I[where P=id, simplified]
+ elim!: bind_returns_result_E2)[1]
+ using returns_result_eq apply fastforce
+ using document_ptrs 3 apply(simp)
+ using document_ptrs
+ by simp
+ have "h \<turnstile> filter_M (\<lambda>document_ptr. do {
+ disconnected_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ return (((cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)) \<in> cast ` set disconnected_nodes)
+ }) document_ptrs \<rightarrow>\<^sub>r [document_ptr]"
+ apply(rule filter_M_filter2)
+ using get_disconnected_nodes_ok document_ptrs 3 assms(1) type_wf filter
+ unfolding heap_is_wellformed_def
+ by(auto intro: bind_pure_I bind_is_OK_I2)
+
+ with 4 document_ptrs have "h \<turnstile> a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r document_ptr"
+ by(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ intro!: bind_pure_returns_result_I filter_M_pure_I bind_pure_I
+ split: option.splits)[1]
+ moreover have "known_ptr (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)"
+ using "4" assms(1) known_ptrs type_wf known_ptrs_known_ptr "2" node_ptr_kinds_commutes by blast
+ ultimately show ?thesis
+ using 2
+ apply(auto simp add: known_ptr_impl get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ apply(drule(1) known_ptr_not_document_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ by(auto split: option.splits intro!: bind_pure_returns_result_I)
+qed
+
+lemma in_disconnected_nodes_no_parent:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r None"
+ and "h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r owner_document"
+ and "h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "node_ptr \<in> set disc_nodes"
+proof -
+ have 2: "cast node_ptr |\<in>| object_ptr_kinds h"
+ using assms(3) get_owner_document_ptr_in_heap by fast
+ then have 3: "h \<turnstile> get_root_node (cast node_ptr) \<rightarrow>\<^sub>r cast node_ptr"
+ using assms(2) local.get_root_node_no_parent by blast
+
+ have "\<not>(\<exists>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h \<and> node_ptr \<in> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r)"
+ apply(auto)[1]
+ using assms(2) child_parent_dual[OF assms(1)] type_wf
+ assms(1) assms(5) get_child_nodes_ok known_ptrs_known_ptr option.simps(3)
+ returns_result_eq returns_result_select_result
+ by (metis (no_types, hide_lams))
+ moreover have "node_ptr |\<in>| node_ptr_kinds h"
+ using assms(2) get_parent_ptr_in_heap by blast
+ ultimately
+ have 0: "\<exists>document_ptr\<in>set |h \<turnstile> document_ptr_kinds_M|\<^sub>r. node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ by (metis DocumentMonad.ptr_kinds_ptr_kinds_M assms(1) finite_set_in heap_is_wellformed_children_disc_nodes)
+ then obtain document_ptr where
+ document_ptr: "document_ptr\<in>set |h \<turnstile> document_ptr_kinds_M|\<^sub>r" and
+ node_ptr_in_disc_nodes: "node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ by auto
+ then show ?thesis
+ using get_owner_document_disconnected_nodes known_ptrs type_wf assms
+ using DocumentMonad.ptr_kinds_ptr_kinds_M assms(1) assms(3) assms(4) get_disconnected_nodes_ok
+ returns_result_select_result select_result_I2
+ by (metis (no_types, hide_lams) )
+qed
+
+lemma get_owner_document_owner_document_in_heap:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ shows "owner_document |\<in>| document_ptr_kinds h"
+ using assms
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_split_asm)+
+proof -
+ assume "h \<turnstile> invoke [] ptr () \<rightarrow>\<^sub>r owner_document"
+ then show "owner_document |\<in>| document_ptr_kinds h"
+ by (meson invoke_empty is_OK_returns_result_I)
+next
+ assume "h \<turnstile> Heap_Error_Monad.bind (check_in_heap ptr)
+ (\<lambda>_. (local.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) ptr ())
+ \<rightarrow>\<^sub>r owner_document"
+ then show "owner_document |\<in>| document_ptr_kinds h"
+ by(auto simp add: a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2 split: if_splits)
+next
+ assume 0: "heap_is_wellformed h"
+ and 1: "type_wf h"
+ and 2: "known_ptrs h"
+ and 3: "\<not> is_element_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ and 4: "is_character_data_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ and 5: "h \<turnstile> Heap_Error_Monad.bind (check_in_heap ptr)
+(\<lambda>_. (local.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r) ptr ()) \<rightarrow>\<^sub>r owner_document"
+ then obtain root where
+ root: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ by(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ split: option.splits)
+
+ then show ?thesis
+ proof (cases "is_document_ptr root")
+ case True
+ then show ?thesis
+ using 4 5 root
+ apply(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ intro!: filter_M_pure_I bind_pure_I split: option.splits)[1]
+ apply(drule(1) returns_result_eq) apply(auto)[1]
+ using "0" "1" "2" document_ptr_kinds_commutes local.get_root_node_root_in_heap by blast
+ next
+ case False
+ have "known_ptr root"
+ using "0" "1" "2" local.get_root_node_root_in_heap local.known_ptrs_known_ptr root by blast
+ have "root |\<in>| object_ptr_kinds h"
+ using root
+ using "0" "1" "2" local.get_root_node_root_in_heap
+ by blast
+ then have "is_node_ptr_kind root"
+ using False \<open>known_ptr root\<close>
+ apply(simp add: known_ptr_impl known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs)
+ using is_node_ptr_kind_none by force
+ then
+ have "(\<exists>document_ptr \<in> fset (document_ptr_kinds h). root \<in> cast ` set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)"
+ by (metis (no_types, lifting) "0" "1" "2" \<open>root |\<in>| object_ptr_kinds h\<close> local.child_parent_dual
+ local.get_child_nodes_ok local.get_root_node_same_no_parent local.heap_is_wellformed_children_disc_nodes
+ local.known_ptrs_known_ptr node_ptr_casts_commute3 node_ptr_inclusion node_ptr_kinds_commutes
+ notin_fset option.distinct(1) returns_result_eq returns_result_select_result root)
+ then obtain some_owner_document where
+ "some_owner_document |\<in>| document_ptr_kinds h" and
+ "root \<in> cast ` set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r"
+ by auto
+ then
+ obtain candidates where
+ candidates: "h \<turnstile> filter_M
+ (\<lambda>document_ptr.
+ Heap_Error_Monad.bind (get_disconnected_nodes document_ptr)
+ (\<lambda>disconnected_nodes. return (root \<in> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ` set disconnected_nodes)))
+ (sorted_list_of_set (fset (document_ptr_kinds h)))
+ \<rightarrow>\<^sub>r candidates"
+ by (metis (no_types, lifting) "1" bind_is_OK_I2 bind_pure_I filter_M_is_OK_I finite_fset
+ is_OK_returns_result_E local.get_disconnected_nodes_ok local.get_disconnected_nodes_pure notin_fset
+ return_ok return_pure sorted_list_of_set(1))
+ then have "some_owner_document \<in> set candidates"
+ apply(rule filter_M_in_result_if_ok)
+ using \<open>some_owner_document |\<in>| document_ptr_kinds h\<close>
+ \<open>root \<in> cast ` set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r\<close>
+ apply(auto intro!: bind_pure_I bind_pure_returns_result_I)[1]
+ apply (simp add: \<open>some_owner_document |\<in>| document_ptr_kinds h\<close>)
+ using "1" \<open>root \<in> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ` set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r\<close>
+ \<open>some_owner_document |\<in>| document_ptr_kinds h\<close>
+ local.get_disconnected_nodes_ok by auto
+ then have "candidates \<noteq> []"
+ by auto
+ then have "owner_document \<in> set candidates"
+ using 5 root 4
+ apply(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ intro!: filter_M_pure_I bind_pure_I split: option.splits)[1]
+ apply (metis candidates list.set_sel(1) returns_result_eq)
+ by (metis \<open>is_node_ptr_kind root\<close> node_ptr_no_document_ptr_cast returns_result_eq)
+
+ then show ?thesis
+ using candidates
+ by (meson bind_pure_I bind_returns_result_E2 filter_M_holds_for_result is_OK_returns_result_I
+ local.get_disconnected_nodes_ptr_in_heap local.get_disconnected_nodes_pure return_pure)
+ qed
+next
+ assume 0: "heap_is_wellformed h"
+ and 1: "type_wf h"
+ and 2: "known_ptrs h"
+ and 3: "is_element_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ and 4: "h \<turnstile> Heap_Error_Monad.bind (check_in_heap ptr) (\<lambda>_. (local.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r) ptr ()) \<rightarrow>\<^sub>r owner_document"
+ then obtain root where
+ root: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ by(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2 split: option.splits)
+
+ then show ?thesis
+ proof (cases "is_document_ptr root")
+ case True
+ then show ?thesis
+ using 3 4 root
+ apply(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ intro!: filter_M_pure_I bind_pure_I split: option.splits)[1]
+ apply(drule(1) returns_result_eq) apply(auto)[1]
+ using "0" "1" "2" document_ptr_kinds_commutes local.get_root_node_root_in_heap by blast
+ next
+ case False
+ have "known_ptr root"
+ using "0" "1" "2" local.get_root_node_root_in_heap local.known_ptrs_known_ptr root by blast
+ have "root |\<in>| object_ptr_kinds h"
+ using root
+ using "0" "1" "2" local.get_root_node_root_in_heap
+ by blast
+ then have "is_node_ptr_kind root"
+ using False \<open>known_ptr root\<close>
+ apply(simp add: known_ptr_impl known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs)
+ using is_node_ptr_kind_none by force
+ then
+ have "(\<exists>document_ptr \<in> fset (document_ptr_kinds h). root \<in> cast ` set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)"
+ by (metis (no_types, lifting) "0" "1" "2" \<open>root |\<in>| object_ptr_kinds h\<close>
+ local.child_parent_dual local.get_child_nodes_ok local.get_root_node_same_no_parent
+ local.heap_is_wellformed_children_disc_nodes local.known_ptrs_known_ptr node_ptr_casts_commute3
+ node_ptr_inclusion node_ptr_kinds_commutes notin_fset option.distinct(1) returns_result_eq
+ returns_result_select_result root)
+ then obtain some_owner_document where
+ "some_owner_document |\<in>| document_ptr_kinds h" and
+ "root \<in> cast ` set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r"
+ by auto
+ then
+ obtain candidates where
+ candidates: "h \<turnstile> filter_M
+ (\<lambda>document_ptr.
+ Heap_Error_Monad.bind (get_disconnected_nodes document_ptr)
+ (\<lambda>disconnected_nodes. return (root \<in> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ` set disconnected_nodes)))
+ (sorted_list_of_set (fset (document_ptr_kinds h)))
+ \<rightarrow>\<^sub>r candidates"
+ by (metis (no_types, lifting) "1" bind_is_OK_I2 bind_pure_I filter_M_is_OK_I finite_fset
+ is_OK_returns_result_E local.get_disconnected_nodes_ok local.get_disconnected_nodes_pure notin_fset
+ return_ok return_pure sorted_list_of_set(1))
+ then have "some_owner_document \<in> set candidates"
+ apply(rule filter_M_in_result_if_ok)
+ using \<open>some_owner_document |\<in>| document_ptr_kinds h\<close>
+ \<open>root \<in> cast ` set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r\<close>
+ apply(auto intro!: bind_pure_I bind_pure_returns_result_I)[1]
+ apply (simp add: \<open>some_owner_document |\<in>| document_ptr_kinds h\<close>)
+ using "1" \<open>root \<in> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ` set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r\<close>
+ \<open>some_owner_document |\<in>| document_ptr_kinds h\<close> local.get_disconnected_nodes_ok
+ by auto
+
+ then have "candidates \<noteq> []"
+ by auto
+ then have "owner_document \<in> set candidates"
+ using 4 root 3
+ apply(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ intro!: filter_M_pure_I bind_pure_I split: option.splits)[1]
+ apply (metis candidates list.set_sel(1) returns_result_eq)
+ by (metis \<open>is_node_ptr_kind root\<close> node_ptr_no_document_ptr_cast returns_result_eq)
+
+ then show ?thesis
+ using candidates
+ by (meson bind_pure_I bind_returns_result_E2 filter_M_holds_for_result is_OK_returns_result_I
+ local.get_disconnected_nodes_ptr_in_heap local.get_disconnected_nodes_pure return_pure)
+ qed
+qed
+
+lemma get_owner_document_ok:
+ assumes "heap_is_wellformed h" "known_ptrs h" "type_wf h"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ shows "h \<turnstile> ok (get_owner_document ptr)"
+proof -
+ have "known_ptr ptr"
+ using assms(2) assms(4) local.known_ptrs_known_ptr
+ by blast
+ then show ?thesis
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ apply(auto simp add: known_ptr_impl)[1]
+ using NodeClass.a_known_ptr_def known_ptr_not_character_data_ptr known_ptr_not_document_ptr
+ known_ptr_not_element_ptr
+ apply blast
+ using assms(4)
+ apply(auto simp add: a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ intro!: bind_is_OK_pure_I)[1]
+ apply (metis (no_types, lifting) document_ptr_casts_commute3 document_ptr_kinds_commutes
+ is_document_ptr_kind_none option.case_eq_if)
+ using assms(4)
+ apply(auto simp add: a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ intro!: bind_is_OK_pure_I)[1]
+ apply (metis (no_types, lifting) assms(1) assms(2) assms(3) is_node_ptr_kind_none
+ local.get_root_node_ok node_ptr_casts_commute3 option.case_eq_if)
+ using assms(4)
+ apply(auto simp add: a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ intro!: bind_is_OK_pure_I)[1]
+ apply(auto split: option.splits intro!: bind_is_OK_pure_I filter_M_pure_I bind_pure_I
+ filter_M_is_OK_I)[1]
+ using assms(3) local.get_disconnected_nodes_ok
+ apply blast
+ apply (simp add: assms(1) assms(2) assms(3) local.get_root_node_ok)
+ using assms(4)
+ apply(auto simp add: a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ intro!: bind_is_OK_pure_I)[1]
+ apply(auto split: option.splits intro!: bind_is_OK_pure_I filter_M_pure_I bind_pure_I
+ filter_M_is_OK_I)[1]
+ apply (simp add: assms(1) assms(2) assms(3) local.get_root_node_ok)[1]
+ apply(auto split: option.splits intro!: bind_is_OK_pure_I filter_M_pure_I bind_pure_I
+ filter_M_is_OK_I)[1]
+ using assms(3) local.get_disconnected_nodes_ok by blast
+qed
+
+lemma get_owner_document_child_same:
+ assumes "heap_is_wellformed h" "known_ptrs h" "type_wf h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assumes "child \<in> set children"
+ shows "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<longleftrightarrow> h \<turnstile> get_owner_document (cast child) \<rightarrow>\<^sub>r owner_document"
+proof -
+ have "ptr |\<in>| object_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_result_I local.get_child_nodes_ptr_in_heap)
+ then have "known_ptr ptr"
+ using assms(2) local.known_ptrs_known_ptr by blast
+
+ have "cast child |\<in>| object_ptr_kinds h"
+ using assms(1) assms(4) assms(5) local.heap_is_wellformed_children_in_heap node_ptr_kinds_commutes
+ by blast
+ then
+ have "known_ptr (cast child)"
+ using assms(2) local.known_ptrs_known_ptr by blast
+
+ obtain root where root: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ by (meson \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) is_OK_returns_result_E
+ local.get_root_node_ok)
+ then have "h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root"
+ using assms(1) assms(2) assms(3) assms(4) assms(5) local.child_parent_dual
+ local.get_root_node_parent_same
+ by blast
+
+ have "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<longleftrightarrow>
+h \<turnstile> a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child () \<rightarrow>\<^sub>r owner_document"
+ proof (cases "is_document_ptr ptr")
+ case True
+ then obtain document_ptr where document_ptr: "cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr = ptr"
+ using case_optionE document_ptr_casts_commute by blast
+ then have "root = cast document_ptr"
+ using root
+ by(auto simp add: get_root_node_def get_ancestors_def elim!: bind_returns_result_E2
+ split: option.splits)
+
+ then have "h \<turnstile> a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr () \<rightarrow>\<^sub>r owner_document \<longleftrightarrow>
+h \<turnstile> a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child () \<rightarrow>\<^sub>r owner_document"
+ using document_ptr
+ \<open>h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root\<close>[simplified \<open>root = cast document_ptr\<close> document_ptr]
+ apply(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ elim!: bind_returns_result_E2 dest!: bind_returns_result_E3[rotated,
+ OF \<open>h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root\<close>[simplified \<open>root = cast document_ptr\<close> document_ptr], rotated]
+ intro!: bind_pure_returns_result_I filter_M_pure_I bind_pure_I split: if_splits option.splits)[1]
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> document_ptr_kinds_commutes by blast
+ then show ?thesis
+ using \<open>known_ptr ptr\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def known_ptr_impl)[1]
+ apply(split invoke_splits, ((rule conjI | rule impI)+)?)+
+ apply(drule(1) known_ptr_not_document_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> True
+ by(auto simp add: document_ptr[symmetric] intro!: bind_pure_returns_result_I
+ split: option.splits)
+ next
+ case False
+ then obtain node_ptr where node_ptr: "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = ptr"
+ using \<open>known_ptr ptr\<close>
+ by(auto simp add: known_ptr_impl DocumentClass.known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+ then have "h \<turnstile> a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document \<longleftrightarrow>
+h \<turnstile> a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child () \<rightarrow>\<^sub>r owner_document"
+ using root \<open>h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root\<close>
+ unfolding a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by (meson bind_pure_returns_result_I bind_returns_result_E3 local.get_root_node_pure)
+ then show ?thesis
+ using \<open>known_ptr ptr\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def known_ptr_impl)[1]
+ apply(split invoke_splits, ((rule conjI | rule impI)+)?)+
+ apply(drule(1) known_ptr_not_document_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close> False
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close> False
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close> False
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close> False
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ apply(split invoke_splits, ((rule conjI | rule impI)+)?)+
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ apply (meson invoke_empty is_OK_returns_result_I)
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ by(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ qed
+ then show ?thesis
+ using \<open>known_ptr (cast child)\<close>
+ apply(auto simp add: get_owner_document_def[of "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child"]
+ a_get_owner_document_tups_def known_ptr_impl)[1]
+ apply(split invoke_splits, ((rule conjI | rule impI)+)?)+
+ apply(drule(1) known_ptr_not_document_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close>
+ apply(auto intro!: bind_pure_returns_result_I split: option.splits)[1]
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close>
+ apply(auto intro!: bind_pure_returns_result_I split: option.splits)[1]
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close>
+ apply(auto intro!: bind_pure_returns_result_I split: option.splits)[1]
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close>
+ apply(auto intro!: bind_pure_returns_result_I split: option.splits)[1]
+ by (smt \<open>cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child |\<in>| object_ptr_kinds h\<close> cast_document_ptr_not_node_ptr(1)
+ comp_apply invoke_empty invoke_not invoke_returns_result is_OK_returns_result_I
+ node_ptr_casts_commute2 option.sel)
+qed
+
+end
+
+locale l_get_owner_document_wf = l_heap_is_wellformed_defs + l_type_wf + l_known_ptrs
+ + l_get_disconnected_nodes_defs + l_get_owner_document_defs
+ + l_get_parent_defs + l_get_child_nodes_defs +
+ assumes get_owner_document_disconnected_nodes:
+ "heap_is_wellformed h \<Longrightarrow>
+ known_ptrs h \<Longrightarrow>
+ type_wf h \<Longrightarrow>
+ h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes \<Longrightarrow>
+ node_ptr \<in> set disc_nodes \<Longrightarrow>
+ h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r document_ptr"
+ assumes in_disconnected_nodes_no_parent:
+ "heap_is_wellformed h \<Longrightarrow>
+ h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r None\<Longrightarrow>
+ h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r owner_document \<Longrightarrow>
+ h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes \<Longrightarrow>
+ known_ptrs h \<Longrightarrow>
+ type_wf h\<Longrightarrow>
+ node_ptr \<in> set disc_nodes"
+ assumes get_owner_document_owner_document_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow>
+h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<Longrightarrow>
+owner_document |\<in>| document_ptr_kinds h"
+ assumes get_owner_document_ok:
+ "heap_is_wellformed h \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h
+ \<Longrightarrow> h \<turnstile> ok (get_owner_document ptr)"
+ assumes get_owner_document_child_same:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow>
+child \<in> set children \<Longrightarrow> h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<longleftrightarrow>
+h \<turnstile> get_owner_document (cast child) \<rightarrow>\<^sub>r owner_document"
+
+interpretation i_get_owner_document_wf?: l_get_owner_document_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr known_ptrs type_wf heap_is_wellformed parent_child_rel get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_parent get_parent_locs get_ancestors
+ get_ancestors_locs get_root_node get_root_node_locs get_owner_document
+ by(auto simp add: l_get_owner_document_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_owner_document_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_owner_document_wf_is_l_get_owner_document_wf [instances]:
+ "l_get_owner_document_wf heap_is_wellformed type_wf known_ptr known_ptrs get_disconnected_nodes
+ get_owner_document get_parent get_child_nodes"
+ using known_ptrs_is_l_known_ptrs
+ apply(auto simp add: l_get_owner_document_wf_def l_get_owner_document_wf_axioms_def)[1]
+ using get_owner_document_disconnected_nodes apply fast
+ using in_disconnected_nodes_no_parent apply fast
+ using get_owner_document_owner_document_in_heap apply fast
+ using get_owner_document_ok apply fast
+ using get_owner_document_child_same apply (fast, fast)
+ done
+
+
+subsubsection \<open>get\_root\_node\<close>
+
+locale l_get_owner_document_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_root_node_wf +
+ l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_owner_document_wf
+begin
+
+lemma get_root_node_document:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ assumes "is_document_ptr_kind root"
+ shows "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r the (cast root)"
+proof -
+ have "ptr |\<in>| object_ptr_kinds h"
+ using assms(4)
+ by (meson is_OK_returns_result_I local.get_root_node_ptr_in_heap)
+ then have "known_ptr ptr"
+ using assms(3) local.known_ptrs_known_ptr by blast
+ {
+ assume "is_document_ptr_kind ptr"
+ then have "ptr = root"
+ using assms(4)
+ by(auto simp add: get_root_node_def get_ancestors_def elim!: bind_returns_result_E2
+ split: option.splits)
+ then have ?thesis
+ using \<open>is_document_ptr_kind ptr\<close> \<open>known_ptr ptr\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close>
+ apply(auto simp add: known_ptr_impl get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ apply(drule(1) known_ptr_not_document_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ by(auto simp add: a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: bind_pure_returns_result_I
+ split: option.splits)
+ }
+ moreover
+ {
+ assume "is_node_ptr_kind ptr"
+ then have ?thesis
+ using \<open>known_ptr ptr\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close>
+ apply(auto simp add: known_ptr_impl get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ apply(drule(1) known_ptr_not_document_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ apply(auto split: option.splits)[1]
+ using \<open>h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root\<close> assms(5)
+ by(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def is_document_ptr_kind_def
+ intro!: bind_pure_returns_result_I split: option.splits)[2]
+ }
+ ultimately
+ show ?thesis
+ using \<open>known_ptr ptr\<close>
+ by(auto simp add: known_ptr_impl DocumentClass.known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+qed
+
+lemma get_root_node_same_owner_document:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ shows "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<longleftrightarrow> h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document"
+proof -
+ have "ptr |\<in>| object_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_result_I local.get_root_node_ptr_in_heap)
+ have "root |\<in>| object_ptr_kinds h"
+ using assms(1) assms(2) assms(3) assms(4) local.get_root_node_root_in_heap by blast
+ have "known_ptr ptr"
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(3) local.known_ptrs_known_ptr by blast
+ have "known_ptr root"
+ using \<open>root |\<in>| object_ptr_kinds h\<close> assms(3) local.known_ptrs_known_ptr by blast
+ show ?thesis
+ proof (cases "is_document_ptr_kind ptr")
+ case True
+ then
+ have "ptr = root"
+ using assms(4)
+ apply(auto simp add: get_root_node_def elim!: bind_returns_result_E2)[1]
+ by (metis document_ptr_casts_commute3 last_ConsL local.get_ancestors_not_node node_ptr_no_document_ptr_cast)
+ then show ?thesis
+ by auto
+ next
+ case False
+ then have "is_node_ptr_kind ptr"
+ using \<open>known_ptr ptr\<close>
+ by(auto simp add: known_ptr_impl DocumentClass.known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+ then obtain node_ptr where node_ptr: "ptr = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr"
+ by (metis node_ptr_casts_commute3)
+ show ?thesis
+ proof
+ assume "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ then have "h \<turnstile> local.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document"
+ using node_ptr
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits)+
+ apply (meson invoke_empty is_OK_returns_result_I)
+ by(auto elim!: bind_returns_result_E2 split: option.splits)
+
+ show "h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document"
+ proof (cases "is_document_ptr_kind root")
+ case True
+ have "is_document_ptr root"
+ using True \<open>known_ptr root\<close>
+ by(auto simp add: known_ptr_impl DocumentClass.known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+ have "root = cast owner_document"
+ using True
+ by (smt \<open>h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document\<close> assms(1) assms(2) assms(3) assms(4)
+ document_ptr_casts_commute3 get_root_node_document returns_result_eq)
+ then show ?thesis
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ using \<open>is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root\<close> apply blast
+ using \<open>root |\<in>| object_ptr_kinds h\<close>
+ by(auto simp add: a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def is_node_ptr_kind_none)
+
+ next
+ case False
+ then have "is_node_ptr_kind root"
+ using \<open>known_ptr root\<close>
+ by(auto simp add: known_ptr_impl DocumentClass.known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+ then obtain root_node_ptr where root_node_ptr: "root = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node_ptr"
+ by (metis node_ptr_casts_commute3)
+ then have "h \<turnstile> local.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node_ptr () \<rightarrow>\<^sub>r owner_document"
+ using \<open>h \<turnstile> local.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document\<close> assms(4)
+ apply(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ intro!: bind_pure_returns_result_I filter_M_pure_I bind_pure_I split: option.splits)[1]
+ apply (metis assms(1) assms(2) assms(3) local.get_root_node_no_parent
+ local.get_root_node_same_no_parent node_ptr returns_result_eq)
+ using \<open>is_node_ptr_kind root\<close> node_ptr returns_result_eq by fastforce
+ then show ?thesis
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ using \<open>is_node_ptr_kind root\<close> \<open>known_ptr root\<close>
+ apply(auto simp add: known_ptr_impl DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ split: option.splits)[1]
+ apply(auto simp add: known_ptr_impl DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ split: option.splits)[1]
+ using \<open>root |\<in>| object_ptr_kinds h\<close>
+ by(auto simp add: root_node_ptr)
+ qed
+ next
+ assume "h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document"
+ show "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ proof (cases "is_document_ptr_kind root")
+ case True
+ have "root = cast owner_document"
+ using \<open>h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits)+
+ apply (meson invoke_empty is_OK_returns_result_I)
+ apply(auto simp add: True a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ split: if_splits)[1]
+ apply (metis True cast_document_ptr_not_node_ptr(2) is_document_ptr_kind_obtains
+ is_node_ptr_kind_none node_ptr_casts_commute3 option.case_eq_if)
+ by (metis True cast_document_ptr_not_node_ptr(1) document_ptr_casts_commute3
+ is_node_ptr_kind_none node_ptr_casts_commute3 option.case_eq_if)
+ then show ?thesis
+ using assms(1) assms(2) assms(3) assms(4) get_root_node_document
+ by fastforce
+ next
+ case False
+ then have "is_node_ptr_kind root"
+ using \<open>known_ptr root\<close>
+ by(auto simp add: known_ptr_impl DocumentClass.known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+ then obtain root_node_ptr where root_node_ptr: "root = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node_ptr"
+ by (metis node_ptr_casts_commute3)
+ then have "h \<turnstile> local.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node_ptr () \<rightarrow>\<^sub>r owner_document"
+ using \<open>h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits)+
+ apply (meson invoke_empty is_OK_returns_result_I)
+ by(auto simp add: is_document_ptr_kind_none elim!: bind_returns_result_E2)
+ then have "h \<turnstile> local.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document"
+ apply(auto simp add: a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ intro!: bind_pure_returns_result_I filter_M_pure_I bind_pure_I split: option.splits)[1]
+ using assms(1) assms(2) assms(3) assms(4) local.get_root_node_no_parent
+ local.get_root_node_same_no_parent node_ptr returns_result_eq root_node_ptr
+ by fastforce+
+ then show ?thesis
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ using node_ptr \<open>known_ptr ptr\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close>
+
+ by(auto simp add: known_ptr_impl DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ intro!: bind_pure_returns_result_I split: option.splits)
+ qed
+ qed
+ qed
+qed
+end
+
+interpretation get_owner_document_wf_get_root_node_wf?: l_get_owner_document_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_ancestors get_ancestors_locs get_root_node get_root_node_locs heap_is_wellformed
+ parent_child_rel get_disconnected_nodes get_disconnected_nodes_locs get_owner_document
+ by(auto simp add: l_get_owner_document_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_owner_document_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+locale l_get_owner_document_wf_get_root_node_wf = l_heap_is_wellformed_defs + l_type_wf +
+ l_known_ptrs + l_get_root_node_defs + l_get_owner_document_defs +
+ assumes get_root_node_document:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root \<Longrightarrow>
+is_document_ptr_kind root \<Longrightarrow> h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r the (cast root)"
+ assumes get_root_node_same_owner_document:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root \<Longrightarrow>
+h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<longleftrightarrow> h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document"
+
+lemma get_owner_document_wf_get_root_node_wf_is_l_get_owner_document_wf_get_root_node_wf [instances]:
+ "l_get_owner_document_wf_get_root_node_wf heap_is_wellformed type_wf known_ptr known_ptrs
+get_root_node get_owner_document"
+ apply(auto simp add: l_get_owner_document_wf_get_root_node_wf_def
+ l_get_owner_document_wf_get_root_node_wf_axioms_def instances)[1]
+ using get_root_node_document apply blast
+ using get_root_node_same_owner_document apply (blast, blast)
+ done
+
+
+subsection \<open>Preserving heap-wellformedness\<close>
+
+subsection \<open>set\_attribute\<close>
+
+locale l_set_attribute_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_attribute\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_attribute_get_disconnected_nodes +
+ l_set_attribute_get_child_nodes
+begin
+lemma set_attribute_preserves_wellformedness:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> set_attribute element_ptr k v \<rightarrow>\<^sub>h h'"
+ shows "heap_is_wellformed h'"
+ thm preserves_wellformedness_writes_needed
+ apply(rule preserves_wellformedness_writes_needed[OF assms set_attribute_writes])
+ using set_attribute_get_child_nodes
+ apply(fast)
+ using set_attribute_get_disconnected_nodes apply(fast)
+ by(auto simp add: all_args_def set_attribute_locs_def)
+end
+
+
+subsection \<open>remove\_child\<close>
+
+locale l_remove_child_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_heap_is_wellformed +
+ l_set_disconnected_nodes_get_child_nodes
+begin
+lemma remove_child_removes_parent:
+ assumes wellformed: "heap_is_wellformed h"
+ and remove_child: "h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h2"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "h2 \<turnstile> get_parent child \<rightarrow>\<^sub>r None"
+proof -
+ obtain children where children: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using remove_child remove_child_def by auto
+ then have "child \<in> set children"
+ using remove_child remove_child_def
+ by(auto elim!: bind_returns_heap_E dest: returns_result_eq split: if_splits)
+ then have h1: "\<And>other_ptr other_children. other_ptr \<noteq> ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes other_ptr \<rightarrow>\<^sub>r other_children \<Longrightarrow> child \<notin> set other_children"
+ using assms(1) known_ptrs type_wf child_parent_dual
+ by (meson child_parent_dual children option.inject returns_result_eq)
+
+ have known_ptr: "known_ptr ptr"
+ using known_ptrs
+ by (meson is_OK_returns_heap_I l_known_ptrs.known_ptrs_known_ptr l_known_ptrs_axioms
+ remove_child remove_child_ptr_in_heap)
+
+ obtain owner_document disc_nodes h' where
+ owner_document: "h \<turnstile> get_owner_document (cast child) \<rightarrow>\<^sub>r owner_document" and
+ disc_nodes: "h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes" and
+ h': "h \<turnstile> set_disconnected_nodes owner_document (child # disc_nodes) \<rightarrow>\<^sub>h h'" and
+ h2: "h' \<turnstile> set_child_nodes ptr (remove1 child children) \<rightarrow>\<^sub>h h2"
+ using assms children unfolding remove_child_def
+ apply(auto split: if_splits elim!: bind_returns_heap_E)[1]
+ by (metis (full_types) get_child_nodes_pure get_disconnected_nodes_pure
+ get_owner_document_pure pure_returns_heap_eq returns_result_eq)
+
+ have "object_ptr_kinds h = object_ptr_kinds h2"
+ using remove_child_writes remove_child unfolding remove_child_locs_def
+ apply(rule writes_small_big)
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by(auto simp add: reflp_def transp_def)
+ then have "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ unfolding object_ptr_kinds_M_defs by simp
+
+ have "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'",
+ OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved type_wf
+ by(auto simp add: reflp_def transp_def)
+ have "type_wf h2"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'",
+ OF remove_child_writes remove_child] unfolding remove_child_locs_def
+ using set_disconnected_nodes_types_preserved set_child_nodes_types_preserved type_wf
+ apply(auto simp add: reflp_def transp_def)[1]
+ by blast
+ then obtain children' where children': "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'"
+ using h2 set_child_nodes_get_child_nodes known_ptr
+ by (metis \<open>object_ptr_kinds h = object_ptr_kinds h2\<close> children get_child_nodes_ok
+ get_child_nodes_ptr_in_heap is_OK_returns_result_E is_OK_returns_result_I)
+
+ have "child \<notin> set children'"
+ by (metis (mono_tags, lifting) \<open>type_wf h'\<close> children children' distinct_remove1_removeAll h2
+ known_ptr local.heap_is_wellformed_children_distinct
+ local.set_child_nodes_get_child_nodes member_remove remove_code(1) select_result_I2
+ wellformed)
+
+
+ moreover have "\<And>other_ptr other_children. other_ptr \<noteq> ptr
+ \<Longrightarrow> h' \<turnstile> get_child_nodes other_ptr \<rightarrow>\<^sub>r other_children \<Longrightarrow> child \<notin> set other_children"
+ proof -
+ fix other_ptr other_children
+ assume a1: "other_ptr \<noteq> ptr" and a3: "h' \<turnstile> get_child_nodes other_ptr \<rightarrow>\<^sub>r other_children"
+ have "h \<turnstile> get_child_nodes other_ptr \<rightarrow>\<^sub>r other_children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h' a3
+ apply(rule reads_writes_separate_backwards)
+ using set_disconnected_nodes_get_child_nodes by fast
+ show "child \<notin> set other_children"
+ using \<open>h \<turnstile> get_child_nodes other_ptr \<rightarrow>\<^sub>r other_children\<close> a1 h1 by blast
+ qed
+ then have "\<And>other_ptr other_children. other_ptr \<noteq> ptr
+ \<Longrightarrow> h2 \<turnstile> get_child_nodes other_ptr \<rightarrow>\<^sub>r other_children \<Longrightarrow> child \<notin> set other_children"
+ proof -
+ fix other_ptr other_children
+ assume a1: "other_ptr \<noteq> ptr" and a3: "h2 \<turnstile> get_child_nodes other_ptr \<rightarrow>\<^sub>r other_children"
+ have "h' \<turnstile> get_child_nodes other_ptr \<rightarrow>\<^sub>r other_children"
+ using get_child_nodes_reads set_child_nodes_writes h2 a3
+ apply(rule reads_writes_separate_backwards)
+ using set_disconnected_nodes_get_child_nodes a1 set_child_nodes_get_child_nodes_different_pointers
+ by metis
+ then show "child \<notin> set other_children"
+ using \<open>\<And>other_ptr other_children. \<lbrakk>other_ptr \<noteq> ptr; h' \<turnstile> get_child_nodes other_ptr \<rightarrow>\<^sub>r other_children\<rbrakk>
+ \<Longrightarrow> child \<notin> set other_children\<close> a1 by blast
+ qed
+ ultimately have ha: "\<And>other_ptr other_children. h2 \<turnstile> get_child_nodes other_ptr \<rightarrow>\<^sub>r other_children
+ \<Longrightarrow> child \<notin> set other_children"
+ by (metis (full_types) children' returns_result_eq)
+ moreover obtain ptrs where ptrs: "h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by (simp add: object_ptr_kinds_M_defs)
+ moreover have "\<And>ptr. ptr \<in> set ptrs \<Longrightarrow> h2 \<turnstile> ok (get_child_nodes ptr)"
+ using \<open>type_wf h2\<close> ptrs get_child_nodes_ok known_ptr
+ using \<open>object_ptr_kinds h = object_ptr_kinds h2\<close> known_ptrs local.known_ptrs_known_ptr by auto
+ ultimately show "h2 \<turnstile> get_parent child \<rightarrow>\<^sub>r None"
+ apply(auto simp add: get_parent_def intro!: bind_pure_returns_result_I filter_M_pure_I bind_pure_I)[1]
+ proof -
+ have "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child |\<in>| object_ptr_kinds h"
+ using get_owner_document_ptr_in_heap owner_document by blast
+ then show "h2 \<turnstile> check_in_heap (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r ()"
+ by (simp add: \<open>object_ptr_kinds h = object_ptr_kinds h2\<close> check_in_heap_def)
+ next
+ show "(\<And>other_ptr other_children. h2 \<turnstile> get_child_nodes other_ptr \<rightarrow>\<^sub>r other_children
+ \<Longrightarrow> child \<notin> set other_children) \<Longrightarrow>
+ ptrs = sorted_list_of_set (fset (object_ptr_kinds h2)) \<Longrightarrow>
+ (\<And>ptr. ptr |\<in>| object_ptr_kinds h2 \<Longrightarrow> h2 \<turnstile> ok get_child_nodes ptr) \<Longrightarrow>
+ h2 \<turnstile> filter_M (\<lambda>ptr. Heap_Error_Monad.bind (get_child_nodes ptr)
+ (\<lambda>children. return (child \<in> set children))) (sorted_list_of_set (fset (object_ptr_kinds h2))) \<rightarrow>\<^sub>r []"
+ by(auto intro!: filter_M_empty_I bind_pure_I)
+ qed
+qed
+end
+
+locale l_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_remove_child_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma remove_child_parent_child_rel_subset:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h'"
+ and "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "parent_child_rel h' \<subseteq> parent_child_rel h"
+proof (standard, safe)
+
+ obtain owner_document children_h h2 disconnected_nodes_h where
+ owner_document: "h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r owner_document" and
+ children_h: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children_h" and
+ child_in_children_h: "child \<in> set children_h" and
+ disconnected_nodes_h: "h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disconnected_nodes_h" and
+ h2: "h \<turnstile> set_disconnected_nodes owner_document (child # disconnected_nodes_h) \<rightarrow>\<^sub>h h2" and
+ h': "h2 \<turnstile> set_child_nodes ptr (remove1 child children_h) \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ apply(auto simp add: remove_child_def elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_child_nodes_pure]
+ split: if_splits)[1]
+ using pure_returns_heap_eq by fastforce
+ have object_ptr_kinds_eq3: "object_ptr_kinds h = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF remove_child_writes assms(2)])
+ unfolding remove_child_locs_def
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_eq: "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ unfolding object_ptr_kinds_M_defs by simp
+ then have object_ptr_kinds_eq2: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ using select_result_eq by force
+ then have node_ptr_kinds_eq2: "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by auto
+ then have node_ptr_kinds_eq3: "node_ptr_kinds h = node_ptr_kinds h'"
+ using node_ptr_kinds_M_eq by auto
+ have document_ptr_kinds_eq2: "|h \<turnstile> document_ptr_kinds_M|\<^sub>r = |h' \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq2 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3: "document_ptr_kinds h = document_ptr_kinds h'"
+ using document_ptr_kinds_M_eq by auto
+ have children_eq:
+ "\<And>ptr' children. ptr \<noteq> ptr' \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ apply(rule reads_writes_preserved[OF get_child_nodes_reads remove_child_writes assms(2)])
+ unfolding remove_child_locs_def
+ using set_disconnected_nodes_get_child_nodes set_child_nodes_get_child_nodes_different_pointers
+ by fast
+ then have children_eq2:
+ "\<And>ptr' children. ptr \<noteq> ptr' \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq:
+ "\<And>document_ptr disconnected_nodes. document_ptr \<noteq> owner_document
+ \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disconnected_nodes
+ = h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disconnected_nodes"
+ apply(rule reads_writes_preserved[OF get_disconnected_nodes_reads remove_child_writes assms(2)])
+ unfolding remove_child_locs_def
+ using set_child_nodes_get_disconnected_nodes set_disconnected_nodes_get_disconnected_nodes_different_pointers
+ by (metis (no_types, lifting) Un_iff owner_document select_result_I2)
+ then have disconnected_nodes_eq2:
+ "\<And>document_ptr. document_ptr \<noteq> owner_document
+ \<Longrightarrow> |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children_h"
+ apply(rule reads_writes_separate_forwards[OF get_child_nodes_reads set_disconnected_nodes_writes h2 children_h] )
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+
+ have "known_ptr ptr"
+ using assms(3)
+ using children_h get_child_nodes_ptr_in_heap local.known_ptrs_known_ptr by blast
+ have "type_wf h2"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h2]
+ using set_disconnected_nodes_types_preserved type_wf
+ by(auto simp add: reflp_def transp_def)
+ then have "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_child_nodes_writes h']
+ using set_child_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_h': "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r remove1 child children_h"
+ using assms(2) owner_document h2 disconnected_nodes_h children_h
+ apply(auto simp add: remove_child_def split: if_splits)[1]
+ apply(drule bind_returns_heap_E3)
+ apply(auto split: if_splits)[1]
+ apply(simp)
+ apply(auto split: if_splits)[1]
+ apply(drule bind_returns_heap_E3)
+ apply(auto)[1]
+ apply(simp)
+ apply(drule bind_returns_heap_E3)
+ apply(auto)[1]
+ apply(simp)
+ apply(drule bind_returns_heap_E4)
+ apply(auto)[1]
+ apply(simp)
+ using \<open>type_wf h2\<close> set_child_nodes_get_child_nodes \<open>known_ptr ptr\<close> h'
+ by blast
+
+ fix parent child
+ assume a1: "(parent, child) \<in> parent_child_rel h'"
+ then show "(parent, child) \<in> parent_child_rel h"
+ proof (cases "parent = ptr")
+ case True
+ then show ?thesis
+ using a1 remove_child_removes_parent[OF assms(1) assms(2)] children_h children_h'
+ get_child_nodes_ptr_in_heap
+ apply(auto simp add: parent_child_rel_def object_ptr_kinds_eq )[1]
+ by (metis notin_set_remove1)
+ next
+ case False
+ then show ?thesis
+ using a1
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq3 children_eq2)
+ qed
+qed
+
+
+lemma remove_child_heap_is_wellformed_preserved:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h'"
+ and "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "type_wf h'" and "known_ptrs h'" and "heap_is_wellformed h'"
+proof -
+ obtain owner_document children_h h2 disconnected_nodes_h where
+ owner_document: "h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r owner_document" and
+ children_h: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children_h" and
+ child_in_children_h: "child \<in> set children_h" and
+ disconnected_nodes_h: "h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disconnected_nodes_h" and
+ h2: "h \<turnstile> set_disconnected_nodes owner_document (child # disconnected_nodes_h) \<rightarrow>\<^sub>h h2" and
+ h': "h2 \<turnstile> set_child_nodes ptr (remove1 child children_h) \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ apply(auto simp add: remove_child_def elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_child_nodes_pure] split: if_splits)[1]
+ using pure_returns_heap_eq by fastforce
+
+ have object_ptr_kinds_eq3: "object_ptr_kinds h = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF remove_child_writes assms(2)])
+ unfolding remove_child_locs_def
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_eq: "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ unfolding object_ptr_kinds_M_defs by simp
+ then have object_ptr_kinds_eq2: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ using select_result_eq by force
+ then have node_ptr_kinds_eq2: "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by auto
+ then have node_ptr_kinds_eq3: "node_ptr_kinds h = node_ptr_kinds h'"
+ using node_ptr_kinds_M_eq by auto
+ have document_ptr_kinds_eq2: "|h \<turnstile> document_ptr_kinds_M|\<^sub>r = |h' \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq2 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3: "document_ptr_kinds h = document_ptr_kinds h'"
+ using document_ptr_kinds_M_eq by auto
+ have children_eq:
+ "\<And>ptr' children. ptr \<noteq> ptr' \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children =
+h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ apply(rule reads_writes_preserved[OF get_child_nodes_reads remove_child_writes assms(2)])
+ unfolding remove_child_locs_def
+ using set_disconnected_nodes_get_child_nodes set_child_nodes_get_child_nodes_different_pointers
+ by fast
+ then have children_eq2:
+ "\<And>ptr' children. ptr \<noteq> ptr' \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq: "\<And>document_ptr disconnected_nodes. document_ptr \<noteq> owner_document
+ \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disconnected_nodes
+ = h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disconnected_nodes"
+ apply(rule reads_writes_preserved[OF get_disconnected_nodes_reads remove_child_writes assms(2)])
+ unfolding remove_child_locs_def
+ using set_child_nodes_get_disconnected_nodes
+ set_disconnected_nodes_get_disconnected_nodes_different_pointers
+ by (metis (no_types, lifting) Un_iff owner_document select_result_I2)
+ then have disconnected_nodes_eq2:
+ "\<And>document_ptr. document_ptr \<noteq> owner_document
+ \<Longrightarrow> |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children_h"
+ apply(rule reads_writes_separate_forwards[OF get_child_nodes_reads
+ set_disconnected_nodes_writes h2 children_h] )
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+
+ show "known_ptrs h'"
+ using object_ptr_kinds_eq3 known_ptrs_preserved \<open>known_ptrs h\<close> by blast
+
+ have "known_ptr ptr"
+ using assms(3)
+ using children_h get_child_nodes_ptr_in_heap local.known_ptrs_known_ptr by blast
+ have "type_wf h2"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'",
+ OF set_disconnected_nodes_writes h2]
+ using set_disconnected_nodes_types_preserved type_wf
+ by(auto simp add: reflp_def transp_def)
+ then show "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_child_nodes_writes h']
+ using set_child_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_h': "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r remove1 child children_h"
+ using assms(2) owner_document h2 disconnected_nodes_h children_h
+ apply(auto simp add: remove_child_def split: if_splits)[1]
+ apply(drule bind_returns_heap_E3)
+ apply(auto split: if_splits)[1]
+ apply(simp)
+ apply(auto split: if_splits)[1]
+ apply(drule bind_returns_heap_E3)
+ apply(auto)[1]
+ apply(simp)
+ apply(drule bind_returns_heap_E3)
+ apply(auto)[1]
+ apply(simp)
+ apply(drule bind_returns_heap_E4)
+ apply(auto)[1]
+ apply simp
+ using \<open>type_wf h2\<close> set_child_nodes_get_child_nodes \<open>known_ptr ptr\<close> h'
+ by blast
+
+ have disconnected_nodes_h2:
+ "h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r child # disconnected_nodes_h"
+ using owner_document assms(2) h2 disconnected_nodes_h
+ apply (auto simp add: remove_child_def split: if_splits)[1]
+ apply(drule bind_returns_heap_E2)
+ apply(auto split: if_splits)[1]
+ apply(simp)
+ by(auto simp add: local.set_disconnected_nodes_get_disconnected_nodes split: if_splits)
+ then have disconnected_nodes_h':
+ "h' \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r child # disconnected_nodes_h"
+ apply(rule reads_writes_separate_forwards[OF get_disconnected_nodes_reads set_child_nodes_writes h'])
+ by (simp add: set_child_nodes_get_disconnected_nodes)
+
+ moreover have "a_acyclic_heap h"
+ using assms(1) by (simp add: heap_is_wellformed_def)
+ have "parent_child_rel h' \<subseteq> parent_child_rel h"
+ proof (standard, safe)
+ fix parent child
+ assume a1: "(parent, child) \<in> parent_child_rel h'"
+ then show "(parent, child) \<in> parent_child_rel h"
+ proof (cases "parent = ptr")
+ case True
+ then show ?thesis
+ using a1 remove_child_removes_parent[OF assms(1) assms(2)] children_h children_h'
+ get_child_nodes_ptr_in_heap
+ apply(auto simp add: parent_child_rel_def object_ptr_kinds_eq )[1]
+ by (metis imageI notin_set_remove1)
+ next
+ case False
+ then show ?thesis
+ using a1
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq3 children_eq2)
+ qed
+ qed
+ then have "a_acyclic_heap h'"
+ using \<open>a_acyclic_heap h\<close> acyclic_heap_def acyclic_subset by blast
+
+ moreover have "a_all_ptrs_in_heap h"
+ using assms(1) by (simp add: heap_is_wellformed_def)
+ then have "a_all_ptrs_in_heap h'"
+ apply(auto simp add: a_all_ptrs_in_heap_def node_ptr_kinds_eq3 disconnected_nodes_eq)[1]
+ apply (metis (no_types, lifting) \<open>type_wf h'\<close> assms(2) assms(3) local.get_child_nodes_ok
+ local.known_ptrs_known_ptr local.remove_child_children_subset notin_fset object_ptr_kinds_eq3
+ returns_result_select_result subset_code(1) type_wf)
+ apply (metis (no_types, lifting) assms(2) disconnected_nodes_eq2 disconnected_nodes_h
+ disconnected_nodes_h' document_ptr_kinds_eq3 finite_set_in local.remove_child_child_in_heap
+ node_ptr_kinds_eq3 select_result_I2 set_ConsD subset_code(1))
+ done
+ moreover have "a_owner_document_valid h"
+ using assms(1) by (simp add: heap_is_wellformed_def)
+ then have "a_owner_document_valid h'"
+ apply(auto simp add: a_owner_document_valid_def object_ptr_kinds_eq3 document_ptr_kinds_eq3
+ node_ptr_kinds_eq3)[1]
+ proof -
+ fix node_ptr
+ assume 0: "\<forall>node_ptr\<in>fset (node_ptr_kinds h'). (\<exists>document_ptr. document_ptr |\<in>| document_ptr_kinds h' \<and>
+node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r) \<or>
+(\<exists>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h' \<and> node_ptr \<in> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r)"
+ and 1: "node_ptr |\<in>| node_ptr_kinds h'"
+ and 2: "\<forall>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h' \<longrightarrow>
+node_ptr \<notin> set |h' \<turnstile> get_child_nodes parent_ptr|\<^sub>r"
+ then show "\<exists>document_ptr. document_ptr |\<in>| document_ptr_kinds h'
+ \<and> node_ptr \<in> set |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ proof (cases "node_ptr = child")
+ case True
+ show ?thesis
+ apply(rule exI[where x=owner_document])
+ using children_eq2 disconnected_nodes_eq2 children_h children_h' disconnected_nodes_h' True
+ by (metis (no_types, lifting) get_disconnected_nodes_ptr_in_heap is_OK_returns_result_I
+ list.set_intros(1) select_result_I2)
+ next
+ case False
+ then show ?thesis
+ using 0 1 2 children_eq2 children_h children_h' disconnected_nodes_eq2 disconnected_nodes_h
+ disconnected_nodes_h'
+ apply(auto simp add: children_eq2 disconnected_nodes_eq2 dest!: select_result_I2)[1]
+ by (metis children_eq2 disconnected_nodes_eq2 finite_set_in in_set_remove1 list.set_intros(2))
+ qed
+ qed
+
+ moreover
+ {
+ have h0: "a_distinct_lists h"
+ using assms(1) by (simp add: heap_is_wellformed_def)
+ moreover have ha1: "(\<Union>x\<in>set |h \<turnstile> object_ptr_kinds_M|\<^sub>r. set |h \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>set |h \<turnstile> document_ptr_kinds_M|\<^sub>r. set |h \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ using \<open>a_distinct_lists h\<close>
+ unfolding a_distinct_lists_def
+ by(auto)
+ have ha2: "ptr |\<in>| object_ptr_kinds h"
+ using children_h get_child_nodes_ptr_in_heap by blast
+ have ha3: "child \<in> set |h \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using child_in_children_h children_h
+ by(simp)
+ have child_not_in: "\<And>document_ptr. document_ptr |\<in>| document_ptr_kinds h
+ \<Longrightarrow> child \<notin> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ using ha1 ha2 ha3
+ apply(simp)
+ using IntI by fastforce
+ moreover have "distinct |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ apply(rule select_result_I)
+ by(auto simp add: object_ptr_kinds_M_defs)
+ moreover have "distinct |h \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ apply(rule select_result_I)
+ by(auto simp add: document_ptr_kinds_M_defs)
+ ultimately have "a_distinct_lists h'"
+ proof(simp (no_asm) add: a_distinct_lists_def, safe)
+ assume 1: "a_distinct_lists h"
+ and 3: "distinct |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+
+ assume 1: "a_distinct_lists h"
+ and 3: "distinct |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ have 4: "distinct (concat ((map (\<lambda>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r) |h \<turnstile> object_ptr_kinds_M|\<^sub>r)))"
+ using 1 by(auto simp add: a_distinct_lists_def)
+ show "distinct (concat (map (\<lambda>ptr. |h' \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h')))))"
+ proof(rule distinct_concat_map_I[OF 3[unfolded object_ptr_kinds_eq2], simplified])
+ fix x
+ assume 5: "x |\<in>| object_ptr_kinds h'"
+ then have 6: "distinct |h \<turnstile> get_child_nodes x|\<^sub>r"
+ using 4 distinct_concat_map_E object_ptr_kinds_eq2 by fastforce
+ obtain children where children: "h \<turnstile> get_child_nodes x \<rightarrow>\<^sub>r children"
+ and distinct_children: "distinct children"
+ by (metis "5" "6" type_wf assms(3) get_child_nodes_ok local.known_ptrs_known_ptr
+ object_ptr_kinds_eq3 select_result_I)
+ obtain children' where children': "h' \<turnstile> get_child_nodes x \<rightarrow>\<^sub>r children'"
+ using children children_eq children_h' by fastforce
+ then have "distinct children'"
+ proof (cases "ptr = x")
+ case True
+ then show ?thesis
+ using children distinct_children children_h children_h'
+ by (metis children' distinct_remove1 returns_result_eq)
+ next
+ case False
+ then show ?thesis
+ using children distinct_children children_eq[OF False]
+ using children' distinct_lists_children h0
+ using select_result_I2 by fastforce
+ qed
+
+ then show "distinct |h' \<turnstile> get_child_nodes x|\<^sub>r"
+ using children' by(auto simp add: )
+ next
+ fix x y
+ assume 5: "x |\<in>| object_ptr_kinds h'" and 6: "y |\<in>| object_ptr_kinds h'" and 7: "x \<noteq> y"
+ obtain children_x where children_x: "h \<turnstile> get_child_nodes x \<rightarrow>\<^sub>r children_x"
+ by (metis "5" type_wf assms(3) get_child_nodes_ok is_OK_returns_result_E
+ local.known_ptrs_known_ptr object_ptr_kinds_eq3)
+ obtain children_y where children_y: "h \<turnstile> get_child_nodes y \<rightarrow>\<^sub>r children_y"
+ by (metis "6" type_wf assms(3) get_child_nodes_ok is_OK_returns_result_E
+ local.known_ptrs_known_ptr object_ptr_kinds_eq3)
+ obtain children_x' where children_x': "h' \<turnstile> get_child_nodes x \<rightarrow>\<^sub>r children_x'"
+ using children_eq children_h' children_x by fastforce
+ obtain children_y' where children_y': "h' \<turnstile> get_child_nodes y \<rightarrow>\<^sub>r children_y'"
+ using children_eq children_h' children_y by fastforce
+ have "distinct (concat (map (\<lambda>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r) |h \<turnstile> object_ptr_kinds_M|\<^sub>r))"
+ using h0 by(auto simp add: a_distinct_lists_def)
+ then have 8: "set children_x \<inter> set children_y = {}"
+ using "7" assms(1) children_x children_y local.heap_is_wellformed_one_parent by blast
+ have "set children_x' \<inter> set children_y' = {}"
+ proof (cases "ptr = x")
+ case True
+ then have "ptr \<noteq> y"
+ by(simp add: 7)
+ have "children_x' = remove1 child children_x"
+ using children_h children_h' children_x children_x' True returns_result_eq by fastforce
+ moreover have "children_y' = children_y"
+ using children_y children_y' children_eq[OF \<open>ptr \<noteq> y\<close>] by auto
+ ultimately show ?thesis
+ using 8 set_remove1_subset by fastforce
+ next
+ case False
+ then show ?thesis
+ proof (cases "ptr = y")
+ case True
+ have "children_y' = remove1 child children_y"
+ using children_h children_h' children_y children_y' True returns_result_eq by fastforce
+ moreover have "children_x' = children_x"
+ using children_x children_x' children_eq[OF \<open>ptr \<noteq> x\<close>] by auto
+ ultimately show ?thesis
+ using 8 set_remove1_subset by fastforce
+ next
+ case False
+ have "children_x' = children_x"
+ using children_x children_x' children_eq[OF \<open>ptr \<noteq> x\<close>] by auto
+ moreover have "children_y' = children_y"
+ using children_y children_y' children_eq[OF \<open>ptr \<noteq> y\<close>] by auto
+ ultimately show ?thesis
+ using 8 by simp
+ qed
+ qed
+ then show "set |h' \<turnstile> get_child_nodes x|\<^sub>r \<inter> set |h' \<turnstile> get_child_nodes y|\<^sub>r = {}"
+ using children_x' children_y'
+ by (metis (no_types, lifting) select_result_I2)
+ qed
+ next
+ assume 2: "distinct |h \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ then have 4: "distinct (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ by simp
+ have 3: "distinct (concat (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h')))))"
+ using h0
+ by(simp add: a_distinct_lists_def document_ptr_kinds_eq3)
+
+ show "distinct (concat (map (\<lambda>document_ptr. |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h')))))"
+ proof(rule distinct_concat_map_I[OF 4[unfolded document_ptr_kinds_eq3]])
+ fix x
+ assume 4: "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ have 5: "distinct |h \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using distinct_lists_disconnected_nodes[OF h0] 4 get_disconnected_nodes_ok
+ by (simp add: type_wf document_ptr_kinds_eq3 select_result_I)
+ show "distinct |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ proof (cases "x = owner_document")
+ case True
+ have "child \<notin> set |h \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using child_not_in document_ptr_kinds_eq2 "4" by fastforce
+ moreover have "|h' \<turnstile> get_disconnected_nodes x|\<^sub>r = child # |h \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using disconnected_nodes_h' disconnected_nodes_h unfolding True
+ by(simp)
+ ultimately show ?thesis
+ using 5 unfolding True
+ by simp
+ next
+ case False
+ show ?thesis
+ using "5" False disconnected_nodes_eq2 by auto
+ qed
+ next
+ fix x y
+ assume 4: "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ and 5: "y \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))" and "x \<noteq> y"
+ obtain disc_nodes_x where disc_nodes_x: "h \<turnstile> get_disconnected_nodes x \<rightarrow>\<^sub>r disc_nodes_x"
+ using 4 get_disconnected_nodes_ok[OF \<open>type_wf h\<close>, of x] document_ptr_kinds_eq2
+ by auto
+ obtain disc_nodes_y where disc_nodes_y: "h \<turnstile> get_disconnected_nodes y \<rightarrow>\<^sub>r disc_nodes_y"
+ using 5 get_disconnected_nodes_ok[OF \<open>type_wf h\<close>, of y] document_ptr_kinds_eq2
+ by auto
+ obtain disc_nodes_x' where disc_nodes_x': "h' \<turnstile> get_disconnected_nodes x \<rightarrow>\<^sub>r disc_nodes_x'"
+ using 4 get_disconnected_nodes_ok[OF \<open>type_wf h'\<close>, of x] document_ptr_kinds_eq2
+ by auto
+ obtain disc_nodes_y' where disc_nodes_y': "h' \<turnstile> get_disconnected_nodes y \<rightarrow>\<^sub>r disc_nodes_y'"
+ using 5 get_disconnected_nodes_ok[OF \<open>type_wf h'\<close>, of y] document_ptr_kinds_eq2
+ by auto
+ have "distinct
+ (concat (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r) |h \<turnstile> document_ptr_kinds_M|\<^sub>r))"
+ using h0 by (simp add: a_distinct_lists_def)
+ then have 6: "set disc_nodes_x \<inter> set disc_nodes_y = {}"
+ using \<open>x \<noteq> y\<close> assms(1) disc_nodes_x disc_nodes_y local.heap_is_wellformed_one_disc_parent
+ by blast
+
+ have "set disc_nodes_x' \<inter> set disc_nodes_y' = {}"
+ proof (cases "x = owner_document")
+ case True
+ then have "y \<noteq> owner_document"
+ using \<open>x \<noteq> y\<close> by simp
+ then have "disc_nodes_y' = disc_nodes_y"
+ using disconnected_nodes_eq[OF \<open>y \<noteq> owner_document\<close>] disc_nodes_y disc_nodes_y'
+ by auto
+ have "disc_nodes_x' = child # disc_nodes_x"
+ using disconnected_nodes_h' disc_nodes_x disc_nodes_x' True disconnected_nodes_h returns_result_eq
+ by fastforce
+ have "child \<notin> set disc_nodes_y"
+ using child_not_in disc_nodes_y 5
+ using document_ptr_kinds_eq2 by fastforce
+ then show ?thesis
+ apply(unfold \<open>disc_nodes_x' = child # disc_nodes_x\<close> \<open>disc_nodes_y' = disc_nodes_y\<close>)
+ using 6 by auto
+ next
+ case False
+ then show ?thesis
+ proof (cases "y = owner_document")
+ case True
+ then have "disc_nodes_x' = disc_nodes_x"
+ using disconnected_nodes_eq[OF \<open>x \<noteq> owner_document\<close>] disc_nodes_x disc_nodes_x' by auto
+ have "disc_nodes_y' = child # disc_nodes_y"
+ using disconnected_nodes_h' disc_nodes_y disc_nodes_y' True disconnected_nodes_h returns_result_eq
+ by fastforce
+ have "child \<notin> set disc_nodes_x"
+ using child_not_in disc_nodes_x 4
+ using document_ptr_kinds_eq2 by fastforce
+ then show ?thesis
+ apply(unfold \<open>disc_nodes_y' = child # disc_nodes_y\<close> \<open>disc_nodes_x' = disc_nodes_x\<close>)
+ using 6 by auto
+ next
+ case False
+ have "disc_nodes_x' = disc_nodes_x"
+ using disconnected_nodes_eq[OF \<open>x \<noteq> owner_document\<close>] disc_nodes_x disc_nodes_x' by auto
+ have "disc_nodes_y' = disc_nodes_y"
+ using disconnected_nodes_eq[OF \<open>y \<noteq> owner_document\<close>] disc_nodes_y disc_nodes_y' by auto
+ then show ?thesis
+ apply(unfold \<open>disc_nodes_y' = disc_nodes_y\<close> \<open>disc_nodes_x' = disc_nodes_x\<close>)
+ using 6 by auto
+ qed
+ qed
+ then show "set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ using disc_nodes_x' disc_nodes_y' by auto
+ qed
+ next
+ fix x xa xb
+ assume 1: "xa \<in> fset (object_ptr_kinds h')"
+ and 2: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 3: "xb \<in> fset (document_ptr_kinds h')"
+ and 4: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ obtain disc_nodes where disc_nodes: "h \<turnstile> get_disconnected_nodes xb \<rightarrow>\<^sub>r disc_nodes"
+ using 3 get_disconnected_nodes_ok[OF \<open>type_wf h\<close>, of xb] document_ptr_kinds_eq2 by auto
+ obtain disc_nodes' where disc_nodes': "h' \<turnstile> get_disconnected_nodes xb \<rightarrow>\<^sub>r disc_nodes'"
+ using 3 get_disconnected_nodes_ok[OF \<open>type_wf h'\<close>, of xb] document_ptr_kinds_eq2 by auto
+
+ obtain children where children: "h \<turnstile> get_child_nodes xa \<rightarrow>\<^sub>r children"
+ by (metis "1" type_wf assms(3) finite_set_in get_child_nodes_ok is_OK_returns_result_E
+ local.known_ptrs_known_ptr object_ptr_kinds_eq3)
+ obtain children' where children': "h' \<turnstile> get_child_nodes xa \<rightarrow>\<^sub>r children'"
+ using children children_eq children_h' by fastforce
+ have "\<And>x. x \<in> set |h \<turnstile> get_child_nodes xa|\<^sub>r \<Longrightarrow> x \<in> set |h \<turnstile> get_disconnected_nodes xb|\<^sub>r \<Longrightarrow> False"
+ using 1 3
+ apply(fold \<open> object_ptr_kinds h = object_ptr_kinds h'\<close>)
+ apply(fold \<open> document_ptr_kinds h = document_ptr_kinds h'\<close>)
+ using children disc_nodes h0 apply(auto simp add: a_distinct_lists_def)[1]
+ by (metis (no_types, lifting) h0 local.distinct_lists_no_parent select_result_I2)
+ then have 5: "\<And>x. x \<in> set children \<Longrightarrow> x \<in> set disc_nodes \<Longrightarrow> False"
+ using children disc_nodes by fastforce
+ have 6: "|h' \<turnstile> get_child_nodes xa|\<^sub>r = children'"
+ using children' by (simp add: )
+ have 7: "|h' \<turnstile> get_disconnected_nodes xb|\<^sub>r = disc_nodes'"
+ using disc_nodes' by (simp add: )
+ have "False"
+ proof (cases "xa = ptr")
+ case True
+ have "distinct children_h"
+ using children_h distinct_lists_children h0 \<open>known_ptr ptr\<close> by blast
+ have "|h' \<turnstile> get_child_nodes ptr|\<^sub>r = remove1 child children_h"
+ using children_h'
+ by(simp add: )
+ have "children = children_h"
+ using True children children_h by auto
+ show ?thesis
+ using disc_nodes' children' 5 2 4 children_h \<open>distinct children_h\<close> disconnected_nodes_h'
+ apply(auto simp add: 6 7
+ \<open>xa = ptr\<close> \<open>|h' \<turnstile> get_child_nodes ptr|\<^sub>r = remove1 child children_h\<close> \<open>children = children_h\<close>)[1]
+ by (metis (no_types, lifting) disc_nodes disconnected_nodes_eq2 disconnected_nodes_h
+ select_result_I2 set_ConsD)
+ next
+ case False
+ have "children' = children"
+ using children' children children_eq[OF False[symmetric]]
+ by auto
+ then show ?thesis
+ proof (cases "xb = owner_document")
+ case True
+ then show ?thesis
+ using disc_nodes disconnected_nodes_h disconnected_nodes_h'
+ using "2" "4" "5" "6" "7" False \<open>children' = children\<close> assms(1) child_in_children_h
+ child_parent_dual children children_h disc_nodes' get_child_nodes_ptr_in_heap
+ list.set_cases list.simps(3) option.simps(1) returns_result_eq set_ConsD
+ by (metis (no_types, hide_lams) assms(3) type_wf)
+ next
+ case False
+ then show ?thesis
+ using "2" "4" "5" "6" "7" \<open>children' = children\<close> disc_nodes disc_nodes'
+ disconnected_nodes_eq returns_result_eq
+ by metis
+ qed
+ qed
+ then show "x \<in> {}"
+ by simp
+ qed
+ }
+
+ ultimately show "heap_is_wellformed h'"
+ using heap_is_wellformed_def by blast
+qed
+
+lemma remove_heap_is_wellformed_preserved:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> remove child \<rightarrow>\<^sub>h h'"
+ and "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "type_wf h'" and "known_ptrs h'" and "heap_is_wellformed h'"
+ using assms
+ by(auto simp add: remove_def intro: remove_child_heap_is_wellformed_preserved
+ elim!: bind_returns_heap_E2 split: option.splits)
+
+lemma remove_child_removes_child:
+ assumes wellformed: "heap_is_wellformed h"
+ and remove_child: "h \<turnstile> remove_child ptr' child \<rightarrow>\<^sub>h h'"
+ and children: "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "child \<notin> set children"
+proof -
+ obtain owner_document children_h h2 disconnected_nodes_h where
+ owner_document: "h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r owner_document" and
+ children_h: "h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children_h" and
+ child_in_children_h: "child \<in> set children_h" and
+ disconnected_nodes_h: "h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disconnected_nodes_h" and
+ h2: "h \<turnstile> set_disconnected_nodes owner_document (child # disconnected_nodes_h) \<rightarrow>\<^sub>h h2" and
+ h': "h2 \<turnstile> set_child_nodes ptr' (remove1 child children_h) \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ apply(auto simp add: remove_child_def elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_child_nodes_pure]
+ split: if_splits)[1]
+ using pure_returns_heap_eq
+ by fastforce
+ have "object_ptr_kinds h = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF remove_child_writes remove_child])
+ unfolding remove_child_locs_def
+ using set_child_nodes_pointers_preserved set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ moreover have "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF remove_child_writes assms(2)]
+ using set_child_nodes_types_preserved set_disconnected_nodes_types_preserved type_wf
+ unfolding remove_child_locs_def
+ apply(auto simp add: reflp_def transp_def)[1]
+ by blast
+ ultimately show ?thesis
+ using remove_child_removes_parent remove_child_heap_is_wellformed_preserved child_parent_dual
+ by (meson children known_ptrs local.known_ptrs_preserved option.distinct(1) remove_child
+ returns_result_eq type_wf wellformed)
+qed
+
+lemma remove_child_removes_first_child:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r node_ptr # children"
+ assumes "h \<turnstile> remove_child ptr node_ptr \<rightarrow>\<^sub>h h'"
+ shows "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+proof -
+ obtain h2 disc_nodes owner_document where
+ "h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r owner_document" and
+ "h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes" and
+ h2: "h \<turnstile> set_disconnected_nodes owner_document (node_ptr # disc_nodes) \<rightarrow>\<^sub>h h2" and
+ "h2 \<turnstile> set_child_nodes ptr children \<rightarrow>\<^sub>h h'"
+ using assms(5)
+ apply(auto simp add: remove_child_def
+ dest!: bind_returns_heap_E3[rotated, OF assms(4) get_child_nodes_pure, rotated])[1]
+ by(auto elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated,OF get_owner_document_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated])
+ have "known_ptr ptr"
+ by (meson assms(3) assms(4) is_OK_returns_result_I get_child_nodes_ptr_in_heap known_ptrs_known_ptr)
+ moreover have "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r node_ptr # children"
+ apply(rule reads_writes_separate_forwards[OF get_child_nodes_reads set_disconnected_nodes_writes h2 assms(4)])
+ using set_disconnected_nodes_get_child_nodes set_child_nodes_get_child_nodes_different_pointers
+ by fast
+ moreover have "type_wf h2"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h2]
+ using \<open>type_wf h\<close> set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ ultimately show ?thesis
+ using set_child_nodes_get_child_nodes\<open>h2 \<turnstile> set_child_nodes ptr children \<rightarrow>\<^sub>h h'\<close>
+ by fast
+qed
+
+lemma remove_removes_child:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r node_ptr # children"
+ assumes "h \<turnstile> remove node_ptr \<rightarrow>\<^sub>h h'"
+ shows "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+proof -
+ have "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r Some ptr"
+ using child_parent_dual assms by fastforce
+ show ?thesis
+ using assms remove_child_removes_first_child
+ by(auto simp add: remove_def
+ dest!: bind_returns_heap_E3[rotated, OF \<open>h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r Some ptr\<close>, rotated]
+ bind_returns_heap_E3[rotated, OF assms(4) get_child_nodes_pure, rotated])
+qed
+
+lemma remove_for_all_empty_children:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assumes "h \<turnstile> forall_M remove children \<rightarrow>\<^sub>h h'"
+ shows "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r []"
+ using assms
+proof(induct children arbitrary: h h')
+ case Nil
+ then show ?case
+ by simp
+next
+ case (Cons a children)
+ have "h \<turnstile> get_parent a \<rightarrow>\<^sub>r Some ptr"
+ using child_parent_dual Cons by fastforce
+ with Cons show ?case
+ proof(auto elim!: bind_returns_heap_E)[1]
+ fix h2
+ assume 0: "(\<And>h h'. heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> h \<turnstile> forall_M remove children \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r [])"
+ and 1: "heap_is_wellformed h"
+ and 2: "type_wf h"
+ and 3: "known_ptrs h"
+ and 4: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r a # children"
+ and 5: "h \<turnstile> get_parent a \<rightarrow>\<^sub>r Some ptr"
+ and 7: "h \<turnstile> remove a \<rightarrow>\<^sub>h h2"
+ and 8: "h2 \<turnstile> forall_M remove children \<rightarrow>\<^sub>h h'"
+ then have "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using remove_removes_child by blast
+
+ moreover have "heap_is_wellformed h2"
+ using 7 1 2 3 remove_child_heap_is_wellformed_preserved(3)
+ by(auto simp add: remove_def
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ split: option.splits)
+ moreover have "type_wf h2"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF remove_writes 7]
+ using \<open>type_wf h\<close> remove_child_types_preserved
+ by(auto simp add: a_remove_child_locs_def reflp_def transp_def)
+ moreover have "object_ptr_kinds h = object_ptr_kinds h2"
+ using 7
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF remove_writes])
+ using remove_child_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have "known_ptrs h2"
+ using 3 known_ptrs_preserved by blast
+
+ ultimately show "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r []"
+ using 0 8 by fast
+ qed
+qed
+end
+
+locale l_remove_child_wf2 = l_type_wf + l_known_ptrs + l_remove_child_defs + l_heap_is_wellformed_defs
+ + l_get_child_nodes_defs + l_remove_defs +
+ assumes remove_child_preserves_type_wf:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> type_wf h'"
+ assumes remove_child_preserves_known_ptrs:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> known_ptrs h'"
+ assumes remove_child_heap_is_wellformed_preserved:
+ "type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> heap_is_wellformed h \<Longrightarrow> h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> heap_is_wellformed h'"
+ assumes remove_preserves_type_wf:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> remove child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> type_wf h'"
+ assumes remove_preserves_known_ptrs:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> remove child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> known_ptrs h'"
+ assumes remove_heap_is_wellformed_preserved:
+ "type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> heap_is_wellformed h \<Longrightarrow> h \<turnstile> remove child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> heap_is_wellformed h'"
+ assumes remove_child_removes_child:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> remove_child ptr' child \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h
+ \<Longrightarrow> child \<notin> set children"
+ assumes remove_child_removes_first_child:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r node_ptr # children
+ \<Longrightarrow> h \<turnstile> remove_child ptr node_ptr \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assumes remove_removes_child:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r node_ptr # children
+ \<Longrightarrow> h \<turnstile> remove node_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assumes remove_for_all_empty_children:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> h \<turnstile> forall_M remove children \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r []"
+
+interpretation i_remove_child_wf2?: l_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs
+ set_child_nodes set_child_nodes_locs get_parent get_parent_locs get_owner_document
+ get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs remove_child remove_child_locs remove type_wf known_ptr known_ptrs
+ heap_is_wellformed parent_child_rel
+ by unfold_locales
+
+declare l_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma remove_child_wf2_is_l_remove_child_wf2 [instances]:
+ "l_remove_child_wf2 type_wf known_ptr known_ptrs remove_child heap_is_wellformed get_child_nodes remove"
+ apply(auto simp add: l_remove_child_wf2_def l_remove_child_wf2_axioms_def instances)[1]
+ using remove_child_heap_is_wellformed_preserved apply(fast, fast, fast)
+ using remove_heap_is_wellformed_preserved apply(fast, fast, fast)
+ using remove_child_removes_child apply fast
+ using remove_child_removes_first_child apply fast
+ using remove_removes_child apply fast
+ using remove_for_all_empty_children apply fast
+ done
+
+
+
+subsection \<open>adopt\_node\<close>
+
+locale l_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent_wf +
+ l_get_owner_document_wf +
+ l_remove_child_wf2 +
+ l_heap_is_wellformed
+begin
+lemma adopt_node_removes_first_child:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r node # children"
+ shows "h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+proof -
+ obtain old_document parent_opt h2 where
+ old_document: "h \<turnstile> get_owner_document (cast node) \<rightarrow>\<^sub>r old_document" and
+ parent_opt: "h \<turnstile> get_parent node \<rightarrow>\<^sub>r parent_opt" and
+ h2: "h \<turnstile> (case parent_opt of Some parent \<Rightarrow> do { remove_child parent node }
+ | None \<Rightarrow> do { return ()}) \<rightarrow>\<^sub>h h2" and
+ h': "h2 \<turnstile> (if owner_document \<noteq> old_document then do {
+ old_disc_nodes \<leftarrow> get_disconnected_nodes old_document;
+ set_disconnected_nodes old_document (remove1 node old_disc_nodes);
+ disc_nodes \<leftarrow> get_disconnected_nodes owner_document;
+ set_disconnected_nodes owner_document (node # disc_nodes)
+ } else do { return () }) \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ by(auto simp add: adopt_node_def elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_parent_pure])
+ have "h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using h2 remove_child_removes_first_child assms(1) assms(2) assms(3) assms(5)
+ by (metis list.set_intros(1) local.child_parent_dual option.simps(5) parent_opt returns_result_eq)
+ then
+ show ?thesis
+ using h'
+ by(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ dest!: reads_writes_separate_forwards[OF get_child_nodes_reads set_disconnected_nodes_writes]
+ split: if_splits)
+qed
+
+
+lemma adopt_node_document_in_heap:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ assumes "h \<turnstile> ok (adopt_node owner_document node)"
+ shows "owner_document |\<in>| document_ptr_kinds h"
+proof -
+ obtain old_document parent_opt h2 h' where
+ old_document: "h \<turnstile> get_owner_document (cast node) \<rightarrow>\<^sub>r old_document" and
+ parent_opt: "h \<turnstile> get_parent node \<rightarrow>\<^sub>r parent_opt" and
+ h2: "h \<turnstile> (case parent_opt of Some parent \<Rightarrow> do { remove_child parent node } | None \<Rightarrow> do { return ()}) \<rightarrow>\<^sub>h h2"
+ and
+ h': "h2 \<turnstile> (if owner_document \<noteq> old_document then do {
+ old_disc_nodes \<leftarrow> get_disconnected_nodes old_document;
+ set_disconnected_nodes old_document (remove1 node old_disc_nodes);
+ disc_nodes \<leftarrow> get_disconnected_nodes owner_document;
+ set_disconnected_nodes owner_document (node # disc_nodes)
+ } else do { return () }) \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ by(auto simp add: adopt_node_def
+ elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_parent_pure])
+ show ?thesis
+ proof (cases "owner_document = old_document")
+ case True
+ then show ?thesis
+ using old_document get_owner_document_owner_document_in_heap assms(1) assms(2) assms(3)
+ by auto
+ next
+ case False
+
+ then obtain h3 old_disc_nodes disc_nodes where
+ old_disc_nodes: "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r old_disc_nodes" and
+ h3: "h2 \<turnstile> set_disconnected_nodes old_document (remove1 node old_disc_nodes) \<rightarrow>\<^sub>h h3" and
+ old_disc_nodes: "h3 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes" and
+ h': "h3 \<turnstile> set_disconnected_nodes owner_document (node # disc_nodes) \<rightarrow>\<^sub>h h'"
+ using h'
+ by(auto elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+ then have "owner_document |\<in>| document_ptr_kinds h3"
+ by (meson is_OK_returns_result_I local.get_disconnected_nodes_ptr_in_heap)
+
+ moreover have "object_ptr_kinds h = object_ptr_kinds h2"
+ using h2 apply(simp split: option.splits)
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF remove_child_writes])
+ using remove_child_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ moreover have "object_ptr_kinds h2 = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h3])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+
+ ultimately show ?thesis
+ by(auto simp add: document_ptr_kinds_def)
+ qed
+qed
+end
+
+locale l_adopt_node_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_root_node +
+ l_get_owner_document_wf +
+ l_remove_child_wf2 +
+ l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma adopt_node_removes_child_step:
+ assumes wellformed: "heap_is_wellformed h"
+ and adopt_node: "h \<turnstile> adopt_node owner_document node_ptr \<rightarrow>\<^sub>h h2"
+ and children: "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "node_ptr \<notin> set children"
+proof -
+ obtain old_document parent_opt h' where
+ old_document: "h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r old_document" and
+ parent_opt: "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r parent_opt" and
+ h': "h \<turnstile> (case parent_opt of Some parent \<Rightarrow> remove_child parent node_ptr | None \<Rightarrow> return () ) \<rightarrow>\<^sub>h h'"
+ using adopt_node get_parent_pure
+ by(auto simp add: adopt_node_def
+ elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_owner_document_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ split: if_splits)
+
+ then have "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using adopt_node
+ apply(auto simp add: adopt_node_def
+ dest!: bind_returns_heap_E3[rotated, OF old_document, rotated]
+ bind_returns_heap_E3[rotated, OF parent_opt, rotated]
+ elim!: bind_returns_heap_E4[rotated, OF h', rotated])[1]
+ apply(auto split: if_splits
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated])[1]
+ apply (simp add: set_disconnected_nodes_get_child_nodes children
+ reads_writes_preserved[OF get_child_nodes_reads set_disconnected_nodes_writes])
+ using children by blast
+ show ?thesis
+ proof(insert parent_opt h', induct parent_opt)
+ case None
+ then show ?case
+ using child_parent_dual wellformed known_ptrs type_wf
+ \<open>h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children\<close> returns_result_eq
+ by fastforce
+ next
+ case (Some option)
+ then show ?case
+ using remove_child_removes_child \<open>h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children\<close> known_ptrs type_wf
+ wellformed
+ by auto
+ qed
+qed
+
+lemma adopt_node_removes_child:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ assumes "h \<turnstile> adopt_node owner_document node_ptr \<rightarrow>\<^sub>h h'"
+ shows "\<And>ptr' children'.
+ h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children' \<Longrightarrow> node_ptr \<notin> set children'"
+ using adopt_node_removes_child_step assms by blast
+
+lemma adopt_node_preserves_wellformedness:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> adopt_node document_ptr child \<rightarrow>\<^sub>h h'"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "heap_is_wellformed h'" and "known_ptrs h'" and "type_wf h'"
+proof -
+ obtain old_document parent_opt h2 where
+ old_document: "h \<turnstile> get_owner_document (cast child) \<rightarrow>\<^sub>r old_document"
+ and
+ parent_opt: "h \<turnstile> get_parent child \<rightarrow>\<^sub>r parent_opt"
+ and
+ h2: "h \<turnstile> (case parent_opt of Some parent \<Rightarrow> remove_child parent child | None \<Rightarrow> return ()) \<rightarrow>\<^sub>h h2"
+ and
+ h': "h2 \<turnstile> (if document_ptr \<noteq> old_document then do {
+ old_disc_nodes \<leftarrow> get_disconnected_nodes old_document;
+ set_disconnected_nodes old_document (remove1 child old_disc_nodes);
+ disc_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ set_disconnected_nodes document_ptr (child # disc_nodes)
+ } else do {
+ return ()
+ }) \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ by(auto simp add: adopt_node_def elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_parent_pure])
+
+ have object_ptr_kinds_h_eq3: "object_ptr_kinds h = object_ptr_kinds h2"
+ using h2 apply(simp split: option.splits)
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF remove_child_writes])
+ using remove_child_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h:
+ "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ unfolding object_ptr_kinds_M_defs by simp
+ then have object_ptr_kinds_eq_h: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq_h: "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+
+ have wellformed_h2: "heap_is_wellformed h2"
+ using h2 remove_child_heap_is_wellformed_preserved known_ptrs type_wf
+ by (metis (no_types, lifting) assms(1) option.case_eq_if pure_returns_heap_eq return_pure)
+ have "type_wf h2"
+ using h2 remove_child_preserves_type_wf known_ptrs type_wf
+ by (metis (no_types, lifting) assms(1) option.case_eq_if pure_returns_heap_eq return_pure)
+ have "known_ptrs h2"
+ using h2 remove_child_preserves_known_ptrs known_ptrs type_wf
+ by (metis (no_types, lifting) assms(1) option.case_eq_if pure_returns_heap_eq return_pure)
+ have "heap_is_wellformed h' \<and> known_ptrs h' \<and> type_wf h'"
+ proof(cases "document_ptr = old_document")
+ case True
+ then show ?thesis
+ using h' wellformed_h2 \<open>type_wf h2\<close> \<open>known_ptrs h2\<close> by auto
+ next
+ case False
+ then obtain h3 old_disc_nodes disc_nodes_document_ptr_h3 where
+ docs_neq: "document_ptr \<noteq> old_document" and
+ old_disc_nodes: "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r old_disc_nodes" and
+ h3: "h2 \<turnstile> set_disconnected_nodes old_document (remove1 child old_disc_nodes) \<rightarrow>\<^sub>h h3" and
+ disc_nodes_document_ptr_h3:
+ "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_document_ptr_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (child # disc_nodes_document_ptr_h3) \<rightarrow>\<^sub>h h'"
+ using h'
+ by(auto elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+
+ have object_ptr_kinds_h2_eq3: "object_ptr_kinds h2 = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h3])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h2:
+ "\<And>ptrs. h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq_h2: "|h2 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+ then have node_ptr_kinds_eq_h2: "|h2 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ then have node_ptr_kinds_eq3_h2: "node_ptr_kinds h2 = node_ptr_kinds h3"
+ by auto
+ have document_ptr_kinds_eq2_h2: "|h2 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq_h2 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3_h2: "document_ptr_kinds h2 = document_ptr_kinds h3"
+ using object_ptr_kinds_eq_h2 document_ptr_kinds_M_eq by auto
+ have children_eq_h2:
+ "\<And>ptr children. h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h2: "\<And>ptr. |h2 \<turnstile> get_child_nodes ptr|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have object_ptr_kinds_h3_eq3: "object_ptr_kinds h3 = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h3:
+ "\<And>ptrs. h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq_h3: "|h3 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+ then have node_ptr_kinds_eq_h3: "|h3 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ then have node_ptr_kinds_eq3_h3: "node_ptr_kinds h3 = node_ptr_kinds h'"
+ by auto
+ have document_ptr_kinds_eq2_h3: "|h3 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h' \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq_h3 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3_h3: "document_ptr_kinds h3 = document_ptr_kinds h'"
+ using object_ptr_kinds_eq_h3 document_ptr_kinds_M_eq by auto
+ have children_eq_h3:
+ "\<And>ptr children. h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h3: "\<And>ptr. |h3 \<turnstile> get_child_nodes ptr|\<^sub>r = |h' \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. old_document \<noteq> doc_ptr
+ \<Longrightarrow> h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. old_document \<noteq> doc_ptr
+ \<Longrightarrow> |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ obtain disc_nodes_old_document_h2 where disc_nodes_old_document_h2:
+ "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disc_nodes_old_document_h2"
+ using old_disc_nodes by blast
+ then have disc_nodes_old_document_h3:
+ "h3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r remove1 child disc_nodes_old_document_h2"
+ using h3 old_disc_nodes returns_result_eq set_disconnected_nodes_get_disconnected_nodes
+ by fastforce
+ have "distinct disc_nodes_old_document_h2"
+ using disc_nodes_old_document_h2 local.heap_is_wellformed_disconnected_nodes_distinct wellformed_h2
+ by blast
+
+
+ have "type_wf h2"
+ proof (insert h2, induct parent_opt)
+ case None
+ then show ?case
+ using type_wf by simp
+ next
+ case (Some option)
+ then show ?case
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF remove_child_writes]
+ type_wf remove_child_types_preserved
+ by (simp add: reflp_def transp_def)
+ qed
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h3]
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then have "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have "known_ptrs h3"
+ using known_ptrs local.known_ptrs_preserved object_ptr_kinds_h2_eq3 object_ptr_kinds_h_eq3 by blast
+ then have "known_ptrs h'"
+ using local.known_ptrs_preserved object_ptr_kinds_h3_eq3 by blast
+
+ have disconnected_nodes_eq_h3:
+ "\<And>doc_ptr disc_nodes. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h3:
+ "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have disc_nodes_document_ptr_h2:
+ "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_document_ptr_h3"
+ using disconnected_nodes_eq_h2 docs_neq disc_nodes_document_ptr_h3 by auto
+ have disc_nodes_document_ptr_h': "
+ h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r child # disc_nodes_document_ptr_h3"
+ using h' disc_nodes_document_ptr_h3
+ using set_disconnected_nodes_get_disconnected_nodes by blast
+
+ have document_ptr_in_heap: "document_ptr |\<in>| document_ptr_kinds h2"
+ using disc_nodes_document_ptr_h3 document_ptr_kinds_eq2_h2 get_disconnected_nodes_ok assms(1)
+ unfolding heap_is_wellformed_def
+ using disc_nodes_document_ptr_h2 get_disconnected_nodes_ptr_in_heap by blast
+ have old_document_in_heap: "old_document |\<in>| document_ptr_kinds h2"
+ using disc_nodes_old_document_h3 document_ptr_kinds_eq2_h2 get_disconnected_nodes_ok assms(1)
+ unfolding heap_is_wellformed_def
+ using get_disconnected_nodes_ptr_in_heap old_disc_nodes by blast
+
+ have "child \<in> set disc_nodes_old_document_h2"
+ proof (insert parent_opt h2, induct parent_opt)
+ case None
+ then have "h = h2"
+ by(auto)
+ moreover have "a_owner_document_valid h"
+ using assms(1) heap_is_wellformed_def by(simp add: heap_is_wellformed_def)
+ ultimately show ?case
+ using old_document disc_nodes_old_document_h2 None(1) child_parent_dual[OF assms(1)]
+ in_disconnected_nodes_no_parent assms(1) known_ptrs type_wf by blast
+ next
+ case (Some option)
+ then show ?case
+ apply(simp split: option.splits)
+ using assms(1) disc_nodes_old_document_h2 old_document remove_child_in_disconnected_nodes known_ptrs
+ by blast
+ qed
+ have "child \<notin> set (remove1 child disc_nodes_old_document_h2)"
+ using disc_nodes_old_document_h3 h3 known_ptrs wellformed_h2 \<open>distinct disc_nodes_old_document_h2\<close>
+ by auto
+ have "child \<notin> set disc_nodes_document_ptr_h3"
+ proof -
+ have "a_distinct_lists h2"
+ using heap_is_wellformed_def wellformed_h2 by blast
+ then have 0: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ |h2 \<turnstile> document_ptr_kinds_M|\<^sub>r))"
+ by(simp add: a_distinct_lists_def)
+ show ?thesis
+ using distinct_concat_map_E(1)[OF 0] \<open>child \<in> set disc_nodes_old_document_h2\<close>
+ disc_nodes_old_document_h2 disc_nodes_document_ptr_h2
+ by (meson \<open>type_wf h2\<close> docs_neq known_ptrs local.get_owner_document_disconnected_nodes
+ local.known_ptrs_preserved object_ptr_kinds_h_eq3 returns_result_eq wellformed_h2)
+ qed
+
+ have child_in_heap: "child |\<in>| node_ptr_kinds h"
+ using get_owner_document_ptr_in_heap[OF is_OK_returns_result_I[OF old_document]]
+ node_ptr_kinds_commutes by blast
+ have "a_acyclic_heap h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def)
+ have "parent_child_rel h' \<subseteq> parent_child_rel h2"
+ proof
+ fix x
+ assume "x \<in> parent_child_rel h'"
+ then show "x \<in> parent_child_rel h2"
+ using object_ptr_kinds_h2_eq3 object_ptr_kinds_h3_eq3 children_eq2_h2 children_eq2_h3
+ mem_Collect_eq object_ptr_kinds_M_eq_h3 select_result_eq split_cong
+ unfolding parent_child_rel_def
+ by(simp)
+ qed
+ then have "a_acyclic_heap h'"
+ using \<open>a_acyclic_heap h2\<close> acyclic_heap_def acyclic_subset by blast
+
+ moreover have "a_all_ptrs_in_heap h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def)
+ then have "a_all_ptrs_in_heap h3"
+ apply(auto simp add: a_all_ptrs_in_heap_def node_ptr_kinds_eq3_h2 children_eq_h2)[1]
+ apply (simp add: children_eq2_h2 object_ptr_kinds_h2_eq3 subset_code(1))
+ by (metis (no_types, lifting) \<open>child \<in> set disc_nodes_old_document_h2\<close> \<open>type_wf h2\<close>
+ disc_nodes_old_document_h2 disc_nodes_old_document_h3 disconnected_nodes_eq2_h2
+ document_ptr_kinds_eq3_h2 in_set_remove1 local.get_disconnected_nodes_ok
+ local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_eq3_h2 returns_result_select_result
+ select_result_I2 wellformed_h2)
+ then have "a_all_ptrs_in_heap h'"
+ apply(auto simp add: a_all_ptrs_in_heap_def node_ptr_kinds_eq3_h3 children_eq_h3)[1]
+ apply (simp add: children_eq2_h3 object_ptr_kinds_h3_eq3 subset_code(1))
+ by (metis (no_types, lifting) \<open>child \<in> set disc_nodes_old_document_h2\<close> disc_nodes_document_ptr_h'
+ disc_nodes_document_ptr_h2 disc_nodes_old_document_h2 disconnected_nodes_eq2_h3 document_ptr_kinds_eq3_h3
+ finite_set_in local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_eq3_h2 node_ptr_kinds_eq3_h3
+ select_result_I2 set_ConsD subset_code(1) wellformed_h2)
+
+ moreover have "a_owner_document_valid h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def)
+ then have "a_owner_document_valid h'"
+ apply(simp add: a_owner_document_valid_def node_ptr_kinds_eq_h2 node_ptr_kinds_eq3_h3
+ object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 document_ptr_kinds_eq2_h2
+ document_ptr_kinds_eq2_h3 children_eq2_h2 children_eq2_h3 )
+ by (smt disc_nodes_document_ptr_h' disc_nodes_document_ptr_h2
+ disc_nodes_old_document_h2 disc_nodes_old_document_h3
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 document_ptr_in_heap
+ document_ptr_kinds_eq3_h2 document_ptr_kinds_eq3_h3 in_set_remove1
+ list.set_intros(1) node_ptr_kinds_eq3_h2 node_ptr_kinds_eq3_h3
+ object_ptr_kinds_h2_eq3 object_ptr_kinds_h3_eq3 select_result_I2
+ set_subset_Cons subset_code(1))
+
+ have a_distinct_lists_h2: "a_distinct_lists h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def)
+ then have "a_distinct_lists h'"
+ apply(auto simp add: a_distinct_lists_def object_ptr_kinds_eq_h3 object_ptr_kinds_eq_h2
+ children_eq2_h2 children_eq2_h3)[1]
+ proof -
+ assume 1: "distinct (concat (map (\<lambda>ptr. |h' \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h')))))"
+ and 2: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h2)))))"
+ and 3: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h2). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ show "distinct (concat (map (\<lambda>document_ptr. |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h')))))"
+ proof(rule distinct_concat_map_I)
+ show "distinct (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ by(auto simp add: document_ptr_kinds_M_def )
+ next
+ fix x
+ assume a1: "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ have 4: "distinct |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using a_distinct_lists_h2 "2" a1 concat_map_all_distinct document_ptr_kinds_eq2_h2
+ document_ptr_kinds_eq2_h3
+ by fastforce
+ then show "distinct |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ proof (cases "old_document \<noteq> x")
+ case True
+ then show ?thesis
+ proof (cases "document_ptr \<noteq> x")
+ case True
+ then show ?thesis
+ using disconnected_nodes_eq2_h2[OF \<open>old_document \<noteq> x\<close>]
+ disconnected_nodes_eq2_h3[OF \<open>document_ptr \<noteq> x\<close>] 4
+ by(auto)
+ next
+ case False
+ then show ?thesis
+ using disc_nodes_document_ptr_h3 disc_nodes_document_ptr_h' 4
+ \<open>child \<notin> set disc_nodes_document_ptr_h3\<close>
+ by(auto simp add: disconnected_nodes_eq2_h2[OF \<open>old_document \<noteq> x\<close>] )
+ qed
+ next
+ case False
+ then show ?thesis
+ by (metis (no_types, hide_lams) \<open>distinct disc_nodes_old_document_h2\<close>
+ disc_nodes_old_document_h3 disconnected_nodes_eq2_h3
+ distinct_remove1 docs_neq select_result_I2)
+ qed
+ next
+ fix x y
+ assume a0: "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ and a1: "y \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ and a2: "x \<noteq> y"
+
+ moreover have 5: "set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ using 2 calculation
+ by (auto simp add: document_ptr_kinds_eq3_h2 document_ptr_kinds_eq3_h3 dest: distinct_concat_map_E(1))
+ ultimately show "set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ proof(cases "old_document = x")
+ case True
+ have "old_document \<noteq> y"
+ using \<open>x \<noteq> y\<close> \<open>old_document = x\<close> by simp
+ have "document_ptr \<noteq> x"
+ using docs_neq \<open>old_document = x\<close> by auto
+ show ?thesis
+ proof(cases "document_ptr = y")
+ case True
+ then show ?thesis
+ using 5 True select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3] \<open>old_document = x\<close>
+ by (metis (no_types, lifting) \<open>child \<notin> set (remove1 child disc_nodes_old_document_h2)\<close>
+ \<open>document_ptr \<noteq> x\<close> disconnected_nodes_eq2_h3 disjoint_iff_not_equal
+ notin_set_remove1 set_ConsD)
+ next
+ case False
+ then show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3]
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 \<open>old_document = x\<close>
+ docs_neq \<open>old_document \<noteq> y\<close>
+ by (metis (no_types, lifting) disjoint_iff_not_equal notin_set_remove1)
+ qed
+ next
+ case False
+ then show ?thesis
+ proof(cases "old_document = y")
+ case True
+ then show ?thesis
+ proof(cases "document_ptr = x")
+ case True
+ show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3]
+ \<open>old_document \<noteq> x\<close> \<open>old_document = y\<close> \<open>document_ptr = x\<close>
+ apply(simp)
+ by (metis (no_types, lifting) \<open>child \<notin> set (remove1 child disc_nodes_old_document_h2)\<close>
+ disconnected_nodes_eq2_h3 disjoint_iff_not_equal notin_set_remove1)
+ next
+ case False
+ then show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3]
+ \<open>old_document \<noteq> x\<close> \<open>old_document = y\<close> \<open>document_ptr \<noteq> x\<close>
+ by (metis (no_types, lifting) disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ disjoint_iff_not_equal docs_neq notin_set_remove1)
+ qed
+ next
+ case False
+ have "set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}"
+ by (metis DocumentMonad.ptr_kinds_M_ok DocumentMonad.ptr_kinds_M_ptr_kinds False
+ \<open>type_wf h2\<close> a1 disc_nodes_old_document_h2 document_ptr_kinds_M_def
+ document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3
+ l_ptr_kinds_M.ptr_kinds_ptr_kinds_M local.get_disconnected_nodes_ok
+ local.heap_is_wellformed_one_disc_parent returns_result_select_result
+ wellformed_h2)
+ then show ?thesis
+ proof(cases "document_ptr = x")
+ case True
+ then have "document_ptr \<noteq> y"
+ using \<open>x \<noteq> y\<close> by auto
+ have "set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}"
+ using \<open>set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}\<close>
+ by blast
+ then show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3]
+ \<open>old_document \<noteq> x\<close> \<open>old_document \<noteq> y\<close> \<open>document_ptr = x\<close> \<open>document_ptr \<noteq> y\<close>
+ \<open>child \<in> set disc_nodes_old_document_h2\<close> disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3
+ \<open>set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}\<close>
+ by(auto)
+ next
+ case False
+ then show ?thesis
+ proof(cases "document_ptr = y")
+ case True
+ have f1: "set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set disc_nodes_document_ptr_h3 = {}"
+ using 2 a1 document_ptr_in_heap document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3
+ \<open>document_ptr \<noteq> x\<close> select_result_I2[OF disc_nodes_document_ptr_h3, symmetric]
+ disconnected_nodes_eq2_h2[OF docs_neq[symmetric], symmetric]
+ by (simp add: "5" True)
+ moreover have f1:
+ "set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes old_document|\<^sub>r = {}"
+ using 2 a1 old_document_in_heap document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3
+ \<open>old_document \<noteq> x\<close>
+ by (metis (no_types, lifting) a0 distinct_concat_map_E(1) document_ptr_kinds_eq3_h2
+ document_ptr_kinds_eq3_h3 finite_fset fmember.rep_eq set_sorted_list_of_set)
+ ultimately show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_old_document_h2] \<open>old_document \<noteq> x\<close>
+ \<open>document_ptr \<noteq> x\<close> \<open>document_ptr = y\<close>
+ \<open>child \<in> set disc_nodes_old_document_h2\<close> disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3
+ by auto
+ next
+ case False
+ then show ?thesis
+ using 5
+ select_result_I2[OF disc_nodes_old_document_h2] \<open>old_document \<noteq> x\<close>
+ \<open>document_ptr \<noteq> x\<close> \<open>document_ptr \<noteq> y\<close>
+ \<open>child \<in> set disc_nodes_old_document_h2\<close>
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ by (metis \<open>set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}\<close>
+ empty_iff inf.idem)
+ qed
+ qed
+ qed
+ qed
+ qed
+ next
+ fix x xa xb
+ assume 0: "distinct (concat (map (\<lambda>ptr. |h' \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h')))))"
+ and 1: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h2)))))"
+ and 2: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h2). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 3: "xa |\<in>| object_ptr_kinds h'"
+ and 4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 5: "xb |\<in>| document_ptr_kinds h'"
+ and 6: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ then show False
+ using \<open>child \<in> set disc_nodes_old_document_h2\<close> disc_nodes_document_ptr_h'
+ disc_nodes_document_ptr_h2 disc_nodes_old_document_h2 disc_nodes_old_document_h3
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 document_ptr_kinds_eq2_h2
+ document_ptr_kinds_eq2_h3 old_document_in_heap
+ apply(auto)[1]
+ apply(cases "xb = old_document")
+ proof -
+ assume a1: "xb = old_document"
+ assume a2: "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disc_nodes_old_document_h2"
+ assume a3: "h3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r remove1 child disc_nodes_old_document_h2"
+ assume a4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ assume "document_ptr_kinds h2 = document_ptr_kinds h'"
+ assume a5: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h'). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ have f6: "old_document |\<in>| document_ptr_kinds h'"
+ using a1 \<open>xb |\<in>| document_ptr_kinds h'\<close> by blast
+ have f7: "|h2 \<turnstile> get_disconnected_nodes old_document|\<^sub>r = disc_nodes_old_document_h2"
+ using a2 by simp
+ have "x \<in> set disc_nodes_old_document_h2"
+ using f6 a3 a1 by (metis (no_types) \<open>type_wf h'\<close> \<open>x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r\<close>
+ disconnected_nodes_eq_h3 docs_neq get_disconnected_nodes_ok returns_result_eq
+ returns_result_select_result set_remove1_subset subsetCE)
+ then have "set |h' \<turnstile> get_child_nodes xa|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes xb|\<^sub>r = {}"
+ using f7 f6 a5 a4 \<open>xa |\<in>| object_ptr_kinds h'\<close>
+ by fastforce
+ then show ?thesis
+ using \<open>x \<in> set disc_nodes_old_document_h2\<close> a1 a4 f7 by blast
+ next
+ assume a1: "xb \<noteq> old_document"
+ assume a2: "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_document_ptr_h3"
+ assume a3: "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disc_nodes_old_document_h2"
+ assume a4: "xa |\<in>| object_ptr_kinds h'"
+ assume a5: "h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r child # disc_nodes_document_ptr_h3"
+ assume a6: "old_document |\<in>| document_ptr_kinds h'"
+ assume a7: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ assume a8: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ assume a9: "document_ptr_kinds h2 = document_ptr_kinds h'"
+ assume a10: "\<And>doc_ptr. old_document \<noteq> doc_ptr
+ \<Longrightarrow> |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ assume a11: "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ assume a12: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h'). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ have f13: "\<And>d. d \<notin> set |h' \<turnstile> document_ptr_kinds_M|\<^sub>r \<or> h2 \<turnstile> ok get_disconnected_nodes d"
+ using a9 \<open>type_wf h2\<close> get_disconnected_nodes_ok
+ by simp
+ then have f14: "|h2 \<turnstile> get_disconnected_nodes old_document|\<^sub>r = disc_nodes_old_document_h2"
+ using a6 a3 by simp
+ have "x \<notin> set |h2 \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ using a12 a8 a4 \<open>xb |\<in>| document_ptr_kinds h'\<close>
+ by (meson UN_I disjoint_iff_not_equal fmember.rep_eq)
+ then have "x = child"
+ using f13 a11 a10 a7 a5 a2 a1
+ by (metis (no_types, lifting) select_result_I2 set_ConsD)
+ then have "child \<notin> set disc_nodes_old_document_h2"
+ using f14 a12 a8 a6 a4
+ by (metis \<open>type_wf h'\<close> adopt_node_removes_child assms(1) assms(2) type_wf
+ get_child_nodes_ok known_ptrs local.known_ptrs_known_ptr object_ptr_kinds_h2_eq3
+ object_ptr_kinds_h3_eq3 object_ptr_kinds_h_eq3 returns_result_select_result)
+ then show ?thesis
+ using \<open>child \<in> set disc_nodes_old_document_h2\<close> by fastforce
+ qed
+ qed
+ ultimately show ?thesis
+ using \<open>type_wf h'\<close> \<open>known_ptrs h'\<close> \<open>a_owner_document_valid h'\<close> heap_is_wellformed_def by blast
+ qed
+ then show "heap_is_wellformed h'" and "known_ptrs h'" and "type_wf h'"
+ by auto
+qed
+
+lemma adopt_node_node_in_disconnected_nodes:
+ assumes wellformed: "heap_is_wellformed h"
+ and adopt_node: "h \<turnstile> adopt_node owner_document node_ptr \<rightarrow>\<^sub>h h'"
+ and "h' \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "node_ptr \<in> set disc_nodes"
+proof -
+ obtain old_document parent_opt h2 where
+ old_document: "h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r old_document" and
+ parent_opt: "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r parent_opt" and
+ h2: "h \<turnstile> (case parent_opt of Some parent \<Rightarrow> remove_child parent node_ptr | None \<Rightarrow> return ()) \<rightarrow>\<^sub>h h2"
+ and
+ h': "h2 \<turnstile> (if owner_document \<noteq> old_document then do {
+ old_disc_nodes \<leftarrow> get_disconnected_nodes old_document;
+ set_disconnected_nodes old_document (remove1 node_ptr old_disc_nodes);
+ disc_nodes \<leftarrow> get_disconnected_nodes owner_document;
+ set_disconnected_nodes owner_document (node_ptr # disc_nodes)
+ } else do {
+ return ()
+ }) \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ by(auto simp add: adopt_node_def elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_parent_pure])
+
+ show ?thesis
+ proof (cases "owner_document = old_document")
+ case True
+ then show ?thesis
+ proof (insert parent_opt h2, induct parent_opt)
+ case None
+ then have "h = h'"
+ using h2 h' by(auto)
+ then show ?case
+ using in_disconnected_nodes_no_parent assms None old_document by blast
+ next
+ case (Some parent)
+ then show ?case
+ using remove_child_in_disconnected_nodes known_ptrs True h' assms(3) old_document by auto
+ qed
+ next
+ case False
+ then show ?thesis
+ using assms(3) h' list.set_intros(1) select_result_I2 set_disconnected_nodes_get_disconnected_nodes
+ apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated])[1]
+ proof -
+ fix x and h'a and xb
+ assume a1: "h' \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes"
+ assume a2: "\<And>h document_ptr disc_nodes h'. h \<turnstile> set_disconnected_nodes document_ptr disc_nodes \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes"
+ assume "h'a \<turnstile> set_disconnected_nodes owner_document (node_ptr # xb) \<rightarrow>\<^sub>h h'"
+ then have "node_ptr # xb = disc_nodes"
+ using a2 a1 by (meson returns_result_eq)
+ then show ?thesis
+ by (meson list.set_intros(1))
+ qed
+ qed
+qed
+end
+
+interpretation i_adopt_node_wf?: l_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_owner_document get_parent get_parent_locs
+ remove_child remove_child_locs get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs adopt_node adopt_node_locs known_ptr
+ type_wf get_child_nodes get_child_nodes_locs known_ptrs set_child_nodes set_child_nodes_locs
+ remove heap_is_wellformed parent_child_rel
+ by(simp add: l_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+interpretation i_adopt_node_wf2?: l_adopt_node_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_owner_document get_parent get_parent_locs
+ remove_child remove_child_locs get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs adopt_node adopt_node_locs known_ptr
+ type_wf get_child_nodes get_child_nodes_locs known_ptrs set_child_nodes set_child_nodes_locs
+ remove heap_is_wellformed parent_child_rel get_root_node get_root_node_locs
+ by(simp add: l_adopt_node_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_adopt_node_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+locale l_adopt_node_wf = l_heap_is_wellformed + l_known_ptrs + l_type_wf + l_adopt_node_defs
+ + l_get_child_nodes_defs + l_get_disconnected_nodes_defs +
+ assumes adopt_node_preserves_wellformedness:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> adopt_node document_ptr child \<rightarrow>\<^sub>h h' \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> type_wf h \<Longrightarrow> heap_is_wellformed h'"
+ assumes adopt_node_removes_child:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> adopt_node owner_document node_ptr \<rightarrow>\<^sub>h h2
+ \<Longrightarrow> h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> type_wf h \<Longrightarrow> node_ptr \<notin> set children"
+ assumes adopt_node_node_in_disconnected_nodes:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> adopt_node owner_document node_ptr \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes
+ \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h \<Longrightarrow> node_ptr \<in> set disc_nodes"
+ assumes adopt_node_removes_first_child: "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r node # children
+ \<Longrightarrow> h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ assumes adopt_node_document_in_heap: "heap_is_wellformed h \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h
+ \<Longrightarrow> h \<turnstile> ok (adopt_node owner_document node)
+ \<Longrightarrow> owner_document |\<in>| document_ptr_kinds h"
+
+lemma adopt_node_wf_is_l_adopt_node_wf [instances]:
+ "l_adopt_node_wf type_wf known_ptr heap_is_wellformed parent_child_rel get_child_nodes
+ get_disconnected_nodes known_ptrs adopt_node"
+ using heap_is_wellformed_is_l_heap_is_wellformed known_ptrs_is_l_known_ptrs
+ apply(auto simp add: l_adopt_node_wf_def l_adopt_node_wf_axioms_def)[1]
+ using adopt_node_preserves_wellformedness apply blast
+ using adopt_node_removes_child apply blast
+ using adopt_node_node_in_disconnected_nodes apply blast
+ using adopt_node_removes_first_child apply blast
+ using adopt_node_document_in_heap apply blast
+ done
+
+
+subsection \<open>insert\_before\<close>
+
+locale l_insert_before_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_adopt_node_wf +
+ l_set_disconnected_nodes_get_child_nodes +
+ l_heap_is_wellformed
+begin
+lemma insert_before_removes_child:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "ptr \<noteq> ptr'"
+ assumes "h \<turnstile> insert_before ptr node child \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r node # children"
+ shows "h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+proof -
+ obtain owner_document h2 h3 disc_nodes reference_child where
+ "h \<turnstile> (if Some node = child then a_next_sibling node else return child) \<rightarrow>\<^sub>r reference_child" and
+ "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document" and
+ h2: "h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h2" and
+ "h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes" and
+ h3: "h2 \<turnstile> set_disconnected_nodes owner_document (remove1 node disc_nodes) \<rightarrow>\<^sub>h h3" and
+ h': "h3 \<turnstile> a_insert_node ptr node reference_child \<rightarrow>\<^sub>h h'"
+ using assms(5)
+ by(auto simp add: insert_before_def a_ensure_pre_insertion_validity_def
+ elim!: bind_returns_heap_E bind_returns_result_E
+ bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_ancestors_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_owner_document_pure, rotated]
+ bind_returns_heap_E2[rotated, OF next_sibling_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ split: if_splits option.splits)
+
+ have "h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using h2 adopt_node_removes_first_child assms(1) assms(2) assms(3) assms(6)
+ by simp
+ then have "h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using h3
+ by(auto simp add: set_disconnected_nodes_get_child_nodes
+ dest!: reads_writes_separate_forwards[OF get_child_nodes_reads set_disconnected_nodes_writes])
+ then show ?thesis
+ using h' assms(4)
+ apply(auto simp add: a_insert_node_def
+ elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated])[1]
+ by(auto simp add: set_child_nodes_get_child_nodes_different_pointers
+ elim!: reads_writes_separate_forwards[OF get_child_nodes_reads set_child_nodes_writes])
+qed
+end
+
+locale l_insert_before_wf = l_heap_is_wellformed_defs + l_type_wf + l_known_ptrs
+ + l_insert_before_defs + l_get_child_nodes_defs +
+ assumes insert_before_removes_child:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> ptr \<noteq> ptr'
+ \<Longrightarrow> h \<turnstile> insert_before ptr node child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r node # children
+ \<Longrightarrow> h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+
+interpretation i_insert_before_wf?: l_insert_before_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_parent get_parent_locs
+ get_child_nodes get_child_nodes_locs set_child_nodes
+ set_child_nodes_locs get_ancestors get_ancestors_locs
+ adopt_node adopt_node_locs set_disconnected_nodes
+ set_disconnected_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_owner_document insert_before
+ insert_before_locs append_child type_wf known_ptr known_ptrs
+ heap_is_wellformed parent_child_rel
+ by(simp add: l_insert_before_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_insert_before_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma insert_before_wf_is_l_insert_before_wf [instances]:
+ "l_insert_before_wf heap_is_wellformed type_wf known_ptr known_ptrs insert_before get_child_nodes"
+ apply(auto simp add: l_insert_before_wf_def l_insert_before_wf_axioms_def instances)[1]
+ using insert_before_removes_child apply fast
+ done
+
+locale l_insert_before_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_insert_before_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_child_nodes_get_disconnected_nodes +
+ l_remove_child +
+ l_get_root_node_wf +
+ l_set_disconnected_nodes_get_disconnected_nodes_wf +
+ l_set_disconnected_nodes_get_ancestors +
+ l_get_ancestors_wf +
+ l_get_owner_document +
+ l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma insert_before_heap_is_wellformed_preserved:
+ assumes wellformed: "heap_is_wellformed h"
+ and insert_before: "h \<turnstile> insert_before ptr node child \<rightarrow>\<^sub>h h'"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "heap_is_wellformed h'" and "type_wf h'" and "known_ptrs h'"
+proof -
+ obtain ancestors reference_child owner_document h2 h3 disconnected_nodes_h2 where
+ ancestors: "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors" and
+ node_not_in_ancestors: "cast node \<notin> set ancestors" and
+ reference_child:
+ "h \<turnstile> (if Some node = child then a_next_sibling node else return child) \<rightarrow>\<^sub>r reference_child" and
+ owner_document: "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document" and
+ h2: "h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h2" and
+ disconnected_nodes_h2: "h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disconnected_nodes_h2" and
+ h3: "h2 \<turnstile> set_disconnected_nodes owner_document (remove1 node disconnected_nodes_h2) \<rightarrow>\<^sub>h h3" and
+ h': "h3 \<turnstile> a_insert_node ptr node reference_child \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ by(auto simp add: insert_before_def a_ensure_pre_insertion_validity_def
+ elim!: bind_returns_heap_E bind_returns_result_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_ancestors_pure, rotated]
+ bind_returns_heap_E2[rotated, OF next_sibling_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_owner_document_pure, rotated]
+ split: if_splits option.splits)
+
+ have "known_ptr ptr"
+ by (meson get_owner_document_ptr_in_heap is_OK_returns_result_I known_ptrs
+ l_known_ptrs.known_ptrs_known_ptr l_known_ptrs_axioms owner_document)
+
+ have "type_wf h2"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF adopt_node_writes h2]
+ using type_wf adopt_node_types_preserved
+ by(auto simp add: a_remove_child_locs_def reflp_def transp_def)
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h3]
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then show "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF insert_node_writes h']
+ using set_child_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have object_ptr_kinds_M_eq3_h: "object_ptr_kinds h = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF adopt_node_writes h2])
+ using adopt_node_pointers_preserved
+ apply blast
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h: "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs )
+ then have object_ptr_kinds_M_eq2_h: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq2_h: "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+
+ have "known_ptrs h2"
+ using known_ptrs object_ptr_kinds_M_eq3_h known_ptrs_preserved by blast
+
+ have wellformed_h2: "heap_is_wellformed h2"
+ using adopt_node_preserves_wellformedness[OF wellformed h2] known_ptrs type_wf .
+
+ have object_ptr_kinds_M_eq3_h2: "object_ptr_kinds h2 = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h3])
+ unfolding a_remove_child_locs_def
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h2: "\<And>ptrs. h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_M_eq2_h2: "|h2 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq2_h2: "|h2 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ have document_ptr_kinds_eq2_h2: "|h2 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_M_eq2_h2 document_ptr_kinds_M_eq by auto
+
+ have "known_ptrs h3"
+ using object_ptr_kinds_M_eq3_h2 known_ptrs_preserved \<open>known_ptrs h2\<close> by blast
+
+ have object_ptr_kinds_M_eq3_h': "object_ptr_kinds h3 = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF insert_node_writes h'])
+ unfolding a_remove_child_locs_def
+ using set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h3:
+ "\<And>ptrs. h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_M_eq2_h3:
+ "|h3 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq2_h3: "|h3 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ have document_ptr_kinds_eq2_h3: "|h3 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h' \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_M_eq2_h3 document_ptr_kinds_M_eq by auto
+
+ show "known_ptrs h'"
+ using object_ptr_kinds_M_eq3_h' known_ptrs_preserved \<open>known_ptrs h3\<close> by blast
+
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. owner_document \<noteq> doc_ptr
+ \<Longrightarrow> h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by (auto simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. doc_ptr \<noteq> owner_document
+ \<Longrightarrow> |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_h3:
+ "h3 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r remove1 node disconnected_nodes_h2"
+ using h3 set_disconnected_nodes_get_disconnected_nodes
+ by blast
+
+ have disconnected_nodes_eq_h3:
+ "\<And>doc_ptr disc_nodes. h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads insert_node_writes h'
+ apply(rule reads_writes_preserved)
+ using set_child_nodes_get_disconnected_nodes by fast
+ then have disconnected_nodes_eq2_h3:
+ "\<And>doc_ptr. |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by (auto simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h2:
+ "\<And>ptr'. |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h3:
+ "\<And>ptr' children. ptr \<noteq> ptr'
+ \<Longrightarrow> h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads insert_node_writes h'
+ apply(rule reads_writes_preserved)
+ by (auto simp add: set_child_nodes_get_child_nodes_different_pointers)
+ then have children_eq2_h3:
+ "\<And>ptr'. ptr \<noteq> ptr' \<Longrightarrow> |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ obtain children_h3 where children_h3: "h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children_h3"
+ using h' a_insert_node_def by auto
+ have children_h': "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r insert_before_list node reference_child children_h3"
+ using h' \<open>type_wf h3\<close> \<open>known_ptr ptr\<close>
+ by(auto simp add: a_insert_node_def elim!: bind_returns_heap_E2
+ dest!: set_child_nodes_get_child_nodes returns_result_eq[OF children_h3])
+
+ have ptr_in_heap: "ptr |\<in>| object_ptr_kinds h3"
+ using children_h3 get_child_nodes_ptr_in_heap by blast
+ have node_in_heap: "node |\<in>| node_ptr_kinds h"
+ using h2 adopt_node_child_in_heap by fast
+ have child_not_in_any_children:
+ "\<And>p children. h2 \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children \<Longrightarrow> node \<notin> set children"
+ using wellformed h2 adopt_node_removes_child \<open>type_wf h\<close> \<open>known_ptrs h\<close> by auto
+ have "node \<in> set disconnected_nodes_h2"
+ using disconnected_nodes_h2 h2 adopt_node_node_in_disconnected_nodes assms(1)
+ \<open>type_wf h\<close> \<open>known_ptrs h\<close> by blast
+ have node_not_in_disconnected_nodes:
+ "\<And>d. d |\<in>| document_ptr_kinds h3 \<Longrightarrow> node \<notin> set |h3 \<turnstile> get_disconnected_nodes d|\<^sub>r"
+ proof -
+ fix d
+ assume "d |\<in>| document_ptr_kinds h3"
+ show "node \<notin> set |h3 \<turnstile> get_disconnected_nodes d|\<^sub>r"
+ proof (cases "d = owner_document")
+ case True
+ then show ?thesis
+ using disconnected_nodes_h2 wellformed_h2 h3 remove_from_disconnected_nodes_removes
+ wellformed_h2 \<open>d |\<in>| document_ptr_kinds h3\<close> disconnected_nodes_h3
+ by fastforce
+ next
+ case False
+ then have
+ "set |h2 \<turnstile> get_disconnected_nodes d|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes owner_document|\<^sub>r = {}"
+ using distinct_concat_map_E(1) wellformed_h2
+ by (metis (no_types, lifting) \<open>d |\<in>| document_ptr_kinds h3\<close> \<open>type_wf h2\<close>
+ disconnected_nodes_h2 document_ptr_kinds_M_def document_ptr_kinds_eq2_h2
+ l_ptr_kinds_M.ptr_kinds_ptr_kinds_M local.get_disconnected_nodes_ok
+ local.heap_is_wellformed_one_disc_parent returns_result_select_result
+ select_result_I2)
+ then show ?thesis
+ using disconnected_nodes_eq2_h2[OF False] \<open>node \<in> set disconnected_nodes_h2\<close>
+ disconnected_nodes_h2 by fastforce
+ qed
+ qed
+
+ have "cast node \<noteq> ptr"
+ using ancestors node_not_in_ancestors get_ancestors_ptr
+ by fast
+
+ obtain ancestors_h2 where ancestors_h2: "h2 \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors_h2"
+ using get_ancestors_ok object_ptr_kinds_M_eq2_h2 \<open>known_ptrs h2\<close> \<open>type_wf h2\<close>
+ by (metis is_OK_returns_result_E object_ptr_kinds_M_eq3_h2 ptr_in_heap wellformed_h2)
+ have ancestors_h3: "h3 \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors_h2"
+ using get_ancestors_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_separate_forwards)
+ using \<open>heap_is_wellformed h2\<close> ancestors_h2
+ by (auto simp add: set_disconnected_nodes_get_ancestors)
+ have node_not_in_ancestors_h2: "cast node \<notin> set ancestors_h2"
+ apply(rule get_ancestors_remains_not_in_ancestors[OF assms(1) wellformed_h2 ancestors ancestors_h2])
+ using adopt_node_children_subset using h2 \<open>known_ptrs h\<close> \<open> type_wf h\<close> apply(blast)
+ using node_not_in_ancestors apply(blast)
+ using object_ptr_kinds_M_eq3_h apply(blast)
+ using \<open>known_ptrs h\<close> apply(blast)
+ using \<open>type_wf h\<close> apply(blast)
+ using \<open>type_wf h2\<close> by blast
+
+ moreover have "a_acyclic_heap h'"
+ proof -
+ have "acyclic (parent_child_rel h2)"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def acyclic_heap_def)
+ then have "acyclic (parent_child_rel h3)"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_M_eq3_h2 children_eq2_h2)
+ moreover have "cast node \<notin> {x. (x, ptr) \<in> (parent_child_rel h2)\<^sup>*}"
+ using get_ancestors_parent_child_rel node_not_in_ancestors_h2 \<open>known_ptrs h2\<close> \<open>type_wf h2\<close>
+ using ancestors_h2 wellformed_h2 by blast
+ then have "cast node \<notin> {x. (x, ptr) \<in> (parent_child_rel h3)\<^sup>*}"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_M_eq3_h2 children_eq2_h2)
+ moreover have "parent_child_rel h' = insert (ptr, cast node) ((parent_child_rel h3))"
+ using children_h3 children_h' ptr_in_heap
+ apply(auto simp add: parent_child_rel_def object_ptr_kinds_M_eq3_h' children_eq2_h3
+ insert_before_list_node_in_set)[1]
+ apply (metis (no_types, lifting) children_eq2_h3 insert_before_list_in_set select_result_I2)
+ by (metis (no_types, lifting) children_eq2_h3 imageI insert_before_list_in_set select_result_I2)
+ ultimately show ?thesis
+ by(auto simp add: acyclic_heap_def)
+ qed
+
+
+ moreover have "a_all_ptrs_in_heap h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def)
+ have "a_all_ptrs_in_heap h'"
+ proof -
+ have "a_all_ptrs_in_heap h3"
+ using \<open>a_all_ptrs_in_heap h2\<close>
+ apply(auto simp add: a_all_ptrs_in_heap_def object_ptr_kinds_M_eq2_h2 node_ptr_kinds_eq2_h2
+ children_eq_h2)[1]
+ using disconnected_nodes_eq2_h2 disconnected_nodes_h2 disconnected_nodes_h3
+ using node_ptr_kinds_eq2_h2 apply auto[1]
+ apply (metis \<open>known_ptrs h2\<close> \<open>type_wf h3\<close> children_eq_h2 local.get_child_nodes_ok
+ local.heap_is_wellformed_children_in_heap local.known_ptrs_known_ptr object_ptr_kinds_M_eq3_h2
+ returns_result_select_result wellformed_h2)
+ by (metis (no_types, lifting) disconnected_nodes_eq2_h2 disconnected_nodes_h2
+ disconnected_nodes_h3 document_ptr_kinds_commutes finite_set_in node_ptr_kinds_commutes
+ object_ptr_kinds_M_eq3_h2 select_result_I2 set_remove1_subset subsetD)
+
+ have "set children_h3 \<subseteq> set |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using children_h3 \<open>a_all_ptrs_in_heap h3\<close>
+ apply(auto simp add: a_all_ptrs_in_heap_def node_ptr_kinds_eq2_h3)[1]
+ by (metis children_eq_h2 l_heap_is_wellformed.heap_is_wellformed_children_in_heap
+ local.l_heap_is_wellformed_axioms node_ptr_kinds_commutes object_ptr_kinds_M_eq3_h'
+ object_ptr_kinds_M_eq3_h2 wellformed_h2)
+
+ then have "set (insert_before_list node reference_child children_h3) \<subseteq> set |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_in_heap
+ apply(auto simp add: node_ptr_kinds_eq2_h node_ptr_kinds_eq2_h2 node_ptr_kinds_eq2_h3)[1]
+ by (metis (no_types, hide_lams) contra_subsetD finite_set_in insert_before_list_in_set
+ node_ptr_kinds_commutes object_ptr_kinds_M_eq3_h object_ptr_kinds_M_eq3_h'
+ object_ptr_kinds_M_eq3_h2)
+ then show ?thesis
+ using \<open>a_all_ptrs_in_heap h3\<close>
+ apply(auto simp add: object_ptr_kinds_M_eq3_h' a_all_ptrs_in_heap_def node_ptr_kinds_def
+ node_ptr_kinds_eq2_h3 disconnected_nodes_eq_h3)[1]
+ using children_eq_h3 children_h'
+ apply (metis (no_types, lifting) children_eq2_h3 finite_set_in select_result_I2 subsetD)
+ by (metis (no_types) \<open>type_wf h'\<close> disconnected_nodes_eq2_h3 disconnected_nodes_eq_h3
+ finite_set_in is_OK_returns_result_I local.get_disconnected_nodes_ok
+ local.get_disconnected_nodes_ptr_in_heap returns_result_select_result subsetD)
+ qed
+
+ moreover have "a_distinct_lists h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def)
+ then have "a_distinct_lists h3"
+ proof(auto simp add: a_distinct_lists_def object_ptr_kinds_M_eq2_h2 document_ptr_kinds_eq2_h2
+ children_eq2_h2 intro!: distinct_concat_map_I)[1]
+ fix x
+ assume 1: "x |\<in>| document_ptr_kinds h3"
+ and 2: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ show "distinct |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using distinct_concat_map_E(2)[OF 2] select_result_I2[OF disconnected_nodes_h3]
+ disconnected_nodes_eq2_h2 select_result_I2[OF disconnected_nodes_h2] 1
+ by (metis (full_types) distinct_remove1 finite_fset fmember.rep_eq set_sorted_list_of_set)
+ next
+ fix x y xa
+ assume 1: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and 2: "x |\<in>| document_ptr_kinds h3"
+ and 3: "y |\<in>| document_ptr_kinds h3"
+ and 4: "x \<noteq> y"
+ and 5: "xa \<in> set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ and 6: "xa \<in> set |h3 \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ show False
+ proof (cases "x = owner_document")
+ case True
+ then have "y \<noteq> owner_document"
+ using 4 by simp
+ show ?thesis
+ using distinct_concat_map_E(1)[OF 1]
+ using 2 3 4 5 6 select_result_I2[OF disconnected_nodes_h3] select_result_I2[OF disconnected_nodes_h2]
+ apply(auto simp add: True disconnected_nodes_eq2_h2[OF \<open>y \<noteq> owner_document\<close>])[1]
+ by (metis (no_types, hide_lams) disconnected_nodes_eq2_h2 disjoint_iff_not_equal notin_set_remove1)
+ next
+ case False
+ then show ?thesis
+ proof (cases "y = owner_document")
+ case True
+ then show ?thesis
+ using distinct_concat_map_E(1)[OF 1]
+ using 2 3 4 5 6 select_result_I2[OF disconnected_nodes_h3] select_result_I2[OF disconnected_nodes_h2]
+ apply(auto simp add: True disconnected_nodes_eq2_h2[OF \<open>x \<noteq> owner_document\<close>])[1]
+ by (metis (no_types, hide_lams) disconnected_nodes_eq2_h2 disjoint_iff_not_equal notin_set_remove1)
+ next
+ case False
+ then show ?thesis
+ using distinct_concat_map_E(1)[OF 1, simplified, OF 2 3 4] 5 6
+ using disconnected_nodes_eq2_h2 disconnected_nodes_h2 disconnected_nodes_h3
+ disjoint_iff_not_equal finite_fset fmember.rep_eq notin_set_remove1 select_result_I2
+ set_sorted_list_of_set
+ by (metis (no_types, lifting))
+ qed
+ qed
+ next
+ fix x xa xb
+ assume 1: "(\<Union>x\<in>fset (object_ptr_kinds h3). set |h3 \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h3). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 2: "xa |\<in>| object_ptr_kinds h3"
+ and 3: "x \<in> set |h3 \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 4: "xb |\<in>| document_ptr_kinds h3"
+ and 5: "x \<in> set |h3 \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ have 6: "set |h3 \<turnstile> get_child_nodes xa|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes xb|\<^sub>r = {}"
+ using 1 2 4
+ by (metis \<open>type_wf h2\<close> children_eq2_h2 document_ptr_kinds_commutes known_ptrs
+ local.get_child_nodes_ok local.get_disconnected_nodes_ok
+ local.heap_is_wellformed_children_disc_nodes_different local.known_ptrs_known_ptr
+ object_ptr_kinds_M_eq3_h object_ptr_kinds_M_eq3_h2 returns_result_select_result
+ wellformed_h2)
+ show False
+ proof (cases "xb = owner_document")
+ case True
+ then show ?thesis
+ using select_result_I2[OF disconnected_nodes_h3,folded select_result_I2[OF disconnected_nodes_h2]]
+ by (metis (no_types, lifting) "3" "5" "6" disjoint_iff_not_equal notin_set_remove1)
+ next
+ case False
+ show ?thesis
+ using 2 3 4 5 6 unfolding disconnected_nodes_eq2_h2[OF False] by auto
+ qed
+ qed
+ then have "a_distinct_lists h'"
+ proof(auto simp add: a_distinct_lists_def document_ptr_kinds_eq2_h3 object_ptr_kinds_M_eq2_h3
+ disconnected_nodes_eq2_h3 intro!: distinct_concat_map_I)[1]
+ fix x
+ assume 1: "distinct (concat (map (\<lambda>ptr. |h3 \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h')))))" and
+ 2: "x |\<in>| object_ptr_kinds h'"
+ have 3: "\<And>p. p |\<in>| object_ptr_kinds h' \<Longrightarrow> distinct |h3 \<turnstile> get_child_nodes p|\<^sub>r"
+ using 1 by (auto elim: distinct_concat_map_E)
+ show "distinct |h' \<turnstile> get_child_nodes x|\<^sub>r"
+ proof(cases "ptr = x")
+ case True
+ show ?thesis
+ using 3[OF 2] children_h3 children_h'
+ by(auto simp add: True insert_before_list_distinct
+ dest: child_not_in_any_children[unfolded children_eq_h2])
+ next
+ case False
+ show ?thesis
+ using children_eq2_h3[OF False] 3[OF 2] by auto
+ qed
+ next
+ fix x y xa
+ assume 1: "distinct (concat (map (\<lambda>ptr. |h3 \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h')))))"
+ and 2: "x |\<in>| object_ptr_kinds h'"
+ and 3: "y |\<in>| object_ptr_kinds h'"
+ and 4: "x \<noteq> y"
+ and 5: "xa \<in> set |h' \<turnstile> get_child_nodes x|\<^sub>r"
+ and 6: "xa \<in> set |h' \<turnstile> get_child_nodes y|\<^sub>r"
+ have 7:"set |h3 \<turnstile> get_child_nodes x|\<^sub>r \<inter> set |h3 \<turnstile> get_child_nodes y|\<^sub>r = {}"
+ using distinct_concat_map_E(1)[OF 1] 2 3 4 by auto
+ show False
+ proof (cases "ptr = x")
+ case True
+ then have "ptr \<noteq> y"
+ using 4 by simp
+ then show ?thesis
+ using children_h3 children_h' child_not_in_any_children[unfolded children_eq_h2] 5 6
+ apply(auto simp add: True children_eq2_h3[OF \<open>ptr \<noteq> y\<close>])[1]
+ by (metis (no_types, hide_lams) "3" "7" \<open>type_wf h3\<close> children_eq2_h3 disjoint_iff_not_equal
+ get_child_nodes_ok insert_before_list_in_set known_ptrs local.known_ptrs_known_ptr
+ object_ptr_kinds_M_eq3_h object_ptr_kinds_M_eq3_h'
+ object_ptr_kinds_M_eq3_h2 returns_result_select_result select_result_I2)
+ next
+ case False
+ then show ?thesis
+ proof (cases "ptr = y")
+ case True
+ then show ?thesis
+ using children_h3 children_h' child_not_in_any_children[unfolded children_eq_h2] 5 6
+ apply(auto simp add: True children_eq2_h3[OF \<open>ptr \<noteq> x\<close>])[1]
+ by (metis (no_types, hide_lams) "2" "4" "7" IntI \<open>known_ptrs h3\<close> \<open>type_wf h'\<close>
+ children_eq_h3 empty_iff insert_before_list_in_set local.get_child_nodes_ok
+ local.known_ptrs_known_ptr object_ptr_kinds_M_eq3_h'
+ returns_result_select_result select_result_I2)
+ next
+ case False
+ then show ?thesis
+ using children_eq2_h3[OF \<open>ptr \<noteq> x\<close>] children_eq2_h3[OF \<open>ptr \<noteq> y\<close>] 5 6 7 by auto
+ qed
+ qed
+ next
+ fix x xa xb
+ assume 1: " (\<Union>x\<in>fset (object_ptr_kinds h'). set |h3 \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h'). set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r) = {} "
+ and 2: "xa |\<in>| object_ptr_kinds h'"
+ and 3: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 4: "xb |\<in>| document_ptr_kinds h'"
+ and 5: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ have 6: "set |h3 \<turnstile> get_child_nodes xa|\<^sub>r \<inter> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r = {}"
+ using 1 2 3 4 5
+ proof -
+ have "\<forall>h d. \<not> type_wf h \<or> d |\<notin>| document_ptr_kinds h \<or> h \<turnstile> ok get_disconnected_nodes d"
+ using local.get_disconnected_nodes_ok by satx
+ then have "h' \<turnstile> ok get_disconnected_nodes xb"
+ using "4" \<open>type_wf h'\<close> by fastforce
+ then have f1: "h3 \<turnstile> get_disconnected_nodes xb \<rightarrow>\<^sub>r |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ by (simp add: disconnected_nodes_eq_h3)
+ have "xa |\<in>| object_ptr_kinds h3"
+ using "2" object_ptr_kinds_M_eq3_h' by blast
+ then show ?thesis
+ using f1 \<open>local.a_distinct_lists h3\<close> local.distinct_lists_no_parent by fastforce
+ qed
+ show False
+ proof (cases "ptr = xa")
+ case True
+ show ?thesis
+ using 6 node_not_in_disconnected_nodes 3 4 5 select_result_I2[OF children_h']
+ select_result_I2[OF children_h3] True disconnected_nodes_eq2_h3
+ by (metis (no_types, lifting) "2" DocumentMonad.ptr_kinds_ptr_kinds_M
+ \<open>a_distinct_lists h3\<close> \<open>type_wf h'\<close> disconnected_nodes_eq_h3
+ distinct_lists_no_parent document_ptr_kinds_eq2_h3 get_disconnected_nodes_ok
+ insert_before_list_in_set object_ptr_kinds_M_eq3_h' returns_result_select_result)
+
+ next
+ case False
+ then show ?thesis
+ using 1 2 3 4 5 children_eq2_h3[OF False] by fastforce
+ qed
+ qed
+
+ moreover have "a_owner_document_valid h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def)
+ then have "a_owner_document_valid h'"
+ apply(auto simp add: a_owner_document_valid_def object_ptr_kinds_M_eq2_h2
+ object_ptr_kinds_M_eq2_h3 node_ptr_kinds_eq2_h2 node_ptr_kinds_eq2_h3
+ document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3 children_eq2_h2)[1]
+ apply(auto simp add: document_ptr_kinds_eq2_h2[simplified] document_ptr_kinds_eq2_h3[simplified]
+ object_ptr_kinds_M_eq2_h2[simplified] object_ptr_kinds_M_eq2_h3[simplified]
+ node_ptr_kinds_eq2_h2[simplified] node_ptr_kinds_eq2_h3[simplified])[1]
+ apply(auto simp add: disconnected_nodes_eq2_h3[symmetric])[1]
+ by (smt children_eq2_h3 children_h' children_h3 disconnected_nodes_eq2_h2 disconnected_nodes_h2
+ disconnected_nodes_h3 finite_set_in in_set_remove1 insert_before_list_in_set
+ object_ptr_kinds_M_eq3_h' ptr_in_heap select_result_I2)
+
+ ultimately show "heap_is_wellformed h'"
+ by (simp add: heap_is_wellformed_def)
+qed
+end
+
+locale l_insert_before_wf2 = l_type_wf + l_known_ptrs + l_insert_before_defs
+ + l_heap_is_wellformed_defs + l_get_child_nodes_defs + l_remove_defs +
+ assumes insert_before_preserves_type_wf:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> insert_before ptr child ref \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> type_wf h'"
+ assumes insert_before_preserves_known_ptrs:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> insert_before ptr child ref \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> known_ptrs h'"
+ assumes insert_before_heap_is_wellformed_preserved:
+ "type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> heap_is_wellformed h \<Longrightarrow> h \<turnstile> insert_before ptr child ref \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> heap_is_wellformed h'"
+
+interpretation i_insert_before_wf2?: l_insert_before_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_parent get_parent_locs
+ get_child_nodes get_child_nodes_locs set_child_nodes
+ set_child_nodes_locs get_ancestors get_ancestors_locs
+ adopt_node adopt_node_locs set_disconnected_nodes
+ set_disconnected_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_owner_document insert_before
+ insert_before_locs append_child type_wf known_ptr known_ptrs
+ heap_is_wellformed parent_child_rel remove_child
+ remove_child_locs get_root_node get_root_node_locs
+ by(simp add: l_insert_before_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_insert_before_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma insert_before_wf2_is_l_insert_before_wf2 [instances]:
+ "l_insert_before_wf2 type_wf known_ptr known_ptrs insert_before heap_is_wellformed"
+ apply(auto simp add: l_insert_before_wf2_def l_insert_before_wf2_axioms_def instances)[1]
+ using insert_before_heap_is_wellformed_preserved apply(fast, fast, fast)
+ done
+
+locale l_append_child_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_insert_before_wf +
+ l_insert_before_wf2 +
+ l_get_child_nodes
+begin
+
+
+lemma append_child_heap_is_wellformed_preserved:
+ assumes wellformed: "heap_is_wellformed h"
+ and append_child: "h \<turnstile> append_child ptr node \<rightarrow>\<^sub>h h'"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "heap_is_wellformed h'" and "type_wf h'" and "known_ptrs h'"
+ using assms
+ by(auto simp add: append_child_def intro: insert_before_preserves_type_wf
+ insert_before_preserves_known_ptrs insert_before_heap_is_wellformed_preserved)
+
+lemma append_child_children:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs"
+ assumes "h \<turnstile> append_child ptr node \<rightarrow>\<^sub>h h'"
+ assumes "node \<notin> set xs"
+ shows "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs @ [node]"
+proof -
+
+ obtain ancestors owner_document h2 h3 disconnected_nodes_h2 where
+ ancestors: "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors" and
+ node_not_in_ancestors: "cast node \<notin> set ancestors" and
+ owner_document: "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document" and
+ h2: "h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h2" and
+ disconnected_nodes_h2: "h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disconnected_nodes_h2" and
+ h3: "h2 \<turnstile> set_disconnected_nodes owner_document (remove1 node disconnected_nodes_h2) \<rightarrow>\<^sub>h h3" and
+ h': "h3 \<turnstile> a_insert_node ptr node None \<rightarrow>\<^sub>h h'"
+ using assms(5)
+ by(auto simp add: append_child_def insert_before_def a_ensure_pre_insertion_validity_def
+ elim!: bind_returns_heap_E bind_returns_result_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_ancestors_pure, rotated]
+ bind_returns_heap_E2[rotated, OF next_sibling_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_owner_document_pure, rotated]
+ split: if_splits option.splits)
+
+ have "\<And>parent. |h \<turnstile> get_parent node|\<^sub>r = Some parent \<Longrightarrow> parent \<noteq> ptr"
+ using assms(1) assms(4) assms(6)
+ by (metis (no_types, lifting) assms(2) assms(3) h2 is_OK_returns_heap_I is_OK_returns_result_E
+ local.adopt_node_child_in_heap local.get_parent_child_dual local.get_parent_ok
+ select_result_I2)
+ have "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs"
+ using get_child_nodes_reads adopt_node_writes h2 assms(4)
+ apply(rule reads_writes_separate_forwards)
+ using \<open>\<And>parent. |h \<turnstile> get_parent node|\<^sub>r = Some parent \<Longrightarrow> parent \<noteq> ptr\<close>
+ apply(auto simp add: adopt_node_locs_def remove_child_locs_def)[1]
+ by (meson local.set_child_nodes_get_child_nodes_different_pointers)
+
+ have "h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs"
+ using get_child_nodes_reads set_disconnected_nodes_writes h3 \<open>h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs\<close>
+ apply(rule reads_writes_separate_forwards)
+ by(auto)
+
+ have "ptr |\<in>| object_ptr_kinds h"
+ by (meson ancestors is_OK_returns_result_I local.get_ancestors_ptr_in_heap)
+ then
+ have "known_ptr ptr"
+ using assms(3)
+ using local.known_ptrs_known_ptr by blast
+
+ have "type_wf h2"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF adopt_node_writes h2]
+ using adopt_node_types_preserved \<open>type_wf h\<close>
+ by(auto simp add: adopt_node_locs_def remove_child_locs_def reflp_def transp_def split: if_splits)
+ then
+ have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h3]
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ show "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs@[node]"
+ using h'
+ apply(auto simp add: a_insert_node_def
+ dest!: bind_returns_heap_E3[rotated, OF \<open>h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs\<close>
+ get_child_nodes_pure, rotated])[1]
+ using \<open>type_wf h3\<close> set_child_nodes_get_child_nodes \<open>known_ptr ptr\<close>
+ by metis
+qed
+
+lemma append_child_for_all_on_children:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs"
+ assumes "h \<turnstile> forall_M (append_child ptr) nodes \<rightarrow>\<^sub>h h'"
+ assumes "set nodes \<inter> set xs = {}"
+ assumes "distinct nodes"
+ shows "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs@nodes"
+ using assms
+ apply(induct nodes arbitrary: h xs)
+ apply(simp)
+proof(auto elim!: bind_returns_heap_E)[1]fix a nodes h xs h'a
+ assume 0: "(\<And>h xs. heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs \<Longrightarrow> h \<turnstile> forall_M (append_child ptr) nodes \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> set nodes \<inter> set xs = {} \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs @ nodes)"
+ and 1: "heap_is_wellformed h"
+ and 2: "type_wf h"
+ and 3: "known_ptrs h"
+ and 4: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs"
+ and 5: "h \<turnstile> append_child ptr a \<rightarrow>\<^sub>r ()"
+ and 6: "h \<turnstile> append_child ptr a \<rightarrow>\<^sub>h h'a"
+ and 7: "h'a \<turnstile> forall_M (append_child ptr) nodes \<rightarrow>\<^sub>h h'"
+ and 8: "a \<notin> set xs"
+ and 9: "set nodes \<inter> set xs = {}"
+ and 10: "a \<notin> set nodes"
+ and 11: "distinct nodes"
+ then have "h'a \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs @ [a]"
+ using append_child_children 6
+ using "1" "2" "3" "4" "8" by blast
+
+ moreover have "heap_is_wellformed h'a" and "type_wf h'a" and "known_ptrs h'a"
+ using insert_before_heap_is_wellformed_preserved insert_before_preserves_known_ptrs
+ insert_before_preserves_type_wf 1 2 3 6 append_child_def
+ by metis+
+ moreover have "set nodes \<inter> set (xs @ [a]) = {}"
+ using 9 10
+ by auto
+ ultimately show "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs @ a # nodes"
+ using 0 7
+ by fastforce
+qed
+
+
+lemma append_child_for_all_on_no_children:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r []"
+ assumes "h \<turnstile> forall_M (append_child ptr) nodes \<rightarrow>\<^sub>h h'"
+ assumes "distinct nodes"
+ shows "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r nodes"
+ using assms append_child_for_all_on_children
+ by force
+end
+
+locale l_append_child_wf = l_type_wf + l_known_ptrs + l_append_child_defs + l_heap_is_wellformed_defs +
+ assumes append_child_preserves_type_wf:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> append_child ptr child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> type_wf h'"
+ assumes append_child_preserves_known_ptrs:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> append_child ptr child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> known_ptrs h'"
+ assumes append_child_heap_is_wellformed_preserved:
+ "type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> heap_is_wellformed h \<Longrightarrow> h \<turnstile> append_child ptr child \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> heap_is_wellformed h'"
+
+interpretation i_append_child_wf?: l_append_child_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_owner_document get_parent
+ get_parent_locs remove_child remove_child_locs
+ get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs
+ adopt_node adopt_node_locs known_ptr type_wf get_child_nodes
+ get_child_nodes_locs known_ptrs set_child_nodes
+ set_child_nodes_locs remove get_ancestors get_ancestors_locs
+ insert_before insert_before_locs append_child heap_is_wellformed
+ parent_child_rel
+ by(auto simp add: l_append_child_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+
+lemma append_child_wf_is_l_append_child_wf [instances]: "l_append_child_wf type_wf known_ptr
+known_ptrs append_child heap_is_wellformed"
+ apply(auto simp add: l_append_child_wf_def l_append_child_wf_axioms_def instances)[1]
+ using append_child_heap_is_wellformed_preserved by fast+
+
+
+subsection \<open>create\_element\<close>
+
+locale l_create_element_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs
+ heap_is_wellformed parent_child_rel +
+ l_new_element_get_disconnected_nodes get_disconnected_nodes get_disconnected_nodes_locs +
+ l_set_tag_name_get_disconnected_nodes type_wf set_tag_name set_tag_name_locs
+ get_disconnected_nodes get_disconnected_nodes_locs +
+ l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs set_tag_name set_tag_name_locs type_wf create_element known_ptr +
+ l_new_element_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs +
+ l_set_tag_name_get_child_nodes type_wf set_tag_name set_tag_name_locs known_ptr
+ get_child_nodes get_child_nodes_locs +
+ l_set_disconnected_nodes_get_child_nodes set_disconnected_nodes set_disconnected_nodes_locs
+ get_child_nodes get_child_nodes_locs +
+ l_set_disconnected_nodes type_wf set_disconnected_nodes set_disconnected_nodes_locs +
+ l_set_disconnected_nodes_get_disconnected_nodes type_wf get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs +
+ l_new_element type_wf +
+ l_known_ptrs known_ptr known_ptrs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and set_tag_name :: "(_) element_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and create_element :: "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+begin
+lemma create_element_preserves_wellformedness:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>h h'"
+ and "type_wf h"
+ and "known_ptrs h"
+ shows "heap_is_wellformed h'" and "type_wf h'" and "known_ptrs h'"
+proof -
+ obtain new_element_ptr h2 h3 disc_nodes_h3 where
+ new_element_ptr: "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr" and
+ h2: "h \<turnstile> new_element \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile> set_tag_name new_element_ptr tag \<rightarrow>\<^sub>h h3" and
+ disc_nodes_h3: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_element_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ by(auto simp add: create_element_def
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+ then have "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr"
+ apply(auto simp add: create_element_def intro!: bind_returns_result_I)[1]
+ apply (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ apply (metis is_OK_returns_heap_E is_OK_returns_result_I local.get_disconnected_nodes_pure
+ pure_returns_heap_eq)
+ by (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+
+ have "new_element_ptr \<notin> set |h \<turnstile> element_ptr_kinds_M|\<^sub>r"
+ using new_element_ptr ElementMonad.ptr_kinds_ptr_kinds_M h2
+ using new_element_ptr_not_in_heap by blast
+ then have "cast new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have "cast new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+
+ have object_ptr_kinds_eq_h: "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ using new_element_new_ptr h2 new_element_ptr by blast
+ then have node_ptr_kinds_eq_h: "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h |\<union>| {|new_element_ptr|}"
+ apply(simp add: element_ptr_kinds_def)
+ by force
+ have character_data_ptr_kinds_eq_h: "character_data_ptr_kinds h2 = character_data_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def character_data_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_tag_name_writes h3])
+ using set_tag_name_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+ have "known_ptr (cast new_element_ptr)"
+ using \<open>h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr\<close> local.create_element_known_ptr
+ by blast
+ then
+ have "known_ptrs h2"
+ using known_ptrs_new_ptr object_ptr_kinds_eq_h \<open>known_ptrs h\<close> h2
+ by blast
+ then
+ have "known_ptrs h3"
+ using known_ptrs_preserved object_ptr_kinds_eq_h2 by blast
+ then
+ show "known_ptrs h'"
+ using known_ptrs_preserved object_ptr_kinds_eq_h3 by blast
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_element_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads h2 get_child_nodes_new_element[rotated, OF new_element_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h: "\<And>ptr'. ptr' \<noteq> cast new_element_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []"
+ using new_element_ptr h2 new_element_ptr_in_heap[OF h2 new_element_ptr]
+ new_element_is_element_ptr[OF new_element_ptr] new_element_no_child_nodes
+ by blast
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads h2 get_disconnected_nodes_new_element[OF new_element_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have disconnected_nodes_eq2_h:
+ "\<And>doc_ptr. |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_tag_name_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_tag_name_get_child_nodes)
+ then have children_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_tag_name_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_tag_name_get_disconnected_nodes)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have "type_wf h2"
+ using \<open>type_wf h\<close> new_element_types_preserved h2 by blast
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_tag_name_writes h3]
+ using set_tag_name_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then show "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_eq_h3:
+ "\<And>ptr' children. h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h3: "\<And>ptr'. |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h3:
+ "\<And>doc_ptr disc_nodes. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h3:
+ "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have disc_nodes_document_ptr_h2: "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h2 disc_nodes_h3 by auto
+ then have disc_nodes_document_ptr_h: "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h by auto
+ then have "cast new_element_ptr \<notin> set disc_nodes_h3"
+ using \<open>heap_is_wellformed h\<close>
+ using \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ a_all_ptrs_in_heap_def heap_is_wellformed_def
+ using NodeMonad.ptr_kinds_ptr_kinds_M local.heap_is_wellformed_disc_nodes_in_heap by blast
+
+ have "acyclic (parent_child_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def acyclic_heap_def)
+ also have "parent_child_rel h = parent_child_rel h2"
+ proof(auto simp add: parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h2"
+ by (simp add: object_ptr_kinds_eq_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq_h \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting)
+ \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2_h empty_iff empty_set image_eqI select_result_I2)
+ qed
+ also have "\<dots> = parent_child_rel h3"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h2 children_eq2_h2)
+ also have "\<dots> = parent_child_rel h'"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h3 children_eq2_h3)
+ finally have "a_acyclic_heap h'"
+ by (simp add: acyclic_heap_def)
+
+ have "a_all_ptrs_in_heap h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def)
+ then have "a_all_ptrs_in_heap h2"
+ apply(auto simp add: a_all_ptrs_in_heap_def)[1]
+ apply (metis \<open>known_ptrs h2\<close> \<open>parent_child_rel h = parent_child_rel h2\<close> \<open>type_wf h2\<close> assms(1)
+ assms(3) funion_iff local.get_child_nodes_ok local.known_ptrs_known_ptr
+ local.parent_child_rel_child_in_heap local.parent_child_rel_child_nodes2 node_ptr_kinds_commutes
+ node_ptr_kinds_eq_h returns_result_select_result)
+ by (metis assms(1) assms(3) disconnected_nodes_eq2_h document_ptr_kinds_eq_h funion_iff
+ local.get_disconnected_nodes_ok local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_eq_h
+ returns_result_select_result)
+ then have "a_all_ptrs_in_heap h3"
+ by (simp add: children_eq2_h2 disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ local.a_all_ptrs_in_heap_def node_ptr_kinds_eq_h2 object_ptr_kinds_eq_h2)
+ then have "a_all_ptrs_in_heap h'"
+ by (smt \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close> children_eq2_h3
+ disc_nodes_document_ptr_h2 disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ document_ptr_kinds_eq_h3 finite_set_in h' is_OK_returns_result_I
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ local.a_all_ptrs_in_heap_def local.get_child_nodes_ptr_in_heap
+ local.l_set_disconnected_nodes_get_disconnected_nodes_axioms node_ptr_kinds_commutes
+ object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 select_result_I2 set_ConsD subset_code(1))
+
+ have "\<And>p. p |\<in>| object_ptr_kinds h \<Longrightarrow> cast new_element_ptr \<notin> set |h \<turnstile> get_child_nodes p|\<^sub>r"
+ using \<open>heap_is_wellformed h\<close> \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ heap_is_wellformed_children_in_heap
+ by (meson NodeMonad.ptr_kinds_ptr_kinds_M a_all_ptrs_in_heap_def assms(3) assms(4) fset_mp
+ fset_of_list_elem get_child_nodes_ok known_ptrs_known_ptr returns_result_select_result)
+ then have "\<And>p. p |\<in>| object_ptr_kinds h2 \<Longrightarrow> cast new_element_ptr \<notin> set |h2 \<turnstile> get_child_nodes p|\<^sub>r"
+ using children_eq2_h
+ apply(auto simp add: object_ptr_kinds_eq_h)[1]
+ using \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close> apply auto[1]
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>)
+ then have "\<And>p. p |\<in>| object_ptr_kinds h3 \<Longrightarrow> cast new_element_ptr \<notin> set |h3 \<turnstile> get_child_nodes p|\<^sub>r"
+ using object_ptr_kinds_eq_h2 children_eq2_h2 by auto
+ then have new_element_ptr_not_in_any_children:
+ "\<And>p. p |\<in>| object_ptr_kinds h' \<Longrightarrow> cast new_element_ptr \<notin> set |h' \<turnstile> get_child_nodes p|\<^sub>r"
+ using object_ptr_kinds_eq_h3 children_eq2_h3 by auto
+
+ have "a_distinct_lists h"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def)
+ then have "a_distinct_lists h2"
+
+ using \<open>h2 \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ apply(auto simp add: a_distinct_lists_def object_ptr_kinds_eq_h document_ptr_kinds_eq_h
+ disconnected_nodes_eq2_h intro!: distinct_concat_map_I)[1]
+ apply (metis distinct_sorted_list_of_set finite_fset sorted_list_of_set_insert)
+ apply(case_tac "x=cast new_element_ptr")
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply (metis IntI assms(1) assms(3) assms(4) empty_iff local.get_child_nodes_ok
+ local.heap_is_wellformed_one_parent local.known_ptrs_known_ptr returns_result_select_result)
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ by (metis \<open>local.a_distinct_lists h\<close> \<open>type_wf h2\<close> disconnected_nodes_eq_h document_ptr_kinds_eq_h
+ local.distinct_lists_no_parent local.get_disconnected_nodes_ok returns_result_select_result)
+
+ then have "a_distinct_lists h3"
+ by(auto simp add: a_distinct_lists_def disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ children_eq2_h2 object_ptr_kinds_eq_h2)
+ then have "a_distinct_lists h'"
+ proof(auto simp add: a_distinct_lists_def disconnected_nodes_eq2_h3 children_eq2_h3
+ object_ptr_kinds_eq_h3 document_ptr_kinds_eq_h3
+ intro!: distinct_concat_map_I)[1]
+ fix x
+ assume "distinct (concat (map (\<lambda>document_ptr. |h3 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and "x |\<in>| document_ptr_kinds h3"
+ then show "distinct |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using document_ptr_kinds_eq_h3 disconnected_nodes_eq_h3 h' set_disconnected_nodes_get_disconnected_nodes
+ by (metis (no_types, lifting) \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set disc_nodes_h3\<close>
+ \<open>a_distinct_lists h3\<close> \<open>type_wf h'\<close> disc_nodes_h3 distinct.simps(2)
+ distinct_lists_disconnected_nodes get_disconnected_nodes_ok returns_result_eq
+ returns_result_select_result)
+ next
+ fix x y xa
+ assume "distinct (concat (map (\<lambda>document_ptr. |h3 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and "x |\<in>| document_ptr_kinds h3"
+ and "y |\<in>| document_ptr_kinds h3"
+ and "x \<noteq> y"
+ and "xa \<in> set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ and "xa \<in> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ moreover have "set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h3 \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ using calculation by(auto dest: distinct_concat_map_E(1))
+ ultimately show "False"
+ apply(-)
+ apply(cases "x = document_ptr")
+ apply (smt NodeMonad.ptr_kinds_ptr_kinds_M \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ \<open>local.a_all_ptrs_in_heap h\<close>
+ disc_nodes_h3 disconnected_nodes_eq2_h disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ disjoint_iff_not_equal document_ptr_kinds_eq_h document_ptr_kinds_eq_h2 finite_set_in h'
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ local.a_all_ptrs_in_heap_def local.l_set_disconnected_nodes_get_disconnected_nodes_axioms
+ select_result_I2 set_ConsD subsetD)
+ by (smt NodeMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close> \<open>local.a_all_ptrs_in_heap h\<close>
+ disc_nodes_document_ptr_h2 disconnected_nodes_eq2_h disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3
+ disjoint_iff_not_equal document_ptr_kinds_eq_h document_ptr_kinds_eq_h2 finite_set_in h'
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ local.a_all_ptrs_in_heap_def local.l_set_disconnected_nodes_get_disconnected_nodes_axioms
+ select_result_I2 set_ConsD subsetD)
+ next
+ fix x xa xb
+ assume 2: "(\<Union>x\<in>fset (object_ptr_kinds h3). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h3). set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 3: "xa |\<in>| object_ptr_kinds h3"
+ and 4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 5: "xb |\<in>| document_ptr_kinds h3"
+ and 6: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ show "False"
+ using disc_nodes_document_ptr_h disconnected_nodes_eq2_h3
+ apply -
+ apply(cases "xb = document_ptr")
+ apply (metis (no_types, hide_lams) "3" "4" "6"
+ \<open>\<And>p. p |\<in>| object_ptr_kinds h3
+ \<Longrightarrow> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h3 \<turnstile> get_child_nodes p|\<^sub>r\<close>
+ \<open>a_distinct_lists h3\<close> children_eq2_h3 disc_nodes_h3 distinct_lists_no_parent h'
+ select_result_I2 set_ConsD set_disconnected_nodes_get_disconnected_nodes)
+ by (metis "3" "4" "5" "6" \<open>a_distinct_lists h3\<close> \<open>type_wf h3\<close> children_eq2_h3
+ distinct_lists_no_parent get_disconnected_nodes_ok returns_result_select_result)
+ qed
+
+ have "a_owner_document_valid h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def)
+ then have "a_owner_document_valid h'"
+ using disc_nodes_h3 \<open>document_ptr |\<in>| document_ptr_kinds h\<close>
+ apply(auto simp add: a_owner_document_valid_def)[1]
+ apply(auto simp add: object_ptr_kinds_eq_h object_ptr_kinds_eq_h3 )[1]
+ apply(auto simp add: object_ptr_kinds_eq_h2)[1]
+ apply(auto simp add: document_ptr_kinds_eq_h document_ptr_kinds_eq_h3 )[1]
+ apply(auto simp add: document_ptr_kinds_eq_h2)[1]
+ apply(auto simp add: node_ptr_kinds_eq_h node_ptr_kinds_eq_h3 )[1]
+ apply(auto simp add: node_ptr_kinds_eq_h2 node_ptr_kinds_eq_h )[1]
+ apply(auto simp add: children_eq2_h2[symmetric] children_eq2_h3[symmetric]
+ disconnected_nodes_eq2_h disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3)[1]
+ apply (metis (no_types, lifting) document_ptr_kinds_eq_h h' list.set_intros(1)
+ local.set_disconnected_nodes_get_disconnected_nodes select_result_I2)
+ apply(simp add: object_ptr_kinds_eq_h)
+ by(metis (no_types, lifting) NodeMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close> children_eq2_h children_eq2_h2
+ children_eq2_h3 disconnected_nodes_eq2_h disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ document_ptr_kinds_eq_h finite_set_in h'
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ list.set_intros(2) local.l_set_disconnected_nodes_get_disconnected_nodes_axioms
+ node_ptr_kinds_commutes select_result_I2)
+
+ show "heap_is_wellformed h'"
+ using \<open>a_acyclic_heap h'\<close> \<open>a_all_ptrs_in_heap h'\<close> \<open>a_distinct_lists h'\<close> \<open>a_owner_document_valid h'\<close>
+ by(simp add: heap_is_wellformed_def)
+qed
+end
+
+interpretation i_create_element_wf?: l_create_element_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr known_ptrs type_wf
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs heap_is_wellformed parent_child_rel
+ set_tag_name set_tag_name_locs
+ set_disconnected_nodes set_disconnected_nodes_locs create_element
+ using instances
+ by(auto simp add: l_create_element_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_create_element_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsection \<open>create\_character\_data\<close>
+
+locale l_create_character_data_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs heap_is_wellformed parent_child_rel
+ + l_new_character_data_get_disconnected_nodes
+ get_disconnected_nodes get_disconnected_nodes_locs
+ + l_set_val_get_disconnected_nodes
+ type_wf set_val set_val_locs get_disconnected_nodes get_disconnected_nodes_locs
+ + l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs set_val set_val_locs type_wf create_character_data known_ptr
+ + l_new_character_data_get_child_nodes
+ type_wf known_ptr get_child_nodes get_child_nodes_locs
+ + l_set_val_get_child_nodes
+ type_wf set_val set_val_locs known_ptr get_child_nodes get_child_nodes_locs
+ + l_set_disconnected_nodes_get_child_nodes
+ set_disconnected_nodes set_disconnected_nodes_locs get_child_nodes get_child_nodes_locs
+ + l_set_disconnected_nodes
+ type_wf set_disconnected_nodes set_disconnected_nodes_locs
+ + l_set_disconnected_nodes_get_disconnected_nodes
+ type_wf get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs
+ + l_new_character_data
+ type_wf
+ + l_known_ptrs
+ known_ptr known_ptrs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and set_val :: "(_) character_data_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_val_locs :: "(_) character_data_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_disconnected_nodes ::
+ "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and create_character_data ::
+ "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) character_data_ptr) prog"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+begin
+
+lemma create_character_data_preserves_wellformedness:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>h h'"
+ and "type_wf h"
+ and "known_ptrs h"
+ shows "heap_is_wellformed h'" and "type_wf h'" and "known_ptrs h'"
+proof -
+ obtain new_character_data_ptr h2 h3 disc_nodes_h3 where
+ new_character_data_ptr: "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr" and
+ h2: "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile> set_val new_character_data_ptr text \<rightarrow>\<^sub>h h3" and
+ disc_nodes_h3: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_character_data_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ by(auto simp add: create_character_data_def
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+ then have "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr"
+ apply(auto simp add: create_character_data_def intro!: bind_returns_result_I)[1]
+ apply (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ apply (metis is_OK_returns_heap_E is_OK_returns_result_I local.get_disconnected_nodes_pure
+ pure_returns_heap_eq)
+ by (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+
+
+ have "new_character_data_ptr \<notin> set |h \<turnstile> character_data_ptr_kinds_M|\<^sub>r"
+ using new_character_data_ptr CharacterDataMonad.ptr_kinds_ptr_kinds_M h2
+ using new_character_data_ptr_not_in_heap by blast
+ then have "cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have "cast new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+
+
+
+ have object_ptr_kinds_eq_h:
+ "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using new_character_data_new_ptr h2 new_character_data_ptr by blast
+ then have node_ptr_kinds_eq_h:
+ "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have character_data_ptr_kinds_eq_h:
+ "character_data_ptr_kinds h2 = character_data_ptr_kinds h |\<union>| {|new_character_data_ptr|}"
+ apply(simp add: character_data_ptr_kinds_def)
+ by force
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_val_writes h3])
+ using set_val_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+ have "known_ptr (cast new_character_data_ptr)"
+ using \<open>h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr\<close>
+ local.create_character_data_known_ptr by blast
+ then
+ have "known_ptrs h2"
+ using known_ptrs_new_ptr object_ptr_kinds_eq_h \<open>known_ptrs h\<close> h2
+ by blast
+ then
+ have "known_ptrs h3"
+ using known_ptrs_preserved object_ptr_kinds_eq_h2 by blast
+ then
+ show "known_ptrs h'"
+ using known_ptrs_preserved object_ptr_kinds_eq_h3 by blast
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads h2 get_child_nodes_new_character_data[rotated, OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h:
+ "\<And>ptr'. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have object_ptr_kinds_eq_h:
+ "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using new_character_data_new_ptr h2 new_character_data_ptr by blast
+ then have node_ptr_kinds_eq_h:
+ "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have character_data_ptr_kinds_eq_h:
+ "character_data_ptr_kinds h2 = character_data_ptr_kinds h |\<union>| {|new_character_data_ptr|}"
+ apply(simp add: character_data_ptr_kinds_def)
+ by force
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_val_writes h3])
+ using set_val_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads h2 get_child_nodes_new_character_data[rotated, OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h: "\<And>ptr'. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []"
+ using new_character_data_ptr h2 new_character_data_ptr_in_heap[OF h2 new_character_data_ptr]
+ new_character_data_is_character_data_ptr[OF new_character_data_ptr]
+ new_character_data_no_child_nodes
+ by blast
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads h2
+ get_disconnected_nodes_new_character_data[OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have disconnected_nodes_eq2_h:
+ "\<And>doc_ptr. |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_val_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_val_get_child_nodes)
+ then have children_eq2_h2:
+ "\<And>ptr'. |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_val_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_val_get_disconnected_nodes)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have "type_wf h2"
+ using \<open>type_wf h\<close> new_character_data_types_preserved h2 by blast
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_val_writes h3]
+ using set_val_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then show "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_eq_h3:
+ "\<And>ptr' children. h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h3:
+ " \<And>ptr'. |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h3: "\<And>doc_ptr disc_nodes. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h3: "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have disc_nodes_document_ptr_h2: "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h2 disc_nodes_h3 by auto
+ then have disc_nodes_document_ptr_h: "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h by auto
+ then have "cast new_character_data_ptr \<notin> set disc_nodes_h3"
+ using \<open>heap_is_wellformed h\<close> using \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ a_all_ptrs_in_heap_def heap_is_wellformed_def
+ using NodeMonad.ptr_kinds_ptr_kinds_M local.heap_is_wellformed_disc_nodes_in_heap by blast
+
+ have "acyclic (parent_child_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def acyclic_heap_def)
+ also have "parent_child_rel h = parent_child_rel h2"
+ proof(auto simp add: parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h2"
+ by (simp add: object_ptr_kinds_eq_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq_h \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting) \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2_h empty_iff empty_set image_eqI select_result_I2)
+ qed
+ also have "\<dots> = parent_child_rel h3"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h2 children_eq2_h2)
+ also have "\<dots> = parent_child_rel h'"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h3 children_eq2_h3)
+ finally have "a_acyclic_heap h'"
+ by (simp add: acyclic_heap_def)
+
+ have "a_all_ptrs_in_heap h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def)
+ then have "a_all_ptrs_in_heap h2"
+ apply(auto simp add: a_all_ptrs_in_heap_def)[1]
+ using node_ptr_kinds_eq_h \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ apply (metis (no_types, lifting) NodeMonad.ptr_kinds_ptr_kinds_M \<open>parent_child_rel h = parent_child_rel h2\<close>
+ children_eq2_h finite_set_in finsert_iff funion_finsert_right local.parent_child_rel_child
+ local.parent_child_rel_parent_in_heap node_ptr_kinds_commutes object_ptr_kinds_eq_h
+ select_result_I2 subsetD sup_bot.right_neutral)
+ by (metis assms(1) assms(3) disconnected_nodes_eq2_h document_ptr_kinds_eq_h funionI1
+ local.get_disconnected_nodes_ok local.heap_is_wellformed_disc_nodes_in_heap
+ node_ptr_kinds_eq_h returns_result_select_result)
+ then have "a_all_ptrs_in_heap h3"
+ by (simp add: children_eq2_h2 disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ local.a_all_ptrs_in_heap_def node_ptr_kinds_eq_h2 object_ptr_kinds_eq_h2)
+ then have "a_all_ptrs_in_heap h'"
+ by (smt character_data_ptr_kinds_commutes children_eq2_h3 disc_nodes_document_ptr_h2
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 document_ptr_kinds_eq_h3
+ finite_set_in h' h2 local.a_all_ptrs_in_heap_def
+ local.set_disconnected_nodes_get_disconnected_nodes new_character_data_ptr
+ new_character_data_ptr_in_heap node_ptr_kinds_eq_h2 node_ptr_kinds_eq_h3
+ object_ptr_kinds_eq_h3 select_result_I2 set_ConsD subset_code(1))
+ have "\<And>p. p |\<in>| object_ptr_kinds h \<Longrightarrow> cast new_character_data_ptr \<notin> set |h \<turnstile> get_child_nodes p|\<^sub>r"
+ using \<open>heap_is_wellformed h\<close> \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ heap_is_wellformed_children_in_heap
+ by (meson NodeMonad.ptr_kinds_ptr_kinds_M a_all_ptrs_in_heap_def assms(3) assms(4) fset_mp
+ fset_of_list_elem get_child_nodes_ok known_ptrs_known_ptr returns_result_select_result)
+ then have "\<And>p. p |\<in>| object_ptr_kinds h2 \<Longrightarrow> cast new_character_data_ptr \<notin> set |h2 \<turnstile> get_child_nodes p|\<^sub>r"
+ using children_eq2_h
+ apply(auto simp add: object_ptr_kinds_eq_h)[1]
+ using \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close> apply auto[1]
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>)
+ then have "\<And>p. p |\<in>| object_ptr_kinds h3 \<Longrightarrow> cast new_character_data_ptr \<notin> set |h3 \<turnstile> get_child_nodes p|\<^sub>r"
+ using object_ptr_kinds_eq_h2 children_eq2_h2 by auto
+ then have new_character_data_ptr_not_in_any_children:
+ "\<And>p. p |\<in>| object_ptr_kinds h' \<Longrightarrow> cast new_character_data_ptr \<notin> set |h' \<turnstile> get_child_nodes p|\<^sub>r"
+ using object_ptr_kinds_eq_h3 children_eq2_h3 by auto
+
+ have "a_distinct_lists h"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def)
+ then have "a_distinct_lists h2"
+ using \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ apply(auto simp add: a_distinct_lists_def object_ptr_kinds_eq_h document_ptr_kinds_eq_h
+ disconnected_nodes_eq2_h intro!: distinct_concat_map_I)[1]
+ apply (metis distinct_sorted_list_of_set finite_fset sorted_list_of_set_insert)
+ apply(case_tac "x=cast new_character_data_ptr")
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply (metis IntI assms(1) assms(3) assms(4) empty_iff local.get_child_nodes_ok
+ local.heap_is_wellformed_one_parent local.known_ptrs_known_ptr
+ returns_result_select_result)
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ by (metis \<open>local.a_distinct_lists h\<close> \<open>type_wf h2\<close> disconnected_nodes_eq_h document_ptr_kinds_eq_h
+ local.distinct_lists_no_parent local.get_disconnected_nodes_ok returns_result_select_result)
+ then have "a_distinct_lists h3"
+ by(auto simp add: a_distinct_lists_def disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ children_eq2_h2 object_ptr_kinds_eq_h2)[1]
+ then have "a_distinct_lists h'"
+ proof(auto simp add: a_distinct_lists_def disconnected_nodes_eq2_h3 children_eq2_h3
+ object_ptr_kinds_eq_h3 document_ptr_kinds_eq_h3 intro!: distinct_concat_map_I)[1]
+ fix x
+ assume "distinct (concat (map (\<lambda>document_ptr. |h3 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and "x |\<in>| document_ptr_kinds h3"
+ then show "distinct |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using document_ptr_kinds_eq_h3 disconnected_nodes_eq_h3 h' set_disconnected_nodes_get_disconnected_nodes
+ by (metis (no_types, lifting) \<open>cast new_character_data_ptr \<notin> set disc_nodes_h3\<close>
+ \<open>a_distinct_lists h3\<close> \<open>type_wf h'\<close> disc_nodes_h3 distinct.simps(2)
+ distinct_lists_disconnected_nodes get_disconnected_nodes_ok returns_result_eq
+ returns_result_select_result)
+ next
+ fix x y xa
+ assume "distinct (concat (map (\<lambda>document_ptr. |h3 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and "x |\<in>| document_ptr_kinds h3"
+ and "y |\<in>| document_ptr_kinds h3"
+ and "x \<noteq> y"
+ and "xa \<in> set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ and "xa \<in> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ moreover have "set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h3 \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ using calculation by(auto dest: distinct_concat_map_E(1))
+ ultimately show "False"
+ by (smt NodeMonad.ptr_kinds_ptr_kinds_M \<open>cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ \<open>local.a_all_ptrs_in_heap h\<close> disc_nodes_document_ptr_h2 disconnected_nodes_eq2_h
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 disjoint_iff_not_equal
+ document_ptr_kinds_eq_h document_ptr_kinds_eq_h2 finite_set_in h'
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ local.a_all_ptrs_in_heap_def local.l_set_disconnected_nodes_get_disconnected_nodes_axioms
+ select_result_I2 set_ConsD subsetD)
+ next
+ fix x xa xb
+ assume 2: "(\<Union>x\<in>fset (object_ptr_kinds h3). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h3). set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 3: "xa |\<in>| object_ptr_kinds h3"
+ and 4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 5: "xb |\<in>| document_ptr_kinds h3"
+ and 6: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ show "False"
+ using disc_nodes_document_ptr_h disconnected_nodes_eq2_h3
+ apply(cases "xb = document_ptr")
+ apply (metis (no_types, hide_lams) "3" "4" "6"
+ \<open>\<And>p. p |\<in>| object_ptr_kinds h3 \<Longrightarrow> cast new_character_data_ptr \<notin> set |h3 \<turnstile> get_child_nodes p|\<^sub>r\<close>
+ \<open>a_distinct_lists h3\<close> children_eq2_h3 disc_nodes_h3 distinct_lists_no_parent h'
+ select_result_I2 set_ConsD set_disconnected_nodes_get_disconnected_nodes)
+ by (metis "3" "4" "5" "6" \<open>a_distinct_lists h3\<close> \<open>type_wf h3\<close> children_eq2_h3
+ distinct_lists_no_parent get_disconnected_nodes_ok returns_result_select_result)
+ qed
+
+ have "a_owner_document_valid h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def)
+ then have "a_owner_document_valid h'"
+ using disc_nodes_h3 \<open>document_ptr |\<in>| document_ptr_kinds h\<close>
+ apply(simp add: a_owner_document_valid_def)
+ apply(simp add: object_ptr_kinds_eq_h object_ptr_kinds_eq_h3 )
+ apply(simp add: object_ptr_kinds_eq_h2)
+ apply(simp add: document_ptr_kinds_eq_h document_ptr_kinds_eq_h3 )
+ apply(simp add: document_ptr_kinds_eq_h2)
+ apply(simp add: node_ptr_kinds_eq_h node_ptr_kinds_eq_h3 )
+ apply(simp add: node_ptr_kinds_eq_h2 node_ptr_kinds_eq_h )
+ apply(auto simp add: children_eq2_h2[symmetric] children_eq2_h3[symmetric] disconnected_nodes_eq2_h
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3)[1]
+ apply (metis (no_types, lifting) document_ptr_kinds_eq_h h' list.set_intros(1)
+ local.set_disconnected_nodes_get_disconnected_nodes select_result_I2)
+ apply(simp add: object_ptr_kinds_eq_h)
+ by (metis (mono_tags, lifting) \<open>cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>
+ children_eq2_h disconnected_nodes_eq2_h3 document_ptr_kinds_eq_h finite_set_in h'
+ l_ptr_kinds_M.ptr_kinds_ptr_kinds_M
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ list.set_intros(2) local.l_set_disconnected_nodes_get_disconnected_nodes_axioms object_ptr_kinds_M_def
+ select_result_I2)
+
+
+ show "heap_is_wellformed h'"
+ using \<open>a_acyclic_heap h'\<close> \<open>a_all_ptrs_in_heap h'\<close> \<open>a_distinct_lists h'\<close> \<open>a_owner_document_valid h'\<close>
+ by(simp add: heap_is_wellformed_def)
+qed
+end
+
+interpretation i_create_character_data_wf?: l_create_character_data_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ heap_is_wellformed parent_child_rel set_val set_val_locs set_disconnected_nodes
+ set_disconnected_nodes_locs create_character_data known_ptrs
+ using instances
+ by (auto simp add: l_create_character_data_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_create_character_data_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsection \<open>create\_document\<close>
+
+locale l_create_document_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs heap_is_wellformed parent_child_rel
+ + l_new_document_get_disconnected_nodes
+ get_disconnected_nodes get_disconnected_nodes_locs
+ + l_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ create_document
+ + l_new_document_get_child_nodes
+ type_wf known_ptr get_child_nodes get_child_nodes_locs
+ + l_new_document
+ type_wf
+ + l_known_ptrs
+ known_ptr known_ptrs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and set_val :: "(_) character_data_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_val_locs :: "(_) character_data_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and create_document :: "((_) heap, exception, (_) document_ptr) prog"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+begin
+
+lemma create_document_preserves_wellformedness:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> create_document \<rightarrow>\<^sub>h h'"
+ and "type_wf h"
+ and "known_ptrs h"
+ shows "heap_is_wellformed h'"
+proof -
+ obtain new_document_ptr where
+ new_document_ptr: "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr" and
+ h': "h \<turnstile> new_document \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ apply(simp add: create_document_def)
+ using new_document_ok by blast
+
+ have "new_document_ptr \<notin> set |h \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using new_document_ptr DocumentMonad.ptr_kinds_ptr_kinds_M
+ using new_document_ptr_not_in_heap h' by blast
+ then have "cast new_document_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+
+ have "new_document_ptr |\<notin>| document_ptr_kinds h"
+ using new_document_ptr DocumentMonad.ptr_kinds_ptr_kinds_M
+ using new_document_ptr_not_in_heap h' by blast
+ then have "cast new_document_ptr |\<notin>| object_ptr_kinds h"
+ by simp
+
+ have object_ptr_kinds_eq: "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_document_ptr|}"
+ using new_document_new_ptr h' new_document_ptr by blast
+ then have node_ptr_kinds_eq: "node_ptr_kinds h' = node_ptr_kinds h"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have character_data_ptr_kinds_eq_h: "character_data_ptr_kinds h' = character_data_ptr_kinds h"
+ by(simp add: character_data_ptr_kinds_def)
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h' = element_ptr_kinds h"
+ using object_ptr_kinds_eq
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h' = document_ptr_kinds h |\<union>| {|new_document_ptr|}"
+ using object_ptr_kinds_eq
+ apply(auto simp add: document_ptr_kinds_def)[1]
+ by (metis (no_types, lifting) document_ptr_kinds_commutes document_ptr_kinds_def finsertI1 fset.map_comp)
+
+
+ have children_eq:
+ "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_document_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads h' get_child_nodes_new_document[rotated, OF new_document_ptr h']
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2: "\<And>ptr'. ptr' \<noteq> cast new_document_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+
+ have "h' \<turnstile> get_child_nodes (cast new_document_ptr) \<rightarrow>\<^sub>r []"
+ using new_document_ptr h' new_document_ptr_in_heap[OF h' new_document_ptr]
+ new_document_is_document_ptr[OF new_document_ptr] new_document_no_child_nodes
+ by blast
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. doc_ptr \<noteq> new_document_ptr
+ \<Longrightarrow> h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads h' get_disconnected_nodes_new_document_different_pointers new_document_ptr
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by (metis(full_types) \<open>\<And>thesis. (\<And>new_document_ptr.
+ \<lbrakk>h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr; h \<turnstile> new_document \<rightarrow>\<^sub>h h'\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis\<close>
+ local.get_disconnected_nodes_new_document_different_pointers new_document_ptr)+
+ then have disconnected_nodes_eq2_h: "\<And>doc_ptr. doc_ptr \<noteq> new_document_ptr
+ \<Longrightarrow> |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have "h' \<turnstile> get_disconnected_nodes new_document_ptr \<rightarrow>\<^sub>r []"
+ using h' local.new_document_no_disconnected_nodes new_document_ptr by blast
+
+ have "type_wf h'"
+ using \<open>type_wf h\<close> new_document_types_preserved h' by blast
+
+ have "acyclic (parent_child_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def acyclic_heap_def)
+ also have "parent_child_rel h = parent_child_rel h'"
+ proof(auto simp add: parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h'"
+ by (simp add: object_ptr_kinds_eq)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h' \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast new_document_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h'"
+ and 1: "x \<in> set |h' \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq \<open>h' \<turnstile> get_child_nodes (cast new_document_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h'"
+ and 1: "x \<in> set |h' \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting) \<open>h' \<turnstile> get_child_nodes (cast new_document_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2 empty_iff empty_set image_eqI select_result_I2)
+ qed
+ finally have "a_acyclic_heap h'"
+ by (simp add: acyclic_heap_def)
+
+ have "a_all_ptrs_in_heap h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def)
+ then have "a_all_ptrs_in_heap h'"
+ apply(auto simp add: a_all_ptrs_in_heap_def)[1]
+ using ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>
+ \<open>parent_child_rel h = parent_child_rel h'\<close> assms(1) children_eq fset_of_list_elem
+ local.heap_is_wellformed_children_in_heap local.parent_child_rel_child
+ local.parent_child_rel_parent_in_heap node_ptr_kinds_eq
+ apply (metis (no_types, lifting) \<open>h' \<turnstile> get_child_nodes (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2 finite_set_in finsert_iff funion_finsert_right object_ptr_kinds_eq
+ select_result_I2 subsetD sup_bot.right_neutral)
+ by (metis (no_types, lifting) \<open>cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr |\<notin>| object_ptr_kinds h\<close>
+ \<open>h' \<turnstile> get_child_nodes (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr) \<rightarrow>\<^sub>r []\<close>
+ \<open>h' \<turnstile> get_disconnected_nodes new_document_ptr \<rightarrow>\<^sub>r []\<close>
+ \<open>parent_child_rel h = parent_child_rel h'\<close> \<open>type_wf h'\<close> assms(1) disconnected_nodes_eq_h
+ local.get_disconnected_nodes_ok
+ local.heap_is_wellformed_disc_nodes_in_heap local.parent_child_rel_child
+ local.parent_child_rel_parent_in_heap
+ node_ptr_kinds_eq returns_result_select_result select_result_I2)
+ have "a_distinct_lists h"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def)
+ then have "a_distinct_lists h'"
+ using \<open>h' \<turnstile> get_disconnected_nodes new_document_ptr \<rightarrow>\<^sub>r []\<close>
+ \<open>h' \<turnstile> get_child_nodes (cast new_document_ptr) \<rightarrow>\<^sub>r []\<close>
+
+ apply(auto simp add: children_eq2[symmetric] a_distinct_lists_def insort_split object_ptr_kinds_eq
+ document_ptr_kinds_eq_h disconnected_nodes_eq2_h intro!: distinct_concat_map_I)[1]
+ apply (metis distinct_sorted_list_of_set finite_fset sorted_list_of_set_insert)
+
+ apply(auto simp add: dest: distinct_concat_map_E)[1]
+ apply(auto simp add: dest: distinct_concat_map_E)[1]
+ using \<open>new_document_ptr |\<notin>| document_ptr_kinds h\<close>
+ apply(auto simp add: distinct_insort dest: distinct_concat_map_E)[1]
+ using disconnected_nodes_eq_h
+ apply (metis assms(1) assms(3) disconnected_nodes_eq2_h local.get_disconnected_nodes_ok
+ local.heap_is_wellformed_disconnected_nodes_distinct
+ returns_result_select_result)
+ proof -
+ fix x :: "(_) document_ptr" and y :: "(_) document_ptr" and xa :: "(_) node_ptr"
+ assume a1: "x \<noteq> y"
+ assume a2: "x |\<in>| document_ptr_kinds h"
+ assume a3: "x \<noteq> new_document_ptr"
+ assume a4: "y |\<in>| document_ptr_kinds h"
+ assume a5: "y \<noteq> new_document_ptr"
+ assume a6: "distinct (concat (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h)))))"
+ assume a7: "xa \<in> set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ assume a8: "xa \<in> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ have f9: "xa \<in> set |h \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using a7 a3 disconnected_nodes_eq2_h by presburger
+ have f10: "xa \<in> set |h \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ using a8 a5 disconnected_nodes_eq2_h by presburger
+ have f11: "y \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))"
+ using a4 by simp
+ have "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))"
+ using a2 by simp
+ then show False
+ using f11 f10 f9 a6 a1 by (meson disjoint_iff_not_equal distinct_concat_map_E(1))
+ next
+ fix x xa xb
+ assume 0: "h' \<turnstile> get_disconnected_nodes new_document_ptr \<rightarrow>\<^sub>r []"
+ and 1: "h' \<turnstile> get_child_nodes (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr) \<rightarrow>\<^sub>r []"
+ and 2: "distinct (concat (map (\<lambda>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h)))))"
+ and 3: "distinct (concat (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h)))))"
+ and 4: "(\<Union>x\<in>fset (object_ptr_kinds h). set |h \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h). set |h \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 5: "x \<in> set |h \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 6: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ and 7: "xa |\<in>| object_ptr_kinds h"
+ and 8: "xa \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr"
+ and 9: "xb |\<in>| document_ptr_kinds h"
+ and 10: "xb \<noteq> new_document_ptr"
+ then show "False"
+
+ by (metis \<open>local.a_distinct_lists h\<close> assms(3) disconnected_nodes_eq2_h
+ local.distinct_lists_no_parent local.get_disconnected_nodes_ok
+ returns_result_select_result)
+ qed
+
+ have "a_owner_document_valid h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def)
+ then have "a_owner_document_valid h'"
+ apply(auto simp add: a_owner_document_valid_def)[1]
+ by (metis \<open>cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr |\<notin>| object_ptr_kinds h\<close>
+ children_eq2 disconnected_nodes_eq2_h document_ptr_kinds_commutes finite_set_in
+ funion_iff node_ptr_kinds_eq object_ptr_kinds_eq)
+ show "heap_is_wellformed h'"
+ using \<open>a_acyclic_heap h'\<close> \<open>a_all_ptrs_in_heap h'\<close> \<open>a_distinct_lists h'\<close> \<open>a_owner_document_valid h'\<close>
+ by(simp add: heap_is_wellformed_def)
+qed
+end
+
+interpretation i_create_document_wf?: l_create_document_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes
+ get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs heap_is_wellformed parent_child_rel
+ set_val set_val_locs set_disconnected_nodes
+ set_disconnected_nodes_locs create_document known_ptrs
+ using instances
+ by (auto simp add: l_create_document_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_create_document_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+end
diff --git a/thys/Core_SC_DOM/safely_composable/classes/ElementClass.thy b/thys/Core_SC_DOM/safely_composable/classes/ElementClass.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/safely_composable/classes/ElementClass.thy
@@ -0,0 +1,327 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Element\<close>
+text\<open>In this theory, we introduce the types for the Element class.\<close>
+theory ElementClass
+ imports
+ "NodeClass"
+ "ShadowRootPointer"
+begin
+text\<open>The type @{type "DOMString"} is a type synonym for @{type "string"}, define
+ in \autoref{sec:Core_DOM_Basic_Datatypes}.\<close>
+type_synonym attr_key = DOMString
+type_synonym attr_value = DOMString
+type_synonym attrs = "(attr_key, attr_value) fmap"
+type_synonym tag_name = DOMString
+record ('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr) RElement = RNode +
+ nothing :: unit
+ tag_name :: tag_name
+ child_nodes :: "('node_ptr, 'element_ptr, 'character_data_ptr) node_ptr list"
+ attrs :: attrs
+ shadow_root_opt :: "'shadow_root_ptr shadow_root_ptr option"
+type_synonym
+ ('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Element) Element
+ = "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Element option) RElement_scheme"
+register_default_tvars
+ "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Element) Element"
+type_synonym
+ ('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Node, 'Element) Node
+ = "(('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Element option) RElement_ext + 'Node) Node"
+register_default_tvars
+ "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Node, 'Element) Node"
+type_synonym
+ ('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Object, 'Node, 'Element) Object
+ = "('Object, ('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Element option)
+RElement_ext + 'Node) Object"
+register_default_tvars
+ "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Object, 'Node, 'Element) Object"
+
+type_synonym
+ ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr, 'shadow_root_ptr,
+ 'Object, 'Node, 'Element) heap
+ = "(('document_ptr, 'shadow_root_ptr) document_ptr + 'object_ptr, 'element_ptr element_ptr +
+'character_data_ptr character_data_ptr + 'node_ptr, 'Object,
+ ('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Element option)
+RElement_ext + 'Node) heap"
+register_default_tvars
+ "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr, 'shadow_root_ptr,
+'Object, 'Node, 'Element) heap"
+type_synonym heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l = "(unit, unit, unit, unit, unit, unit, unit, unit, unit) heap"
+
+definition element_ptr_kinds :: "(_) heap \<Rightarrow> (_) element_ptr fset"
+ where
+ "element_ptr_kinds heap = the |`| (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r |`|
+(ffilter is_element_ptr_kind (node_ptr_kinds heap)))"
+
+lemma element_ptr_kinds_simp [simp]:
+ "element_ptr_kinds (Heap (fmupd (cast element_ptr) element (the_heap h))) =
+{|element_ptr|} |\<union>| element_ptr_kinds h"
+ apply(auto simp add: element_ptr_kinds_def)[1]
+ by force
+
+definition element_ptrs :: "(_) heap \<Rightarrow> (_) element_ptr fset"
+ where
+ "element_ptrs heap = ffilter is_element_ptr (element_ptr_kinds heap)"
+
+definition cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) Node \<Rightarrow> (_) Element option"
+ where
+ "cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t node = (case RNode.more node of Inl element \<Rightarrow>
+Some (RNode.extend (RNode.truncate node) element) | _ \<Rightarrow> None)"
+adhoc_overloading cast cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+abbreviation cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) Object \<Rightarrow> (_) Element option"
+ where
+ "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t obj \<equiv> (case cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e obj of Some node \<Rightarrow> cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t node | None \<Rightarrow> None)"
+adhoc_overloading cast cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+definition cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e :: "(_) Element \<Rightarrow> (_) Node"
+ where
+ "cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e element = RNode.extend (RNode.truncate element) (Inl (RNode.more element))"
+adhoc_overloading cast cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+
+abbreviation cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t :: "(_) Element \<Rightarrow> (_) Object"
+ where
+ "cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr \<equiv> cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr)"
+adhoc_overloading cast cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+consts is_element_kind :: 'a
+definition is_element_kind\<^sub>N\<^sub>o\<^sub>d\<^sub>e :: "(_) Node \<Rightarrow> bool"
+ where
+ "is_element_kind\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr \<longleftrightarrow> cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr \<noteq> None"
+
+adhoc_overloading is_element_kind is_element_kind\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+lemmas is_element_kind_def = is_element_kind\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def
+
+abbreviation is_element_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t :: "(_) Object \<Rightarrow> bool"
+ where
+ "is_element_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr \<equiv> cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr \<noteq> None"
+adhoc_overloading is_element_kind is_element_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+lemma element_ptr_kinds_commutes [simp]:
+ "cast element_ptr |\<in>| node_ptr_kinds h \<longleftrightarrow> element_ptr |\<in>| element_ptr_kinds h"
+ apply(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)[1]
+ by (metis (no_types, lifting) element_ptr_casts_commute2 ffmember_filter fimage_eqI
+ fset.map_comp is_element_ptr_kind_none node_ptr_casts_commute3
+ node_ptr_kinds_commutes node_ptr_kinds_def option.sel option.simps(3))
+
+definition get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) element_ptr \<Rightarrow> (_) heap \<Rightarrow> (_) Element option"
+ where
+ "get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h = Option.bind (get\<^sub>N\<^sub>o\<^sub>d\<^sub>e (cast element_ptr) h) cast"
+adhoc_overloading get get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+locale l_type_wf_def\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+begin
+definition a_type_wf :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_type_wf h = (NodeClass.type_wf h \<and> (\<forall>element_ptr \<in> fset (element_ptr_kinds h).
+ get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h \<noteq> None))"
+end
+global_interpretation l_type_wf_def\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t defines type_wf = a_type_wf .
+lemmas type_wf_defs = a_type_wf_def
+
+locale l_type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t = l_type_wf type_wf for type_wf :: "((_) heap \<Rightarrow> bool)" +
+ assumes type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t: "type_wf h \<Longrightarrow> ElementClass.type_wf h"
+
+sublocale l_type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t \<subseteq> l_type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e
+ apply(unfold_locales)
+ using NodeClass.a_type_wf_def
+ by (meson ElementClass.a_type_wf_def l_type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_axioms l_type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+
+locale l_get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas = l_type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+begin
+sublocale l_get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_lemmas by unfold_locales
+
+lemma get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_type_wf:
+ assumes "type_wf h"
+ shows "element_ptr |\<in>| element_ptr_kinds h \<longleftrightarrow> get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h \<noteq> None"
+ using l_type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_axioms assms
+ apply(simp add: type_wf_defs get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def l_type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+ by (metis NodeClass.get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_type_wf bind_eq_None_conv element_ptr_kinds_commutes notin_fset
+ option.distinct(1))
+end
+
+global_interpretation l_get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas type_wf
+ by unfold_locales
+
+definition put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) element_ptr \<Rightarrow> (_) Element \<Rightarrow> (_) heap \<Rightarrow> (_) heap"
+ where
+ "put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr element = put\<^sub>N\<^sub>o\<^sub>d\<^sub>e (cast element_ptr) (cast element)"
+adhoc_overloading put put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+lemma put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap:
+ assumes "put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr element h = h'"
+ shows "element_ptr |\<in>| element_ptr_kinds h'"
+ using assms
+ unfolding put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def element_ptr_kinds_def
+ by (metis element_ptr_kinds_commutes element_ptr_kinds_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_ptr_in_heap)
+
+lemma put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_put_ptrs:
+ assumes "put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr element h = h'"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast element_ptr|}"
+ using assms
+ by (simp add: put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_put_ptrs)
+
+
+
+lemma cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_inject [simp]:
+ "cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e x = cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e y \<longleftrightarrow> x = y"
+ apply(simp add: cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def RObject.extend_def RNode.extend_def)
+ by (metis (full_types) RNode.surjective old.unit.exhaust)
+
+lemma cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_none [simp]:
+ "cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t node = None \<longleftrightarrow> \<not> (\<exists>element. cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e element = node)"
+ apply(auto simp add: cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def RObject.extend_def RNode.extend_def
+ split: sum.splits)[1]
+ by (metis (full_types) RNode.select_convs(2) RNode.surjective old.unit.exhaust)
+
+lemma cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_some [simp]:
+ "cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t node = Some element \<longleftrightarrow> cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e element = node"
+ by(auto simp add: cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def RObject.extend_def RNode.extend_def
+ split: sum.splits)
+
+lemma cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_inv [simp]: "cast\<^sub>N\<^sub>o\<^sub>d\<^sub>e\<^sub>2\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t (cast\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>N\<^sub>o\<^sub>d\<^sub>e element) = Some element"
+ by simp
+
+lemma get_elment_ptr_simp1 [simp]:
+ "get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr (put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr element h) = Some element"
+ by(auto simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+lemma get_elment_ptr_simp2 [simp]:
+ "element_ptr \<noteq> element_ptr'
+ \<Longrightarrow> get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr (put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr' element h) = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h"
+ by(auto simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+
+
+abbreviation "create_element_obj tag_name_arg child_nodes_arg attrs_arg shadow_root_opt_arg
+ \<equiv> \<lparr> RObject.nothing = (), RNode.nothing = (), RElement.nothing = (),
+ tag_name = tag_name_arg, Element.child_nodes = child_nodes_arg, attrs = attrs_arg,
+ shadow_root_opt = shadow_root_opt_arg, \<dots> = None \<rparr>"
+
+definition new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) heap \<Rightarrow> ((_) element_ptr \<times> (_) heap)"
+ where
+ "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h =
+ (let new_element_ptr = element_ptr.Ref (Suc (fMax (finsert 0 (element_ptr.the_ref
+ |`| (element_ptrs h)))))
+ in
+ (new_element_ptr, put new_element_ptr (create_element_obj '''' [] fmempty None) h))"
+
+lemma new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap:
+ assumes "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_element_ptr, h')"
+ shows "new_element_ptr |\<in>| element_ptr_kinds h'"
+ using assms
+ unfolding new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def
+ using put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap by blast
+
+lemma new_element_ptr_new:
+ "element_ptr.Ref (Suc (fMax (finsert 0 (element_ptr.the_ref |`| element_ptrs h)))) |\<notin>| element_ptrs h"
+ by (metis Suc_n_not_le_n element_ptr.sel(1) fMax_ge fimage_finsert finsertI1 finsertI2 set_finsert)
+
+lemma new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_not_in_heap:
+ assumes "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_element_ptr, h')"
+ shows "new_element_ptr |\<notin>| element_ptr_kinds h"
+ using assms
+ unfolding new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ by (metis Pair_inject element_ptrs_def ffmember_filter new_element_ptr_new is_element_ptr_ref)
+
+lemma new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_new_ptr:
+ assumes "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_element_ptr, h')"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ using assms
+ by (metis Pair_inject new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_put_ptrs)
+
+lemma new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_is_element_ptr:
+ assumes "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_element_ptr, h')"
+ shows "is_element_ptr new_element_ptr"
+ using assms
+ by(auto simp add: new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
+
+lemma new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t [simp]:
+ assumes "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_element_ptr, h')"
+ assumes "ptr \<noteq> cast new_element_ptr"
+ shows "get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h = get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+
+lemma new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>N\<^sub>o\<^sub>d\<^sub>e [simp]:
+ assumes "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_element_ptr, h')"
+ assumes "ptr \<noteq> cast new_element_ptr"
+ shows "get\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr h = get\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+
+lemma new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t [simp]:
+ assumes "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_element_ptr, h')"
+ assumes "ptr \<noteq> new_element_ptr"
+ shows "get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
+
+locale l_known_ptr\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+begin
+definition a_known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "a_known_ptr ptr = (known_ptr ptr \<or> is_element_ptr ptr)"
+
+lemma known_ptr_not_element_ptr: "\<not>is_element_ptr ptr \<Longrightarrow> a_known_ptr ptr \<Longrightarrow> known_ptr ptr"
+ by(simp add: a_known_ptr_def)
+end
+global_interpretation l_known_ptr\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t defines known_ptr = a_known_ptr .
+lemmas known_ptr_defs = a_known_ptr_def
+
+
+locale l_known_ptrs\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t = l_known_ptr known_ptr for known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+begin
+definition a_known_ptrs :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_known_ptrs h = (\<forall>ptr \<in> fset (object_ptr_kinds h). known_ptr ptr)"
+
+lemma known_ptrs_known_ptr:
+ "ptr |\<in>| object_ptr_kinds h \<Longrightarrow> a_known_ptrs h \<Longrightarrow> known_ptr ptr"
+ apply(simp add: a_known_ptrs_def)
+ using notin_fset by fastforce
+
+lemma known_ptrs_preserved:
+ "object_ptr_kinds h = object_ptr_kinds h' \<Longrightarrow> a_known_ptrs h = a_known_ptrs h'"
+ by(auto simp add: a_known_ptrs_def)
+lemma known_ptrs_subset:
+ "object_ptr_kinds h' |\<subseteq>| object_ptr_kinds h \<Longrightarrow> a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def less_eq_fset.rep_eq subsetD)
+lemma known_ptrs_new_ptr:
+ "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|new_ptr|} \<Longrightarrow> known_ptr new_ptr \<Longrightarrow>
+a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def)
+end
+global_interpretation l_known_ptrs\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t known_ptr defines known_ptrs = a_known_ptrs .
+lemmas known_ptrs_defs = a_known_ptrs_def
+
+lemma known_ptrs_is_l_known_ptrs: "l_known_ptrs known_ptr known_ptrs"
+ using known_ptrs_known_ptr known_ptrs_preserved known_ptrs_subset known_ptrs_new_ptr l_known_ptrs_def
+ by blast
+
+end
diff --git a/thys/Core_SC_DOM/safely_composable/pointers/ShadowRootPointer.thy b/thys/Core_SC_DOM/safely_composable/pointers/ShadowRootPointer.thy
new file mode 100644
--- /dev/null
+++ b/thys/Core_SC_DOM/safely_composable/pointers/ShadowRootPointer.thy
@@ -0,0 +1,192 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2018 The University of Sheffield, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>ShadowRoot\<close>
+text\<open>In this theory, we introduce the typed pointers for the class ShadowRoot. Note that, in
+this document, we will not make use of ShadowRoots nor will we discuss their particular properties.
+We only include them here, as they are required for future work and they cannot be added alter
+following the object-oriented extensibility of our data model.\<close>
+theory ShadowRootPointer
+ imports
+ "DocumentPointer"
+begin
+
+datatype 'shadow_root_ptr shadow_root_ptr = Ref (the_ref: ref) | Ext 'shadow_root_ptr
+register_default_tvars "'shadow_root_ptr shadow_root_ptr"
+type_synonym ('document_ptr, 'shadow_root_ptr) document_ptr
+ = "('shadow_root_ptr shadow_root_ptr + 'document_ptr) document_ptr"
+register_default_tvars "('document_ptr, 'shadow_root_ptr) document_ptr"
+type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr,
+ 'document_ptr, 'shadow_root_ptr) object_ptr
+ = "('object_ptr, 'node_ptr, 'element_ptr,
+ 'character_data_ptr, 'shadow_root_ptr shadow_root_ptr + 'document_ptr) object_ptr"
+register_default_tvars "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr,
+ 'document_ptr, 'shadow_root_ptr) object_ptr"
+
+
+definition cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) shadow_root_ptr \<Rightarrow> (_) shadow_root_ptr"
+ where
+ "cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r = id"
+
+definition cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) shadow_root_ptr \<Rightarrow> (_) document_ptr"
+ where
+ "cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = document_ptr.Ext (Inl ptr)"
+
+abbreviation cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) shadow_root_ptr \<Rightarrow> (_) object_ptr"
+ where
+ "cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr)"
+
+definition cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) document_ptr \<Rightarrow> (_) shadow_root_ptr option"
+ where
+ "cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr = (case document_ptr of document_ptr.Ext (Inl shadow_root_ptr)
+ \<Rightarrow> Some shadow_root_ptr | _ \<Rightarrow> None)"
+
+abbreviation cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> (_) shadow_root_ptr option"
+ where
+ "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some document_ptr \<Rightarrow> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr
+ | None \<Rightarrow> None)"
+
+adhoc_overloading cast cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+ cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+
+consts is_shadow_root_ptr_kind :: 'a
+definition is_shadow_root_ptr_kind\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) document_ptr \<Rightarrow> bool"
+ where
+ "is_shadow_root_ptr_kind\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr =
+(case cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of Some _ \<Rightarrow> True | _ \<Rightarrow> False)"
+
+abbreviation is_shadow_root_ptr_kind\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "is_shadow_root_ptr_kind\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast ptr of
+ Some document_ptr \<Rightarrow> is_shadow_root_ptr_kind\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr
+ | None \<Rightarrow> False)"
+
+adhoc_overloading is_shadow_root_ptr_kind is_shadow_root_ptr_kind\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_shadow_root_ptr_kind\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+lemmas is_shadow_root_ptr_kind_def = is_shadow_root_ptr_kind\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+
+consts is_shadow_root_ptr :: 'a
+definition is_shadow_root_ptr\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) shadow_root_ptr \<Rightarrow> bool"
+ where
+ "is_shadow_root_ptr\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr = (case ptr of shadow_root_ptr.Ref _ \<Rightarrow> True
+ | _ \<Rightarrow> False)"
+abbreviation is_shadow_root_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) document_ptr \<Rightarrow> bool"
+ where
+ "is_shadow_root_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast ptr of
+ Some shadow_root_ptr \<Rightarrow> is_shadow_root_ptr\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr
+ | _ \<Rightarrow> False)"
+
+abbreviation is_shadow_root_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "is_shadow_root_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> (case cast ptr of
+ Some document_ptr \<Rightarrow> is_shadow_root_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr
+ | None \<Rightarrow> False)"
+
+adhoc_overloading is_shadow_root_ptr is_shadow_root_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_shadow_root_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+ is_shadow_root_ptr\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+lemmas is_shadow_root_ptr_def = is_shadow_root_ptr\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+
+consts is_shadow_root_ptr_ext :: 'a
+abbreviation "is_shadow_root_ptr_ext\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv> \<not> is_shadow_root_ptr\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+
+abbreviation "is_shadow_root_ptr_ext\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv>
+is_shadow_root_ptr_kind ptr \<and> (\<not> is_shadow_root_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr)"
+
+abbreviation "is_shadow_root_ptr_ext\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<equiv>
+is_shadow_root_ptr_kind ptr \<and> (\<not> is_shadow_root_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr)"
+adhoc_overloading is_shadow_root_ptr_ext is_shadow_root_ptr_ext\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r is_shadow_root_ptr_ext\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r
+
+
+instantiation shadow_root_ptr :: (linorder) linorder
+begin
+definition
+ less_eq_shadow_root_ptr :: "(_::linorder) shadow_root_ptr \<Rightarrow> (_) shadow_root_ptr \<Rightarrow> bool"
+ where
+ "less_eq_shadow_root_ptr x y \<equiv> (case x of Ext i \<Rightarrow> (case y of Ext j \<Rightarrow> i \<le> j | Ref _ \<Rightarrow> False)
+ | Ref i \<Rightarrow> (case y of Ext _ \<Rightarrow> True | Ref j \<Rightarrow> i \<le> j))"
+definition less_shadow_root_ptr :: "(_::linorder) shadow_root_ptr \<Rightarrow> (_) shadow_root_ptr \<Rightarrow> bool"
+ where "less_shadow_root_ptr x y \<equiv> x \<le> y \<and> \<not> y \<le> x"
+instance
+ apply(standard)
+ by(auto simp add: less_eq_shadow_root_ptr_def less_shadow_root_ptr_def
+ split: shadow_root_ptr.splits)
+end
+
+
+lemma is_shadow_root_ptr_ref [simp]: "is_shadow_root_ptr (shadow_root_ptr.Ref n)"
+ by(simp add: is_shadow_root_ptr\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma shadow_root_ptr_casts_commute [simp]:
+ "cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr =
+Some shadow_root_ptr \<longleftrightarrow> cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr = document_ptr"
+ unfolding cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by(auto split: document_ptr.splits sum.splits)
+
+lemma shadow_root_ptr_casts_commute2 [simp]:
+ "(cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) = Some shadow_root_ptr)"
+ by simp
+
+lemma shadow_root_ptr_casts_commute3 [simp]:
+ assumes "is_shadow_root_ptr_kind\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr"
+ shows "cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (the (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)) = document_ptr"
+ using assms
+ by(auto simp add: is_shadow_root_ptr_kind_def cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: document_ptr.splits sum.splits)
+
+lemma is_shadow_root_ptr_kind_obtains:
+ assumes "is_shadow_root_ptr_kind document_ptr"
+ obtains shadow_root_ptr where "document_ptr = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr"
+ by (metis assms is_shadow_root_ptr_kind_def case_optionE shadow_root_ptr_casts_commute)
+
+lemma is_shadow_root_ptr_kind_none:
+ assumes "\<not>is_shadow_root_ptr_kind document_ptr"
+ shows "cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr = None"
+ using assms
+ unfolding is_shadow_root_ptr_kind_def cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by(auto split: document_ptr.splits sum.splits)
+
+lemma is_shadow_root_ptr_kind_cast [simp]:
+ "is_shadow_root_ptr_kind (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr)"
+ by (metis shadow_root_ptr_casts_commute is_shadow_root_ptr_kind_none option.distinct(1))
+
+lemma cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject [simp]:
+ "cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r x = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r y \<longleftrightarrow> x = y"
+ by(simp add: cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_ext_none [simp]:
+ "cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (document_ptr.Ext (Inr (Inr document_ext_ptr))) = None"
+ by(simp add: cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+
+lemma is_shadow_root_ptr_implies_kind [dest]:
+ "is_shadow_root_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr \<Longrightarrow> is_shadow_root_ptr_kind\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ by(auto split: option.splits)
+
+lemma is_shadow_root_ptr_kind_not_document_ptr [simp]: "\<not>is_shadow_root_ptr_kind (document_ptr.Ref x)"
+ by(simp add: is_shadow_root_ptr_kind_def cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def split: option.splits)
+end
diff --git a/thys/Physical_Quantities/BIS.thy b/thys/Physical_Quantities/BIS.thy
new file mode 100644
--- /dev/null
+++ b/thys/Physical_Quantities/BIS.thy
@@ -0,0 +1,88 @@
+section \<open> British Imperial System (1824/1897) \<close>
+
+theory BIS
+ imports ISQ SI_Units CGS
+begin
+
+text \<open> The values in the British Imperial System (BIS) are derived from the UK Weights and Measures
+ Act 1824. \<close>
+
+subsection \<open> Preliminaries \<close>
+
+typedef BIS = "UNIV :: unit set" ..
+instance BIS :: unit_system
+ by (rule unit_system_intro[of "Abs_BIS ()"],
+ metis (full_types) Abs_BIS_cases UNIV_eq_I insert_iff old.unit.exhaust)
+instance BIS :: time_second ..
+abbreviation "BIS \<equiv> unit :: BIS"
+
+subsection \<open> Base Units \<close>
+
+abbreviation "yard \<equiv> BUNIT(L, BIS)"
+abbreviation "pound \<equiv> BUNIT(M, BIS)"
+abbreviation "rankine \<equiv> BUNIT(\<Theta>, BIS)"
+
+text \<open> We chose Rankine rather than Farenheit as this is more compatible with the SI system and
+ avoids the need for having an offset in conversion functions. \<close>
+
+subsection \<open> Derived Units \<close>
+
+definition [si_eq]: "foot = 1/3 *\<^sub>Q yard"
+
+definition [si_eq]: "inch = 1/12 *\<^sub>Q foot"
+
+definition [si_eq]: "furlong = 220 *\<^sub>Q yard"
+
+definition [si_eq]: "mile = 1760 *\<^sub>Q yard"
+
+definition [si_eq]: "acre = 4840 *\<^sub>Q yard\<^sup>\<three>"
+
+definition [si_eq]: "ounce = 1/12 *\<^sub>Q pound"
+
+definition [si_eq]: "gallon = 277.421 *\<^sub>Q inch\<^sup>\<three>"
+
+definition [si_eq]: "quart = 1/4 *\<^sub>Q gallon"
+
+definition [si_eq]: "pint = 1/8 *\<^sub>Q gallon"
+
+definition [si_eq]: "peck = 2 *\<^sub>Q gallon"
+
+definition [si_eq]: "bushel = 8 *\<^sub>Q gallon"
+
+definition [si_eq]: "minute = 60 *\<^sub>Q second"
+
+definition [si_eq]: "hour = 60 *\<^sub>Q minute"
+
+subsection \<open> Conversion to SI \<close>
+
+instantiation BIS :: metrifiable
+begin
+
+lift_definition convschema_BIS :: "BIS itself \<Rightarrow> (BIS, SI) Conversion" is
+"\<lambda> x. \<lparr> cLengthF = 0.9143993, cMassF = 0.453592338, cTimeF = 1
+ , cCurrentF = 1, cTemperatureF = 5/9, cAmountF = 1, cIntensityF = 1 \<rparr>" by simp
+
+instance ..
+end
+
+lemma BIS_SI_simps [simp]: "LengthF (convschema (a::BIS itself)) = 0.9143993"
+ "MassF (convschema a) = 0.453592338"
+ "TimeF (convschema a) = 1"
+ "CurrentF (convschema a) = 1"
+ "TemperatureF (convschema a) = 5/9"
+ by (transfer, simp)+
+
+subsection \<open> Conversion Examples \<close>
+
+lemma "metrify (foot :: rat[L, BIS]) = 0.9143993 / 3 *\<^sub>Q metre"
+ by (simp add: foot_def)
+
+lemma "metrify ((70::rat) *\<^sub>Q mile \<^bold>/ hour) = (704087461 / 22500000) *\<^sub>Q (metre \<^bold>/ second)"
+ by (si_simp)
+
+lemma "QMC(CGS \<rightarrow> BIS) ((1::rat) *\<^sub>Q centimetre) = 100000 / 9143993 *\<^sub>Q yard"
+ by simp
+
+
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/CGS.thy b/thys/Physical_Quantities/CGS.thy
new file mode 100644
--- /dev/null
+++ b/thys/Physical_Quantities/CGS.thy
@@ -0,0 +1,42 @@
+section \<open> Centimetre-Gram-Second System \<close>
+
+theory CGS
+ imports SI_Units
+begin
+
+subsection \<open> Preliminaries \<close>
+
+typedef CGS = "UNIV :: unit set" ..
+instance CGS :: unit_system
+ by (rule unit_system_intro[of "Abs_CGS ()"], metis (full_types)
+ Abs_CGS_cases UNIV_eq_I insert_iff old.unit.exhaust)
+instance CGS :: time_second ..
+abbreviation "CGS \<equiv> unit :: CGS"
+
+subsection \<open> Base Units \<close>
+
+abbreviation "centimetre \<equiv> BUNIT(L, CGS)"
+abbreviation "gram \<equiv> BUNIT(M, CGS)"
+
+subsection \<open> Conversion to SI \<close>
+
+instantiation CGS :: metrifiable
+begin
+
+lift_definition convschema_CGS :: "CGS itself \<Rightarrow> (CGS, SI) Conversion" is
+"\<lambda> x. \<lparr> cLengthF = 0.01, cMassF = 0.001, cTimeF = 1
+ , cCurrentF = 1, cTemperatureF = 1, cAmountF = 1, cIntensityF = 1 \<rparr>" by simp
+
+instance ..
+end
+
+lemma CGS_SI_simps [simp]: "LengthF (convschema (a::CGS itself)) = 0.01" "MassF (convschema a) = 0.001"
+ "TimeF (convschema a) = 1" "CurrentF (convschema a) = 1" "TemperatureF (convschema a) = 1"
+ by (transfer, simp)+
+
+subsection \<open> Conversion Examples \<close>
+
+lemma "metrify ((100::rat) *\<^sub>Q centimetre) = 1 *\<^sub>Q metre"
+ by (si_simp)
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/Enum_extra.thy b/thys/Physical_Quantities/Enum_extra.thy
new file mode 100644
--- /dev/null
+++ b/thys/Physical_Quantities/Enum_extra.thy
@@ -0,0 +1,94 @@
+section \<open> Enumeration Extras \<close>
+
+theory Enum_extra
+ imports "HOL-Library.Cardinality"
+begin
+
+subsection \<open> First Index Function \<close>
+
+text \<open> The following function extracts the index of the first occurrence of an element in a list,
+ assuming it is indeed an element. \<close>
+
+fun first_ind :: "'a list \<Rightarrow> 'a \<Rightarrow> nat \<Rightarrow> nat" where
+"first_ind [] y i = undefined" |
+"first_ind (x # xs) y i = (if (x = y) then i else first_ind xs y (Suc i))"
+
+lemma first_ind_length:
+ "x \<in> set(xs) \<Longrightarrow> first_ind xs x i < length(xs) + i"
+ by (induct xs arbitrary: i, auto, metis add_Suc_right)
+
+lemma nth_first_ind:
+ "\<lbrakk> distinct xs; x \<in> set(xs) \<rbrakk> \<Longrightarrow> xs ! (first_ind xs x i - i) = x"
+ apply (induct xs arbitrary: i)
+ apply (auto)
+ apply (metis One_nat_def add.right_neutral add_Suc_right add_diff_cancel_left' diff_diff_left empty_iff first_ind.simps(2) list.set(1) nat.simps(3) neq_Nil_conv nth_Cons' zero_diff)
+ done
+
+lemma first_ind_nth:
+ "\<lbrakk> distinct xs; i < length xs \<rbrakk> \<Longrightarrow> first_ind xs (xs ! i) j = i + j"
+ apply (induct xs arbitrary: i j)
+ apply (auto)
+ apply (metis less_Suc_eq_le nth_equal_first_eq)
+ using less_Suc_eq_0_disj apply auto
+ done
+
+subsection \<open> Enumeration Indices \<close>
+
+syntax
+ "_ENUM" :: "type \<Rightarrow> logic" ("ENUM'(_')")
+
+translations
+ "ENUM('a)" => "CONST Enum.enum :: ('a::enum) list"
+
+text \<open> Extract a unique natural number associated with an enumerated value by using its index
+ in the characteristic list \<^term>\<open>ENUM('a)\<close>. \<close>
+
+definition enum_ind :: "'a::enum \<Rightarrow> nat" where
+"enum_ind (x :: 'a::enum) = first_ind ENUM('a) x 0"
+
+lemma length_enum_CARD: "length ENUM('a) = CARD('a)"
+ by (simp add: UNIV_enum distinct_card enum_distinct)
+
+lemma CARD_length_enum: "CARD('a) = length ENUM('a)"
+ by (simp add: length_enum_CARD)
+
+lemma enum_ind_less_CARD [simp]: "enum_ind (x :: 'a::enum) < CARD('a)"
+ using first_ind_length[of x, OF in_enum, of 0] by (simp add: enum_ind_def CARD_length_enum)
+
+lemma enum_nth_ind [simp]: "Enum.enum ! (enum_ind x) = x"
+ using nth_first_ind[of Enum.enum x 0, OF enum_distinct in_enum] by (simp add: enum_ind_def)
+
+lemma enum_distinct_conv_nth:
+ assumes "i < CARD('a)" "j < CARD('a)" "ENUM('a) ! i = ENUM('a) ! j"
+ shows "i = j"
+proof -
+ have "(\<forall>i<length ENUM('a). \<forall>j<length ENUM('a). i \<noteq> j \<longrightarrow> ENUM('a) ! i \<noteq> ENUM('a) ! j)"
+ using distinct_conv_nth[of "ENUM('a)", THEN sym] by (simp add: enum_distinct)
+ with assms show ?thesis
+ by (auto simp add: CARD_length_enum)
+qed
+
+lemma enum_ind_nth [simp]:
+ assumes "i < CARD('a::enum)"
+ shows "enum_ind (ENUM('a) ! i) = i"
+ using assms first_ind_nth[of "ENUM('a)" i 0, OF enum_distinct]
+ by (simp add: enum_ind_def CARD_length_enum)
+
+lemma enum_ind_spec:
+ "enum_ind (x :: 'a::enum) = (THE i. i < CARD('a) \<and> Enum.enum ! i = x)"
+proof (rule sym, rule the_equality, safe)
+ show "enum_ind x < CARD('a)"
+ by (simp add: enum_ind_less_CARD[of x])
+ show "enum_class.enum ! enum_ind x = x"
+ by simp
+ show "\<And>i. i < CARD('a) \<Longrightarrow> x = ENUM('a) ! i \<Longrightarrow> i = enum_ind (ENUM('a) ! i)"
+ by (simp add: enum_ind_nth)
+qed
+
+lemma enum_ind_inj: "inj (enum_ind :: 'a::enum \<Rightarrow> nat)"
+ by (rule inj_on_inverseI[of _ "\<lambda> i. ENUM('a) ! i"], simp)
+
+lemma enum_ind_neq [simp]: "x \<noteq> y \<Longrightarrow> enum_ind x \<noteq> enum_ind y"
+ by (simp add: enum_ind_inj inj_eq)
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/Groups_mult.thy b/thys/Physical_Quantities/Groups_mult.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/Groups_mult.thy
@@ -0,0 +1,48 @@
+section \<open> Multiplication Groups \<close>
+
+theory Groups_mult
+ imports Main
+begin
+
+text \<open> The HOL standard library only has groups based on addition. Here, we build one based on
+ multiplication. \<close>
+
+notation times (infixl "\<cdot>" 70)
+
+class group_mult = inverse + monoid_mult +
+ assumes left_inverse: "inverse a \<cdot> a = 1"
+ assumes multi_inverse_conv_div [simp]: "a \<cdot> (inverse b) = a / b"
+begin
+
+lemma div_conv_mult_inverse: "a / b = a \<cdot> (inverse b)"
+ by simp
+
+sublocale mult: group times 1 inverse
+ by standard (simp_all add: left_inverse)
+
+lemma diff_self [simp]: "a / a = 1"
+ using mult.right_inverse by auto
+
+lemma mult_distrib_inverse [simp]: "(a * b) / b = a"
+ by (metis local.mult_1_right local.multi_inverse_conv_div mult.right_inverse mult_assoc)
+
+end
+
+class ab_group_mult = comm_monoid_mult + group_mult
+begin
+
+lemma mult_distrib_inverse' [simp]: "(a * b) / a = b"
+ using local.mult_distrib_inverse mult_commute by fastforce
+
+lemma inverse_distrib: "inverse (a * b) = (inverse a) * (inverse b)"
+ by (simp add: local.mult.inverse_distrib_swap mult_commute)
+
+lemma inverse_divide [simp]: "inverse (a / b) = b / a"
+ by (metis div_conv_mult_inverse inverse_distrib mult.commute mult.inverse_inverse)
+
+end
+
+abbreviation (input) npower :: "'a::{power,inverse} \<Rightarrow> nat \<Rightarrow> 'a" ("(_\<^sup>-\<^sup>_)" [1000,999] 999)
+ where "npower x n \<equiv> inverse (x ^ n)"
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/ISQ.thy b/thys/Physical_Quantities/ISQ.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/ISQ.thy
@@ -0,0 +1,5 @@
+section \<open> Meta-Theory for ISQ \<close>
+
+theory ISQ
+ imports ISQ_Dimensions ISQ_Quantities ISQ_Proof ISQ_Algebra ISQ_Units ISQ_Conversion
+begin end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/ISQ_Algebra.thy b/thys/Physical_Quantities/ISQ_Algebra.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/ISQ_Algebra.thy
@@ -0,0 +1,88 @@
+section \<open> Algebraic Laws \<close>
+
+theory ISQ_Algebra
+ imports ISQ_Proof
+begin
+
+subsection \<open> Quantity Scale \<close>
+
+lemma scaleQ_add_right: "a *\<^sub>Q x + y = (a *\<^sub>Q x) + (a *\<^sub>Q y)"
+ by (si_simp add: distrib_left)
+
+lemma scaleQ_add_left: "a + b *\<^sub>Q x = (a *\<^sub>Q x) + (b *\<^sub>Q x)"
+ by (si_simp add: distrib_right)
+
+lemma scaleQ_scaleQ [simp]: "a *\<^sub>Q b *\<^sub>Q x = a \<cdot> b *\<^sub>Q x"
+ by si_simp
+
+lemma scaleQ_one [simp]: "1 *\<^sub>Q x = x"
+ by si_simp
+
+lemma scaleQ_zero [simp]: "0 *\<^sub>Q x = 0"
+ by si_simp
+
+lemma scaleQ_inv: "-a *\<^sub>Q x = a *\<^sub>Q -x"
+ by si_calc
+
+lemma scaleQ_as_qprod: "a *\<^sub>Q x \<cong>\<^sub>Q (a *\<^sub>Q \<one>) \<^bold>\<cdot> x"
+ by si_simp
+
+lemma mult_scaleQ_left [simp]: "(a *\<^sub>Q x) \<^bold>\<cdot> y = a *\<^sub>Q x \<^bold>\<cdot> y"
+ by si_simp
+
+lemma mult_scaleQ_right [simp]: "x \<^bold>\<cdot> (a *\<^sub>Q y) = a *\<^sub>Q x \<^bold>\<cdot> y"
+ by si_simp
+
+subsection \<open> Field Laws \<close>
+
+lemma qtimes_commute: "x \<^bold>\<cdot> y \<cong>\<^sub>Q y \<^bold>\<cdot> x"
+ by si_calc
+
+lemma qtimes_assoc: "(x \<^bold>\<cdot> y) \<^bold>\<cdot> z \<cong>\<^sub>Q x \<^bold>\<cdot> (y \<^bold>\<cdot> z)"
+ by (si_calc)
+
+lemma qtimes_left_unit: "\<one> \<^bold>\<cdot> x \<cong>\<^sub>Q x"
+ by (si_calc)
+
+lemma qtimes_right_unit: "x \<^bold>\<cdot> \<one> \<cong>\<^sub>Q x"
+ by (si_calc)
+
+text\<open>The following weak congruences will allow for replacing equivalences in contexts
+ built from product and inverse. \<close>
+
+lemma qtimes_weak_cong_left:
+ assumes "x \<cong>\<^sub>Q y"
+ shows "x\<^bold>\<cdot>z \<cong>\<^sub>Q y\<^bold>\<cdot>z"
+ using assms by si_simp
+
+lemma qtimes_weak_cong_right:
+ assumes "x \<cong>\<^sub>Q y"
+ shows "z\<^bold>\<cdot>x \<cong>\<^sub>Q z\<^bold>\<cdot>y"
+ using assms by si_calc
+
+lemma qinverse_weak_cong:
+ assumes "x \<cong>\<^sub>Q y"
+ shows "x\<^sup>-\<^sup>\<one> \<cong>\<^sub>Q y\<^sup>-\<^sup>\<one>"
+ using assms by si_calc
+
+lemma scaleQ_cong:
+ assumes "y \<cong>\<^sub>Q z"
+ shows "x *\<^sub>Q y \<cong>\<^sub>Q x *\<^sub>Q z"
+ using assms by si_calc
+
+lemma qinverse_qinverse: "x\<^sup>-\<^sup>\<one>\<^sup>-\<^sup>\<one> \<cong>\<^sub>Q x"
+ by si_calc
+
+lemma qinverse_nonzero_iff_nonzero: "x\<^sup>-\<^sup>\<one> = 0 \<longleftrightarrow> x = 0"
+ by (auto, si_calc+)
+
+lemma qinverse_qtimes: "(x \<^bold>\<cdot> y)\<^sup>-\<^sup>\<one> \<cong>\<^sub>Q x\<^sup>-\<^sup>\<one> \<^bold>\<cdot> y\<^sup>-\<^sup>\<one>"
+ by (si_simp add: inverse_distrib)
+
+lemma qinverse_qdivide: "(x \<^bold>/ y)\<^sup>-\<^sup>\<one> \<cong>\<^sub>Q y \<^bold>/ x"
+ by si_simp
+
+lemma qtimes_cancel: "x \<noteq> 0 \<Longrightarrow> x \<^bold>/ x \<cong>\<^sub>Q \<one>"
+ by si_calc
+
+end
diff --git a/thys/Physical_Quantities/ISQ_Conversion.thy b/thys/Physical_Quantities/ISQ_Conversion.thy
new file mode 100644
--- /dev/null
+++ b/thys/Physical_Quantities/ISQ_Conversion.thy
@@ -0,0 +1,180 @@
+section \<open> Conversion Between Unit Systems \<close>
+
+theory ISQ_Conversion
+ imports ISQ_Units
+begin
+
+subsection \<open> Conversion Schemas \<close>
+
+text \<open> A conversion schema provides factors for each of the base units for converting between
+ two systems of units. We currently only support conversion between systems that can meaningfully
+ characterise a subset of the seven SI dimensions. \<close>
+
+record ConvSchema =
+ cLengthF :: rat
+ cMassF :: rat
+ cTimeF :: rat
+ cCurrentF :: rat
+ cTemperatureF :: rat
+ cAmountF :: rat
+ cIntensityF :: rat
+
+text \<open> We require that all the factors of greater than zero. \<close>
+
+typedef ('s\<^sub>1::unit_system, 's\<^sub>2::unit_system) Conversion ("(_/ \<Rightarrow>\<^sub>U _)" [1, 0] 0) =
+ "{c :: ConvSchema. cLengthF c > 0 \<and> cMassF c > 0 \<and> cTimeF c > 0 \<and> cCurrentF c > 0
+ \<and> cTemperatureF c > 0 \<and> cAmountF c > 0 \<and> cIntensityF c > 0}"
+ by (rule_tac x="\<lparr> cLengthF = 1, cMassF = 1, cTimeF = 1, cCurrentF = 1
+ , cTemperatureF = 1, cAmountF = 1, cIntensityF = 1 \<rparr>" in exI, simp)
+
+setup_lifting type_definition_Conversion
+
+lift_definition LengthF :: "('s\<^sub>1::unit_system \<Rightarrow>\<^sub>U 's\<^sub>2::unit_system) \<Rightarrow> rat" is cLengthF .
+lift_definition MassF :: "('s\<^sub>1::unit_system \<Rightarrow>\<^sub>U 's\<^sub>2::unit_system) \<Rightarrow> rat" is cMassF .
+lift_definition TimeF :: "('s\<^sub>1::unit_system \<Rightarrow>\<^sub>U 's\<^sub>2::unit_system) \<Rightarrow> rat" is cTimeF .
+lift_definition CurrentF :: "('s\<^sub>1::unit_system \<Rightarrow>\<^sub>U 's\<^sub>2::unit_system) \<Rightarrow> rat" is cCurrentF .
+lift_definition TemperatureF :: "('s\<^sub>1::unit_system \<Rightarrow>\<^sub>U 's\<^sub>2::unit_system) \<Rightarrow> rat" is cTemperatureF .
+lift_definition AmountF :: "('s\<^sub>1::unit_system \<Rightarrow>\<^sub>U 's\<^sub>2::unit_system) \<Rightarrow> rat" is cAmountF .
+lift_definition IntensityF :: "('s\<^sub>1::unit_system \<Rightarrow>\<^sub>U 's\<^sub>2::unit_system) \<Rightarrow> rat" is cIntensityF .
+
+lemma Conversion_props [simp]: "LengthF c > 0" "MassF c > 0" "TimeF c > 0" "CurrentF c > 0"
+ "TemperatureF c > 0" "AmountF c > 0" "IntensityF c > 0"
+ by (transfer, simp)+
+
+subsection \<open> Conversion Algebra \<close>
+
+lift_definition convid :: "'s::unit_system \<Rightarrow>\<^sub>U 's" ("id\<^sub>C")
+is "
+ \<lparr> cLengthF = 1
+ , cMassF = 1
+ , cTimeF = 1
+ , cCurrentF = 1
+ , cTemperatureF = 1
+ , cAmountF = 1
+ , cIntensityF = 1 \<rparr>" by simp
+
+lift_definition convcomp ::
+ "('s\<^sub>2 \<Rightarrow>\<^sub>U 's\<^sub>3::unit_system) \<Rightarrow> ('s\<^sub>1::unit_system \<Rightarrow>\<^sub>U 's\<^sub>2::unit_system) \<Rightarrow> ('s\<^sub>1 \<Rightarrow>\<^sub>U 's\<^sub>3)" (infixl "\<circ>\<^sub>C" 55) is
+"\<lambda> c\<^sub>1 c\<^sub>2. \<lparr> cLengthF = cLengthF c\<^sub>1 * cLengthF c\<^sub>2, cMassF = cMassF c\<^sub>1 * cMassF c\<^sub>2
+ , cTimeF = cTimeF c\<^sub>1 * cTimeF c\<^sub>2, cCurrentF = cCurrentF c\<^sub>1 * cCurrentF c\<^sub>2
+ , cTemperatureF = cTemperatureF c\<^sub>1 * cTemperatureF c\<^sub>2
+ , cAmountF = cAmountF c\<^sub>1 * cAmountF c\<^sub>2, cIntensityF = cIntensityF c\<^sub>1 * cIntensityF c\<^sub>2 \<rparr>"
+ by simp
+
+lift_definition convinv :: "('s\<^sub>1::unit_system \<Rightarrow>\<^sub>U 's\<^sub>2::unit_system) \<Rightarrow> ('s\<^sub>2 \<Rightarrow>\<^sub>U 's\<^sub>1)" ("inv\<^sub>C") is
+"\<lambda> c. \<lparr> cLengthF = inverse (cLengthF c), cMassF = inverse (cMassF c), cTimeF = inverse (cTimeF c)
+ , cCurrentF = inverse (cCurrentF c), cTemperatureF = inverse (cTemperatureF c)
+ , cAmountF = inverse (cAmountF c), cIntensityF = inverse (cIntensityF c) \<rparr>" by simp
+
+lemma convinv_inverse [simp]: "convinv (convinv c) = c"
+ by (transfer, simp)
+
+lemma convcomp_inv [simp]: "c \<circ>\<^sub>C inv\<^sub>C c = id\<^sub>C"
+ by (transfer, simp)
+
+lemma inv_convcomp [simp]: "inv\<^sub>C c \<circ>\<^sub>C c = id\<^sub>C"
+ by (transfer, simp)
+
+lemma Conversion_invs [simp]: "LengthF (inv\<^sub>C x) = inverse (LengthF x)" "MassF (inv\<^sub>C x) = inverse (MassF x)"
+ "TimeF (inv\<^sub>C x) = inverse (TimeF x)" "CurrentF (inv\<^sub>C x) = inverse (CurrentF x)"
+ "TemperatureF (inv\<^sub>C x) = inverse (TemperatureF x)" "AmountF (inv\<^sub>C x) = inverse (AmountF x)"
+ "IntensityF (inv\<^sub>C x) = inverse (IntensityF x)"
+ by (transfer, simp)+
+
+lemma Conversion_comps [simp]: "LengthF (c\<^sub>1 \<circ>\<^sub>C c\<^sub>2) = LengthF c\<^sub>1 * LengthF c\<^sub>2"
+ "MassF (c\<^sub>1 \<circ>\<^sub>C c\<^sub>2) = MassF c\<^sub>1 * MassF c\<^sub>2"
+ "TimeF (c\<^sub>1 \<circ>\<^sub>C c\<^sub>2) = TimeF c\<^sub>1 * TimeF c\<^sub>2"
+ "CurrentF (c\<^sub>1 \<circ>\<^sub>C c\<^sub>2) = CurrentF c\<^sub>1 * CurrentF c\<^sub>2"
+ "TemperatureF (c\<^sub>1 \<circ>\<^sub>C c\<^sub>2) = TemperatureF c\<^sub>1 * TemperatureF c\<^sub>2"
+ "AmountF (c\<^sub>1 \<circ>\<^sub>C c\<^sub>2) = AmountF c\<^sub>1 * AmountF c\<^sub>2"
+ "IntensityF (c\<^sub>1 \<circ>\<^sub>C c\<^sub>2) = IntensityF c\<^sub>1 * IntensityF c\<^sub>2"
+ by (transfer, simp)+
+
+subsection \<open> Conversion Functions \<close>
+
+definition dconvfactor :: "('s\<^sub>1::unit_system \<Rightarrow>\<^sub>U 's\<^sub>2::unit_system) \<Rightarrow> Dimension \<Rightarrow> rat" where
+"dconvfactor c d =
+ LengthF c ^\<^sub>Z dim_nth d Length
+ * MassF c ^\<^sub>Z dim_nth d Mass
+ * TimeF c ^\<^sub>Z dim_nth d Time
+ * CurrentF c ^\<^sub>Z dim_nth d Current
+ * TemperatureF c ^\<^sub>Z dim_nth d Temperature
+ * AmountF c ^\<^sub>Z dim_nth d Amount
+ * IntensityF c ^\<^sub>Z dim_nth d Intensity"
+
+lemma dconvfactor_pos [simp]: "dconvfactor c d > 0"
+ by (simp add: dconvfactor_def)
+
+lemma dconvfactor_nz [simp]: "dconvfactor c d \<noteq> 0"
+ by (metis dconvfactor_pos less_numeral_extra(3))
+
+lemma dconvfactor_convinv: "dconvfactor (convinv c) d = inverse (dconvfactor c d)"
+ by (simp add: dconvfactor_def intpow_inverse[THEN sym])
+
+lemma dconvfactor_id [simp]: "dconvfactor id\<^sub>C d = 1"
+ by (simp add: dconvfactor_def, transfer, simp)
+
+lemma dconvfactor_compose:
+ "dconvfactor (c\<^sub>1 \<circ>\<^sub>C c\<^sub>2) d = dconvfactor c\<^sub>1 d * dconvfactor c\<^sub>2 d"
+ by (simp add: dconvfactor_def, transfer, simp add: mult_ac intpow_mult_distrib)
+
+lemma dconvfactor_inverse:
+ "dconvfactor c (inverse d) = inverse (dconvfactor c d)"
+ by (simp add: dconvfactor_def inverse_dimvec_def intpow_uminus)
+
+lemma dconvfactor_times:
+ "dconvfactor c (x \<cdot> y) = dconvfactor c x \<cdot> dconvfactor c y"
+ by (auto simp add: dconvfactor_def mult_ac intpow_mult_combine times_dimvec_def)
+
+lift_definition qconv :: "('s\<^sub>1, 's\<^sub>2) Conversion \<Rightarrow> ('a::field_char_0)['d::dim_type, 's\<^sub>1::unit_system] \<Rightarrow> 'a['d, 's\<^sub>2::unit_system]"
+is "\<lambda> c q. \<lparr> mag = of_rat (dconvfactor c (dim q)) * mag q, dim = dim q, unit_sys = unit \<rparr>" by simp
+
+lemma magQ_qconv: "\<lbrakk>qconv c q\<rbrakk>\<^sub>Q = of_rat (dconvfactor c (dimQ q)) * \<lbrakk>q\<rbrakk>\<^sub>Q"
+ by (simp add: si_def, transfer, simp)
+
+lemma qconv_id [simp]: "qconv id\<^sub>C x = x"
+ by (transfer', simp add: Measurement_System_eq_intro)
+
+lemma qconv_comp: "qconv (c\<^sub>1 \<circ>\<^sub>C c\<^sub>2) x = qconv c\<^sub>1 (qconv c\<^sub>2 x)"
+ by (transfer, simp add: dconvfactor_compose of_rat_mult)
+
+lemma qconv_convinv [simp]: "qconv (convinv c) (qconv c x) = x"
+ by (transfer, simp add: dconvfactor_convinv mult.assoc[THEN sym] of_rat_mult[THEN sym] Measurement_System_eq_intro)
+
+lemma qconv_scaleQ [simp]: "qconv c (d *\<^sub>Q x) = d *\<^sub>Q qconv c x"
+ by (transfer, simp)
+
+lemma qconv_plus [simp]: "qconv c (x + y) = qconv c x + qconv c y"
+ by (transfer, auto simp add: plus_Quantity_ext_def mult.commute ring_class.ring_distribs)
+
+lemma qconv_minus [simp]: "qconv c (x - y) = qconv c x - qconv c y"
+ by (transfer, auto simp add: plus_Quantity_ext_def mult.commute ring_class.ring_distribs)
+
+lemma qconv_qmult [simp]: "qconv c (x \<^bold>\<cdot> y) = qconv c x \<^bold>\<cdot> qconv c y"
+ by (transfer, simp add: times_Quantity_ext_def times_Measurement_System_ext_def dconvfactor_times of_rat_mult)
+
+lemma qconv_qinverse [simp]: "qconv c (x\<^sup>-\<^sup>\<one>) = (qconv c x)\<^sup>-\<^sup>\<one>"
+ by (transfer, simp add: inverse_Quantity_ext_def inverse_Measurement_System_ext_def dconvfactor_inverse of_rat_inverse)
+
+lemma qconv_Length [simp]: "qconv c BUNIT(L, _) = LengthF c *\<^sub>Q BUNIT(L, _)"
+ by (simp add: dconvfactor_def magQ_qconv si_eq mk_BaseDim_def one_dimvec_def)
+
+lemma qconv_Mass [simp]: "qconv c BUNIT(M, _) = MassF c *\<^sub>Q BUNIT(M, _)"
+ by (simp add: dconvfactor_def magQ_qconv si_eq mk_BaseDim_def one_dimvec_def)
+
+lemma qconv_Time [simp]: "qconv c BUNIT(T, _) = TimeF c *\<^sub>Q BUNIT(T, _)"
+ by (simp add: dconvfactor_def magQ_qconv si_eq mk_BaseDim_def one_dimvec_def)
+
+lemma qconv_Current [simp]: "qconv c BUNIT(I, _) = CurrentF c *\<^sub>Q BUNIT(I, _)"
+ by (simp add: dconvfactor_def magQ_qconv si_eq mk_BaseDim_def one_dimvec_def)
+
+lemma qconv_Temperature [simp]: "qconv c BUNIT(\<Theta>, _) = TemperatureF c *\<^sub>Q BUNIT(\<Theta>, _)"
+ by (simp add: dconvfactor_def magQ_qconv si_eq mk_BaseDim_def one_dimvec_def)
+
+lemma qconv_Amount [simp]: "qconv c BUNIT(N, _) = AmountF c *\<^sub>Q BUNIT(N, _)"
+ by (simp add: dconvfactor_def magQ_qconv si_eq mk_BaseDim_def one_dimvec_def)
+
+lemma qconv_Intensity [simp]: "qconv c BUNIT(J, _) = IntensityF c *\<^sub>Q BUNIT(J, _)"
+ by (simp add: dconvfactor_def magQ_qconv si_eq mk_BaseDim_def one_dimvec_def)
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/ISQ_Dimensions.thy b/thys/Physical_Quantities/ISQ_Dimensions.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/ISQ_Dimensions.thy
@@ -0,0 +1,521 @@
+chapter \<open> International System of Quantities \<close>
+
+section \<open> Quantity Dimensions \<close>
+
+theory ISQ_Dimensions
+ imports Groups_mult Power_int Enum_extra
+ HOL.Transcendental
+ "HOL-Eisbach.Eisbach"
+begin
+
+subsection \<open> Preliminaries \<close>
+
+class unitary = finite +
+ assumes unitary_unit_pres: "card (UNIV::'a set) = 1"
+begin
+
+definition "unit = (undefined::'a)"
+
+lemma UNIV_unitary: "UNIV = {a::'a}"
+proof -
+ have "card(UNIV :: 'a set) = 1"
+ by (simp add: local.unitary_unit_pres)
+ thus ?thesis
+ by (metis (full_types) UNIV_I card_1_singletonE empty_iff insert_iff)
+qed
+
+lemma eq_unit: "(a::'a) = b"
+ by (metis (full_types) UNIV_unitary iso_tuple_UNIV_I singletonD)
+
+end
+
+lemma unitary_intro: "(UNIV::'s set) = {a} \<Longrightarrow> OFCLASS('s, unitary_class)"
+ apply (intro_classes, auto)
+ using finite.simps apply blast
+ using card_1_singleton_iff apply blast
+ done
+
+named_theorems si_def and si_eq
+
+instantiation unit :: comm_monoid_add
+begin
+ definition "zero_unit = ()"
+ definition "plus_unit (x::unit) (y::unit) = ()"
+ instance proof qed (simp_all)
+end
+
+instantiation unit :: comm_monoid_mult
+begin
+ definition "one_unit = ()"
+ definition "times_unit (x::unit) (y::unit) = ()"
+ instance proof qed (simp_all)
+end
+
+instantiation unit :: inverse
+begin
+ definition "inverse_unit (x::unit) = ()"
+ definition "divide_unit (x::unit) (y::unit) = ()"
+ instance ..
+end
+
+instance unit :: ab_group_mult
+ by (intro_classes, simp_all)
+
+subsection \<open> Dimension Vectors \<close>
+
+text \<open> Quantity dimensions are used to distinguish quantities of different kinds. Only quantities
+ of the same kind can be compared and combined: it is a mistake to add a length to a mass, for
+ example. Dimensions are often expressed in terms of seven base quantities, which can be combined
+ to form derived quantities. Consequently, a dimension associates with each of the base quantities
+ an integer that denotes the power to which it is raised. We use a special vector type to represent
+ dimensions, and then specialise this to the seven major dimensions. \<close>
+
+typedef ('n, 'd) dimvec = "UNIV :: ('d::enum \<Rightarrow> 'n) set"
+ morphisms dim_nth dim_lambda ..
+
+declare dim_lambda_inject [simplified, simp]
+declare dim_nth_inverse [simp]
+declare dim_lambda_inverse [simplified, simp]
+
+instantiation dimvec :: (zero, enum) "one"
+begin
+definition one_dimvec :: "('a, 'b) dimvec" where "one_dimvec = dim_lambda (\<lambda> i. 0)"
+instance ..
+end
+
+instantiation dimvec :: (plus, enum) times
+begin
+definition times_dimvec :: "('a, 'b) dimvec \<Rightarrow> ('a, 'b) dimvec \<Rightarrow> ('a, 'b) dimvec" where
+"times_dimvec x y = dim_lambda (\<lambda> i. dim_nth x i + dim_nth y i)"
+instance ..
+end
+
+instance dimvec :: (comm_monoid_add, enum) comm_monoid_mult
+ by ((intro_classes; simp add: times_dimvec_def one_dimvec_def fun_eq_iff add.assoc), simp add: add.commute)
+
+text \<open> We also define the inverse and division operations, and an abelian group, which will allow
+ us to perform dimensional analysis. \<close>
+
+instantiation dimvec :: ("{plus,uminus}", enum) inverse
+begin
+definition inverse_dimvec :: "('a, 'b) dimvec \<Rightarrow> ('a, 'b) dimvec" where
+"inverse_dimvec x = dim_lambda (\<lambda> i. - dim_nth x i)"
+
+definition divide_dimvec :: "('a, 'b) dimvec \<Rightarrow> ('a, 'b) dimvec \<Rightarrow> ('a, 'b) dimvec" where
+[code_unfold]: "divide_dimvec x y = x * (inverse y)"
+
+ instance ..
+end
+
+instance dimvec :: (ab_group_add, enum) ab_group_mult
+ by (intro_classes, simp_all add: inverse_dimvec_def one_dimvec_def times_dimvec_def divide_dimvec_def)
+
+subsection \<open> Code Generation \<close>
+
+text \<open> Dimension vectors can be represented using lists, which enables code generation and thus
+ efficient proof. \<close>
+
+definition mk_dimvec :: "'n list \<Rightarrow> ('n::ring_1, 'd::enum) dimvec"
+ where "mk_dimvec ds = (if (length ds = CARD('d)) then dim_lambda (\<lambda> d. ds ! enum_ind d) else 1)"
+
+code_datatype mk_dimvec
+
+lemma mk_dimvec_inj: "inj_on (mk_dimvec :: 'n list \<Rightarrow> ('n::ring_1, 'd::enum) dimvec) {xs. length xs = CARD('d)}"
+proof (rule inj_onI, safe)
+ fix x y :: "'n list"
+ assume a: "(mk_dimvec x :: ('n, 'd) dimvec) = mk_dimvec y" "length x = CARD('d)" "length y = CARD('d)"
+ have "\<And>i. i < length x \<Longrightarrow> x ! i = y ! i"
+ proof -
+ fix i
+ assume "i < length x"
+ with a have "enum_ind (ENUM('d) ! i) = i"
+ by (simp)
+ with a show "x ! i = y ! i"
+ by (auto simp add: mk_dimvec_def fun_eq_iff, metis)
+ qed
+
+ then show "x = y"
+ by (metis a(2) a(3) nth_equalityI)
+qed
+
+lemma mk_dimvec_eq_iff [simp]:
+ assumes "length x = CARD('d)" "length y = CARD('d)"
+ shows "((mk_dimvec x :: ('n::ring_1, 'd::enum) dimvec) = mk_dimvec y) \<longleftrightarrow> (x = y)"
+ by (rule inj_on_eq_iff[OF mk_dimvec_inj], simp_all add: assms)
+
+lemma one_mk_dimvec [code, si_def]: "(1::('n::ring_1, 'a::enum) dimvec) = mk_dimvec (replicate CARD('a) 0)"
+ by (auto simp add: mk_dimvec_def one_dimvec_def)
+
+lemma times_mk_dimvec [code, si_def]:
+ "(mk_dimvec xs * mk_dimvec ys :: ('n::ring_1, 'a::enum) dimvec) =
+ (if (length xs = CARD('a) \<and> length ys = CARD('a))
+ then mk_dimvec (map (\<lambda> (x, y). x + y) (zip xs ys))
+ else if length xs = CARD('a) then mk_dimvec xs else mk_dimvec ys)"
+ by (auto simp add: times_dimvec_def mk_dimvec_def fun_eq_iff one_dimvec_def)
+
+lemma power_mk_dimvec [si_def]:
+ "(power (mk_dimvec xs) n :: ('n::ring_1, 'a::enum) dimvec) =
+ (if (length xs = CARD('a)) then mk_dimvec (map ((*) (of_nat n)) xs) else mk_dimvec xs)"
+ by (induct n, simp add: one_dimvec_def mk_dimvec_def)
+ (auto simp add: times_mk_dimvec zip_map_map[where f="id", simplified] comp_def split_beta' zip_same_conv_map distrib_right mult.commute)
+
+lemma inverse_mk_dimvec [code, si_def]:
+ "(inverse (mk_dimvec xs) :: ('n::ring_1, 'a::enum) dimvec) =
+ (if (length xs = CARD('a)) then mk_dimvec (map uminus xs) else 1)"
+ by (auto simp add: inverse_dimvec_def one_dimvec_def mk_dimvec_def fun_eq_iff)
+
+lemma divide_mk_dimvec [code, si_def]:
+ "(mk_dimvec xs / mk_dimvec ys :: ('n::ring_1, 'a::enum) dimvec) =
+ (if (length xs = CARD('a) \<and> length ys = CARD('a))
+ then mk_dimvec (map (\<lambda> (x, y). x - y) (zip xs ys))
+ else if length ys = CARD('a) then mk_dimvec (map uminus ys) else mk_dimvec xs)"
+ by (auto simp add: divide_dimvec_def inverse_mk_dimvec times_mk_dimvec zip_map_map[where f="id", simplified] comp_def split_beta')
+
+text \<open> A base dimension is a dimension where precisely one component has power 1: it is the
+ dimension of a base quantity. Here we define the seven base dimensions. \<close>
+
+definition mk_BaseDim :: "'d::enum \<Rightarrow> (int, 'd) dimvec" where
+"mk_BaseDim d = dim_lambda (\<lambda> i. if (i = d) then 1 else 0)"
+
+lemma mk_BaseDim_neq [simp]: "x \<noteq> y \<Longrightarrow> mk_BaseDim x \<noteq> mk_BaseDim y"
+ by (auto simp add: mk_BaseDim_def fun_eq_iff)
+
+lemma mk_BaseDim_code [code]: "mk_BaseDim (d::'d::enum) = mk_dimvec (list_update (replicate CARD('d) 0) (enum_ind d) 1)"
+ by (auto simp add: mk_BaseDim_def mk_dimvec_def fun_eq_iff)
+
+definition is_BaseDim :: "(int, 'd::enum) dimvec \<Rightarrow> bool"
+ where "is_BaseDim x \<equiv> (\<exists> i. x = dim_lambda ((\<lambda> x. 0)(i := 1)))"
+
+lemma is_BaseDim_mk [simp]: "is_BaseDim (mk_BaseDim x)"
+ by (auto simp add: mk_BaseDim_def is_BaseDim_def fun_eq_iff)
+
+subsection \<open> Dimension Semantic Domain \<close>
+
+text \<open> We next specialise dimension vectors to the usual seven place vector. \<close>
+
+datatype sdim = Length | Mass | Time | Current | Temperature | Amount | Intensity
+
+lemma sdim_UNIV: "(UNIV :: sdim set) = {Length, Mass, Time, Current, Temperature, Amount, Intensity}"
+ using sdim.exhaust by blast
+
+lemma CARD_sdim [simp]: "CARD(sdim) = 7"
+ by (simp add: sdim_UNIV)
+
+instantiation sdim :: enum
+begin
+ definition "enum_sdim = [Length, Mass, Time, Current, Temperature, Amount, Intensity]"
+ definition "enum_all_sdim P \<longleftrightarrow> P Length \<and> P Mass \<and> P Time \<and> P Current \<and> P Temperature \<and> P Amount \<and> P Intensity"
+ definition "enum_ex_sdim P \<longleftrightarrow> P Length \<or> P Mass \<or> P Time \<or> P Current \<or> P Temperature \<or> P Amount \<or> P Intensity"
+ instance
+ by (intro_classes, simp_all add: sdim_UNIV enum_sdim_def enum_all_sdim_def enum_ex_sdim_def)
+end
+
+instantiation sdim :: card_UNIV
+begin
+ definition "finite_UNIV = Phantom(sdim) True"
+ definition "card_UNIV = Phantom(sdim) 7"
+ instance by (intro_classes, simp_all add: finite_UNIV_sdim_def card_UNIV_sdim_def)
+end
+
+lemma sdim_enum [simp]:
+ "enum_ind Length = 0" "enum_ind Mass = 1" "enum_ind Time = 2" "enum_ind Current = 3"
+ "enum_ind Temperature = 4" "enum_ind Amount = 5" "enum_ind Intensity = 6"
+ by (simp_all add: enum_ind_def enum_sdim_def)
+
+type_synonym Dimension = "(int, sdim) dimvec"
+
+abbreviation LengthBD ("\<^bold>L") where "\<^bold>L \<equiv> mk_BaseDim Length"
+abbreviation MassBD ("\<^bold>M") where "\<^bold>M \<equiv> mk_BaseDim Mass"
+abbreviation TimeBD ("\<^bold>T") where "\<^bold>T \<equiv> mk_BaseDim Time"
+abbreviation CurrentBD ("\<^bold>I") where "\<^bold>I \<equiv> mk_BaseDim Current"
+abbreviation TemperatureBD ("\<^bold>\<Theta>") where "\<^bold>\<Theta> \<equiv> mk_BaseDim Temperature"
+abbreviation AmountBD ("\<^bold>N") where "\<^bold>N \<equiv> mk_BaseDim Amount"
+abbreviation IntensityBD ("\<^bold>J") where "\<^bold>J \<equiv> mk_BaseDim Intensity"
+
+abbreviation "BaseDimensions \<equiv> {\<^bold>L, \<^bold>M, \<^bold>T, \<^bold>I, \<^bold>\<Theta>, \<^bold>N, \<^bold>J}"
+
+lemma BD_mk_dimvec [si_def]:
+ "\<^bold>L = mk_dimvec [1, 0, 0, 0, 0, 0, 0]"
+ "\<^bold>M = mk_dimvec [0, 1, 0, 0, 0, 0, 0]"
+ "\<^bold>T = mk_dimvec [0, 0, 1, 0, 0, 0, 0]"
+ "\<^bold>I = mk_dimvec [0, 0, 0, 1, 0, 0, 0]"
+ "\<^bold>\<Theta> = mk_dimvec [0, 0, 0, 0, 1, 0, 0]"
+ "\<^bold>N = mk_dimvec [0, 0, 0, 0, 0, 1, 0]"
+ "\<^bold>J = mk_dimvec [0, 0, 0, 0, 0, 0, 1]"
+ by (simp_all add: mk_BaseDim_code eval_nat_numeral)
+
+text \<open> The following lemma confirms that there are indeed seven unique base dimensions. \<close>
+
+lemma seven_BaseDimensions: "card BaseDimensions = 7"
+ by simp
+
+text \<open> We can use the base dimensions and algebra to form dimension expressions. Some examples
+ are shown below. \<close>
+
+term "\<^bold>L\<cdot>\<^bold>M\<cdot>\<^bold>T\<^sup>-\<^sup>2"
+term "\<^bold>M\<cdot>\<^bold>L\<^sup>-\<^sup>3"
+
+value "\<^bold>L\<cdot>\<^bold>M\<cdot>\<^bold>T\<^sup>-\<^sup>2"
+
+lemma "\<^bold>L\<cdot>\<^bold>M\<cdot>\<^bold>T\<^sup>-\<^sup>2 = mk_dimvec [1, 1, - 2, 0, 0, 0, 0]"
+ by (simp add: si_def)
+
+subsection \<open> Dimension Type Expressions \<close>
+
+subsubsection \<open> Classification \<close>
+
+text \<open> We provide a syntax for dimension type expressions, which allows representation of
+ dimensions as types in Isabelle. This will allow us to represent quantities that are parametrised
+ by a particular dimension type. We first must characterise the subclass of types that represent a
+ dimension.
+
+ The mechanism in Isabelle to characterize a certain subclass of Isabelle type expressions
+ are \<^emph>\<open>type classes\<close>. The following type class is used to link particular Isabelle types
+ to an instance of the type \<^typ>\<open>Dimension\<close>. It requires that any such type has the cardinality
+ \<^term>\<open>1\<close>, since a dimension type is used only to mark a quantity.
+ \<close>
+
+class dim_type = unitary +
+ fixes dim_ty_sem :: "'a itself \<Rightarrow> Dimension"
+
+syntax
+ "_QD" :: "type \<Rightarrow> logic" ("QD'(_')")
+
+translations
+ "QD('a)" == "CONST dim_ty_sem TYPE('a)"
+
+text \<open> The notation \<^term>\<open>QD('a::dim_type)\<close> allows to obtain the dimension of a dimension type
+ \<^typ>\<open>'a\<close>.
+
+ The subset of basic dimension types can be characterized by the following type class: \<close>
+
+class basedim_type = dim_type +
+ assumes is_BaseDim: "is_BaseDim QD('a)"
+
+subsubsection \<open> Base Dimension Type Expressions \<close>
+
+text \<open> The definition of the basic dimension type constructors is straightforward via a
+ one-elementary set, \<^typ>\<open>unit set\<close>. The latter is adequate since we need just an abstract syntax
+ for type expressions, so just one value for the \<^verbatim>\<open>dimension\<close>-type symbols. We define types for
+ each of the seven base dimensions, and also for dimensionless quantities. \<close>
+
+typedef Length = "UNIV :: unit set" .. setup_lifting type_definition_Length
+typedef Mass = "UNIV :: unit set" .. setup_lifting type_definition_Mass
+typedef Time = "UNIV :: unit set" .. setup_lifting type_definition_Time
+typedef Current = "UNIV :: unit set" .. setup_lifting type_definition_Current
+typedef Temperature = "UNIV :: unit set" .. setup_lifting type_definition_Temperature
+typedef Amount = "UNIV :: unit set" .. setup_lifting type_definition_Amount
+typedef Intensity = "UNIV :: unit set" .. setup_lifting type_definition_Intensity
+typedef NoDimension = "UNIV :: unit set" .. setup_lifting type_definition_NoDimension
+
+type_synonym M = Mass
+type_synonym L = Length
+type_synonym T = Time
+type_synonym I = Current
+type_synonym \<Theta> = Temperature
+type_synonym N = Amount
+type_synonym J = Intensity
+type_notation NoDimension ("\<one>")
+
+translations
+ (type) "M" <= (type) "Mass"
+ (type) "L" <= (type) "Length"
+ (type) "T" <= (type) "Time"
+ (type) "I" <= (type) "Current"
+ (type) "\<Theta>" <= (type) "Temperature"
+ (type) "N" <= (type) "Amount"
+ (type) "J" <= (type) "Intensity"
+
+text\<open> Next, we embed the base dimensions into the dimension type expressions by instantiating the
+ class \<^class>\<open>basedim_type\<close> with each of the base dimension types. \<close>
+
+instantiation Length :: basedim_type
+begin
+definition [si_eq]: "dim_ty_sem_Length (_::Length itself) = \<^bold>L"
+instance by (intro_classes, auto simp add: dim_ty_sem_Length_def, (transfer, simp)+)
+end
+
+instantiation Mass :: basedim_type
+begin
+definition [si_eq]: "dim_ty_sem_Mass (_::Mass itself) = \<^bold>M"
+instance by (intro_classes, auto simp add: dim_ty_sem_Mass_def, (transfer, simp)+)
+end
+
+instantiation Time :: basedim_type
+begin
+definition [si_eq]: "dim_ty_sem_Time (_::Time itself) = \<^bold>T"
+instance by (intro_classes, auto simp add: dim_ty_sem_Time_def, (transfer, simp)+)
+end
+
+instantiation Current :: basedim_type
+begin
+definition [si_eq]: "dim_ty_sem_Current (_::Current itself) = \<^bold>I"
+instance by (intro_classes, auto simp add: dim_ty_sem_Current_def, (transfer, simp)+)
+end
+
+instantiation Temperature :: basedim_type
+begin
+definition [si_eq]: "dim_ty_sem_Temperature (_::Temperature itself) = \<^bold>\<Theta>"
+instance by (intro_classes, auto simp add: dim_ty_sem_Temperature_def, (transfer, simp)+)
+end
+
+instantiation Amount :: basedim_type
+begin
+definition [si_eq]: "dim_ty_sem_Amount (_::Amount itself) = \<^bold>N"
+instance by (intro_classes, auto simp add: dim_ty_sem_Amount_def, (transfer, simp)+)
+end
+
+instantiation Intensity :: basedim_type
+begin
+definition [si_eq]: "dim_ty_sem_Intensity (_::Intensity itself) = \<^bold>J"
+instance by (intro_classes, auto simp add: dim_ty_sem_Intensity_def, (transfer, simp)+)
+end
+
+instantiation NoDimension :: dim_type
+begin
+definition [si_eq]: "dim_ty_sem_NoDimension (_::NoDimension itself) = (1::Dimension)"
+instance by (intro_classes, auto simp add: dim_ty_sem_NoDimension_def, (transfer, simp)+)
+end
+
+lemma base_dimension_types [simp]:
+ "is_BaseDim QD(Length)" "is_BaseDim QD(Mass)" "is_BaseDim QD(Time)" "is_BaseDim QD(Current)"
+ "is_BaseDim QD(Temperature)" "is_BaseDim QD(Amount)" "is_BaseDim QD(Intensity)"
+ by (simp_all add: is_BaseDim)
+
+subsubsection \<open> Dimension Type Constructors: Inner Product and Inverse \<close>
+
+text\<open> Dimension type expressions can be constructed by multiplication and division of the base
+ dimension types above. Consequently, we need to define multiplication and inverse operators
+ at the type level as well. On the class of dimension types (in which we have already inserted
+ the base dimension types), the definitions of the type constructors for inner product and inverse is
+ straightforward. \<close>
+
+typedef ('a::dim_type, 'b::dim_type) DimTimes (infixl "\<cdot>" 69) = "UNIV :: unit set" ..
+setup_lifting type_definition_DimTimes
+
+text \<open> The type \<^typ>\<open>('a,'b) DimTimes\<close> is parameterised by two types, \<^typ>\<open>'a\<close> and \<^typ>\<open>'b\<close> that must
+ both be elements of the \<^class>\<open>dim_type\<close> class. As with the base dimensions, it is a unitary type
+ as its purpose is to represent dimension type expressions. We instantiate \<^class>\<open>dim_type\<close> with
+ this type, where the semantics of a product dimension expression is the product of the underlying
+ dimensions. This means that multiplication of two dimension types yields a dimension type. \<close>
+
+instantiation DimTimes :: (dim_type, dim_type) dim_type
+begin
+ definition dim_ty_sem_DimTimes :: "('a \<cdot> 'b) itself \<Rightarrow> Dimension" where
+ [si_eq]: "dim_ty_sem_DimTimes x = QD('a) * QD('b)"
+ instance by (intro_classes, simp_all add: dim_ty_sem_DimTimes_def, (transfer, simp)+)
+end
+
+text \<open> Similarly, we define inversion of dimension types and prove that dimension types are
+ closed under this. \<close>
+
+typedef 'a DimInv ("(_\<^sup>-\<^sup>1)" [999] 999) = "UNIV :: unit set" ..
+setup_lifting type_definition_DimInv
+instantiation DimInv :: (dim_type) dim_type
+begin
+ definition dim_ty_sem_DimInv :: "('a\<^sup>-\<^sup>1) itself \<Rightarrow> Dimension" where
+ [si_eq]: "dim_ty_sem_DimInv x = inverse QD('a)"
+ instance by (intro_classes, simp_all add: dim_ty_sem_DimInv_def, (transfer, simp)+)
+end
+
+subsubsection \<open> Dimension Type Syntax \<close>
+
+text \<open> A division is expressed, as usual, by multiplication with an inverted dimension. \<close>
+
+type_synonym ('a, 'b) DimDiv = "'a \<cdot> ('b\<^sup>-\<^sup>1)" (infixl "'/" 69)
+
+text \<open> A number of further type synonyms allow for more compact notation: \<close>
+
+type_synonym 'a DimSquare = "'a \<cdot> 'a" ("(_)\<^sup>2" [999] 999)
+type_synonym 'a DimCube = "'a \<cdot> 'a \<cdot> 'a" ("(_)\<^sup>3" [999] 999)
+type_synonym 'a DimQuart = "'a \<cdot> 'a \<cdot> 'a \<cdot> 'a" ("(_)\<^sup>4" [999] 999)
+type_synonym 'a DimInvSquare = "('a\<^sup>2)\<^sup>-\<^sup>1" ("(_)\<^sup>-\<^sup>2" [999] 999)
+type_synonym 'a DimInvCube = "('a\<^sup>3)\<^sup>-\<^sup>1" ("(_)\<^sup>-\<^sup>3" [999] 999)
+type_synonym 'a DimInvQuart = "('a\<^sup>4)\<^sup>-\<^sup>1" ("(_)\<^sup>-\<^sup>4" [999] 999)
+
+translations (type) "'a\<^sup>-\<^sup>2" <= (type) "('a\<^sup>2)\<^sup>-\<^sup>1"
+translations (type) "'a\<^sup>-\<^sup>3" <= (type) "('a\<^sup>3)\<^sup>-\<^sup>1"
+translations (type) "'a\<^sup>-\<^sup>4" <= (type) "('a\<^sup>4)\<^sup>-\<^sup>1"
+
+print_translation \<open>
+ [(@{type_syntax DimTimes},
+ fn ctx => fn [a, b] =>
+ if (a = b)
+ then Const (@{type_syntax DimSquare}, dummyT) $ a
+ else case a of
+ Const (@{type_syntax DimTimes}, _) $ a1 $ a2 =>
+ if (a1 = a2 andalso a2 = b)
+ then Const (@{type_syntax DimCube}, dummyT) $ a1
+ else case a1 of
+ Const (@{type_syntax DimTimes}, _) $ a11 $ a12 =>
+ if (a11 = a12 andalso a12 = a2 andalso a2 = b)
+ then Const (@{type_syntax DimQuart}, dummyT) $ a11
+ else raise Match |
+ _ => raise Match)]
+\<close>
+
+subsubsection \<open> Derived Dimension Types \<close>
+
+type_synonym Area = "L\<^sup>2"
+type_synonym Volume = "L\<^sup>3"
+type_synonym Acceleration = "L\<cdot>T\<^sup>-\<^sup>1"
+type_synonym Frequency = "T\<^sup>-\<^sup>1"
+type_synonym Energy = "L\<^sup>2\<cdot>M\<cdot>T\<^sup>-\<^sup>2"
+type_synonym Power = "L\<^sup>2\<cdot>M\<cdot>T\<^sup>-\<^sup>3"
+type_synonym Force = "L\<cdot>M\<cdot>T\<^sup>-\<^sup>2"
+type_synonym Pressure = "L\<^sup>-\<^sup>1\<cdot>M\<cdot>T\<^sup>-\<^sup>2"
+type_synonym Charge = "I\<cdot>T"
+type_synonym PotentialDifference = "L\<^sup>2\<cdot>M\<cdot>T\<^sup>-\<^sup>3\<cdot>I\<^sup>-\<^sup>1"
+type_synonym Capacitance = "L\<^sup>-\<^sup>2\<cdot>M\<^sup>-\<^sup>1\<cdot>T\<^sup>4\<cdot>I\<^sup>2"
+
+subsection \<open> ML Functions \<close>
+
+text \<open> We define ML functions for converting a dimension to an integer vector, and vice-versa.
+ These are useful for normalising dimension types. \<close>
+
+ML \<open>
+signature DIMENSION_TYPE =
+sig
+ val dim_to_typ: int list -> typ
+ val typ_to_dim: typ -> int list
+ val normalise: typ -> typ
+end
+
+structure Dimension_Type : DIMENSION_TYPE =
+struct
+
+ val dims = [@{typ L}, @{typ M}, @{typ T}, @{typ I}, @{typ \<Theta>}, @{typ N}, @{typ J}];
+
+ fun typ_to_dim (Type (@{type_name Length}, [])) = [1, 0, 0, 0, 0, 0, 0] |
+ typ_to_dim (Type (@{type_name Mass}, [])) = [0, 1, 0, 0, 0, 0, 0] |
+ typ_to_dim (Type (@{type_name Time}, [])) = [0, 0, 1, 0, 0, 0, 0] |
+ typ_to_dim (Type (@{type_name Current}, [])) = [0, 0, 0, 1, 0, 0, 0] |
+ typ_to_dim (Type (@{type_name Temperature}, [])) = [0, 0, 0, 0, 1, 0, 0] |
+ typ_to_dim (Type (@{type_name Amount}, [])) = [0, 0, 0, 0, 0, 1, 0] |
+ typ_to_dim (Type (@{type_name Intensity}, [])) = [0, 0, 0, 0, 0, 0, 1] |
+ typ_to_dim (Type (@{type_name NoDimension}, [])) = [0, 0, 0, 0, 0, 0, 0] |
+ typ_to_dim (Type (@{type_name DimInv}, [x])) = map (fn x => 0 - x) (typ_to_dim x) |
+ typ_to_dim (Type (@{type_name DimTimes}, [x, y]))
+ = map (fn (x, y) => x + y) (ListPair.zip (typ_to_dim x, typ_to_dim y)) |
+ typ_to_dim _ = raise Match;
+
+ fun DimPow 0 _ = Type (@{type_name NoDimension}, []) |
+ DimPow 1 t = t |
+ DimPow n t = (if (n > 0) then Type (@{type_name DimTimes}, [DimPow (n - 1) t, t])
+ else Type (@{type_name DimInv}, [DimPow (0 - n) t]));
+
+ fun dim_to_typ ds =
+ let val dts = map (fn (n, d) => DimPow n d) (filter (fn (n, _) => n <> 0) (ListPair.zip (ds, dims)))
+ in if (dts = []) then @{typ NoDimension} else
+ foldl1 (fn (x, y) => Type (@{type_name DimTimes}, [x, y])) dts
+ end;
+
+ val normalise = dim_to_typ o typ_to_dim;
+
+end;
+
+Dimension_Type.typ_to_dim @{typ "L\<^sup>-\<^sup>2\<cdot>M\<^sup>-\<^sup>1\<cdot>T\<^sup>4\<cdot>I\<^sup>2\<cdot>M"};
+Dimension_Type.normalise @{typ "L\<^sup>-\<^sup>2\<cdot>M\<^sup>-\<^sup>1\<cdot>T\<^sup>4\<cdot>I\<^sup>2\<cdot>M"};
+\<close>
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/ISQ_Proof.thy b/thys/Physical_Quantities/ISQ_Proof.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/ISQ_Proof.thy
@@ -0,0 +1,110 @@
+section \<open> Proof Support for Quantities \<close>
+
+theory ISQ_Proof
+ imports ISQ_Quantities
+begin
+
+named_theorems si_transfer
+
+definition magQ :: "'a['u::dim_type, 's::unit_system] \<Rightarrow> 'a" ("\<lbrakk>_\<rbrakk>\<^sub>Q") where
+[si_def]: "magQ x = mag (fromQ x)"
+
+definition dimQ :: "'a['u::dim_type, 's::unit_system] \<Rightarrow> Dimension" where
+[si_def]: "dimQ x = dim (fromQ x)"
+
+lemma quant_eq_iff_mag_eq [si_eq]:
+ "x = y \<longleftrightarrow> \<lbrakk>x\<rbrakk>\<^sub>Q = \<lbrakk>y\<rbrakk>\<^sub>Q"
+ by (auto simp add: magQ_def, transfer, simp add: eq_unit)
+
+lemma quant_eqI [si_transfer]:
+ "\<lbrakk>x\<rbrakk>\<^sub>Q = \<lbrakk>y\<rbrakk>\<^sub>Q \<Longrightarrow> x = y"
+ by (simp add: quant_eq_iff_mag_eq)
+
+lemma quant_equiv_iff [si_eq]:
+ fixes x :: "'a['u\<^sub>1::dim_type, 's::unit_system]" and y :: "'a['u\<^sub>2::dim_type, 's::unit_system]"
+ shows "x \<cong>\<^sub>Q y \<longleftrightarrow> \<lbrakk>x\<rbrakk>\<^sub>Q = \<lbrakk>y\<rbrakk>\<^sub>Q \<and> QD('u\<^sub>1) = QD('u\<^sub>2)"
+proof -
+ have "\<forall>t ta. (ta::'a['u\<^sub>2, 's]) = t \<or> mag (fromQ ta) \<noteq> mag (fromQ t)"
+ by (simp add: magQ_def quant_eq_iff_mag_eq)
+ then show ?thesis
+ by (metis (full_types) qequiv.rep_eq coerceQuant_eq_iff2 qeq magQ_def)
+qed
+
+lemma quant_equivI [si_transfer]:
+ fixes x :: "'a['u\<^sub>1::dim_type, 's::unit_system]" and y :: "'a['u\<^sub>2::dim_type, 's::unit_system]"
+ assumes "QD('u\<^sub>1) = QD('u\<^sub>2)" "QD('u\<^sub>1) = QD('u\<^sub>2) \<Longrightarrow> \<lbrakk>x\<rbrakk>\<^sub>Q = \<lbrakk>y\<rbrakk>\<^sub>Q"
+ shows "x \<cong>\<^sub>Q y"
+ using assms quant_equiv_iff by blast
+
+lemma quant_le_iff_magn_le [si_eq]:
+ "x \<le> y \<longleftrightarrow> \<lbrakk>x\<rbrakk>\<^sub>Q \<le> \<lbrakk>y\<rbrakk>\<^sub>Q"
+ by (auto simp add: magQ_def; (transfer, simp))
+
+lemma quant_leI [si_transfer]:
+ "\<lbrakk>x\<rbrakk>\<^sub>Q \<le> \<lbrakk>y\<rbrakk>\<^sub>Q \<Longrightarrow> x \<le> y"
+ by (simp add: quant_le_iff_magn_le)
+
+lemma quant_less_iff_magn_less [si_eq]:
+ "x < y \<longleftrightarrow> \<lbrakk>x\<rbrakk>\<^sub>Q < \<lbrakk>y\<rbrakk>\<^sub>Q"
+ by (auto simp add: magQ_def; (transfer, simp))
+
+lemma quant_lessI [si_transfer]:
+ "\<lbrakk>x\<rbrakk>\<^sub>Q < \<lbrakk>y\<rbrakk>\<^sub>Q \<Longrightarrow> x < y"
+ by (simp add: quant_less_iff_magn_less)
+
+lemma magQ_zero [si_eq]: "\<lbrakk>0\<rbrakk>\<^sub>Q = 0"
+ by (simp add: magQ_def, transfer, simp)
+
+lemma magQ_one [si_eq]: "\<lbrakk>1\<rbrakk>\<^sub>Q = 1"
+ by (simp add: magQ_def, transfer, simp)
+
+lemma magQ_plus [si_eq]: "\<lbrakk>x + y\<rbrakk>\<^sub>Q = \<lbrakk>x\<rbrakk>\<^sub>Q + \<lbrakk>y\<rbrakk>\<^sub>Q"
+ by (simp add: magQ_def, transfer, simp)
+
+lemma magQ_minus [si_eq]: "\<lbrakk>x - y\<rbrakk>\<^sub>Q = \<lbrakk>x\<rbrakk>\<^sub>Q - \<lbrakk>y\<rbrakk>\<^sub>Q"
+ by (simp add: magQ_def, transfer, simp)
+
+lemma magQ_uminus [si_eq]: "\<lbrakk>- x\<rbrakk>\<^sub>Q = - \<lbrakk>x\<rbrakk>\<^sub>Q"
+ by (simp add: magQ_def, transfer, simp)
+
+lemma magQ_scaleQ [si_eq]: "\<lbrakk>x *\<^sub>Q y\<rbrakk>\<^sub>Q = x * \<lbrakk>y\<rbrakk>\<^sub>Q"
+ by (simp add: magQ_def, transfer, simp)
+
+lemma magQ_qtimes [si_eq]: "\<lbrakk>x \<^bold>\<cdot> y\<rbrakk>\<^sub>Q = \<lbrakk>x\<rbrakk>\<^sub>Q \<cdot> \<lbrakk>y\<rbrakk>\<^sub>Q"
+ by (simp add: magQ_def, transfer, simp)
+
+lemma magQ_qinverse [si_eq]: "\<lbrakk>x\<^sup>-\<^sup>\<one>\<rbrakk>\<^sub>Q = inverse \<lbrakk>x\<rbrakk>\<^sub>Q"
+ by (simp add: magQ_def, transfer, simp)
+
+lemma magQ_qdivivide [si_eq]: "\<lbrakk>(x::('a::field)[_,_]) \<^bold>/ y\<rbrakk>\<^sub>Q = \<lbrakk>x\<rbrakk>\<^sub>Q / \<lbrakk>y\<rbrakk>\<^sub>Q"
+ by (simp add: magQ_def, transfer, simp add: field_class.field_divide_inverse)
+
+lemma magQ_numeral [si_eq]: "\<lbrakk>numeral n\<rbrakk>\<^sub>Q = numeral n"
+ apply (induct n, simp_all add: si_def)
+ apply (metis magQ_def magQ_one)
+ apply (metis magQ_def magQ_plus numeral_code(2))
+ apply (metis magQ_def magQ_one magQ_plus numeral_code(3))
+ done
+
+lemma magQ_coerce [si_eq]:
+ fixes q :: "'a['d\<^sub>1::dim_type, 's::unit_system]" and t :: "'d\<^sub>2::dim_type itself"
+ assumes "QD('d\<^sub>1) = QD('d\<^sub>2)"
+ shows "\<lbrakk>coerceQuantT t q\<rbrakk>\<^sub>Q = \<lbrakk>q\<rbrakk>\<^sub>Q"
+ by (simp add: coerceQuantT_def magQ_def assms, metis assms qequiv.rep_eq updown_eq_iff)
+
+lemma dimQ [simp]: "dimQ(x :: 'a['d::dim_type, 's::unit_system]) = QD('d)"
+ by (simp add: dimQ_def, transfer, simp)
+
+text \<open> The following tactic breaks an SI conjecture down to numeric and unit properties \<close>
+
+method si_simp uses add =
+ (rule_tac si_transfer; simp add: add si_eq field_simps)
+
+text \<open> The next tactic additionally compiles the semantics of the underlying units \<close>
+
+method si_calc uses add =
+ (si_simp add: add; simp add: si_def add)
+
+lemma "QD(N \<cdot> \<Theta> \<cdot> N) = QD(\<Theta> \<cdot> N\<^sup>2)" by (simp add: si_eq si_def)
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/ISQ_Quantities.thy b/thys/Physical_Quantities/ISQ_Quantities.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/ISQ_Quantities.thy
@@ -0,0 +1,515 @@
+section \<open> Quantities \<close>
+
+theory ISQ_Quantities
+ imports ISQ_Dimensions
+begin
+
+subsection \<open> Quantity Semantic Domain \<close>
+
+text \<open> Here, we give a semantic domain for particular values of physical quantities. A quantity
+ is usually expressed as a number and a measurement unit, and the goal is to support this. First,
+ though, we give a more general semantic domain where a quantity has a magnitude and a dimension. \<close>
+
+record ('a, 'd::enum) Quantity =
+ mag :: 'a \<comment> \<open> Magnitude of the quantity. \<close>
+ dim :: "(int, 'd) dimvec" \<comment> \<open> Dimension of the quantity -- denotes the kind of quantity. \<close>
+
+text \<open> The quantity type is parametric as we permit the magnitude to be represented using any kind
+ of numeric type, such as \<^typ>\<open>int\<close>, \<^typ>\<open>rat\<close>, or \<^typ>\<open>real\<close>, though we usually minimally expect
+ a field. \<close>
+
+lemma Quantity_eq_intro:
+ assumes "mag x = mag y" "dim x = dim y" "more x = more y"
+ shows "x = y"
+ by (simp add: assms eq_unit)
+
+text \<open> We can define several arithmetic operators on quantities. Multiplication takes multiplies
+ both the magnitudes and the dimensions. \<close>
+
+instantiation Quantity_ext :: (times, enum, times) times
+begin
+definition times_Quantity_ext ::
+ "('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme"
+ where [si_def]: "times_Quantity_ext x y = \<lparr> mag = mag x \<cdot> mag y, dim = dim x \<cdot> dim y,
+ \<dots> = more x \<cdot> more y \<rparr>"
+instance ..
+end
+
+lemma mag_times [simp]: "mag (x \<cdot> y) = mag x \<cdot> mag y" by (simp add: times_Quantity_ext_def)
+lemma dim_times [simp]: "dim (x \<cdot> y) = dim x \<cdot> dim y" by (simp add: times_Quantity_ext_def)
+lemma more_times [simp]: "more (x \<cdot> y) = more x \<cdot> more y" by (simp add: times_Quantity_ext_def)
+
+text \<open> The zero and one quantities are both dimensionless quantities with magnitude of \<^term>\<open>0\<close> and
+ \<^term>\<open>1\<close>, respectively. \<close>
+
+instantiation Quantity_ext :: (zero, enum, zero) zero
+begin
+ definition "zero_Quantity_ext = \<lparr> mag = 0, dim = 1, \<dots> = 0 \<rparr>"
+instance ..
+end
+
+lemma mag_zero [simp]: "mag 0 = 0" by (simp add: zero_Quantity_ext_def)
+lemma dim_zero [simp]: "dim 0 = 1" by (simp add: zero_Quantity_ext_def)
+lemma more_zero [simp]: "more 0 = 0" by (simp add: zero_Quantity_ext_def)
+
+instantiation Quantity_ext :: (one, enum, one) one
+begin
+ definition [si_def]: "one_Quantity_ext = \<lparr> mag = 1, dim = 1, \<dots> = 1 \<rparr>"
+instance ..
+end
+
+lemma mag_one [simp]: "mag 1 = 1" by (simp add: one_Quantity_ext_def)
+lemma dim_one [simp]: "dim 1 = 1" by (simp add: one_Quantity_ext_def)
+lemma more_one [simp]: "more 1 = 1" by (simp add: one_Quantity_ext_def)
+
+text \<open> Quantity inversion inverts both the magnitude and the dimension. Similarly, division of
+ one quantity by another, divides both the magnitudes and the dimensions. \<close>
+
+instantiation Quantity_ext :: (inverse, enum, inverse) inverse
+begin
+definition inverse_Quantity_ext :: "('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme" where
+ [si_def]: "inverse_Quantity_ext x = \<lparr> mag = inverse (mag x), dim = inverse (dim x), \<dots> = inverse (more x) \<rparr>"
+definition divide_Quantity_ext :: "('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme" where
+ [si_def]: "divide_Quantity_ext x y = \<lparr> mag = mag x / mag y, dim = dim x / dim y, \<dots> = more x / more y \<rparr>"
+instance ..
+end
+
+lemma mag_inverse [simp]: "mag (inverse x) = inverse (mag x)"
+ by (simp add: inverse_Quantity_ext_def)
+
+lemma dim_inverse [simp]: "dim (inverse x) = inverse (dim x)"
+ by (simp add: inverse_Quantity_ext_def)
+
+lemma more_inverse [simp]: "more (inverse x) = inverse (more x)"
+ by (simp add: inverse_Quantity_ext_def)
+
+lemma mag_divide [simp]: "mag (x / y) = mag x / mag y"
+ by (simp add: divide_Quantity_ext_def)
+
+lemma dim_divide [simp]: "dim (x / y) = dim x / dim y"
+ by (simp add: divide_Quantity_ext_def)
+
+lemma more_divide [simp]: "more (x / y) = more x / more y"
+ by (simp add: divide_Quantity_ext_def)
+
+text \<open> As for dimensions, quantities form a commutative monoid and an abelian group. \<close>
+
+instance Quantity_ext :: (comm_monoid_mult, enum, comm_monoid_mult) comm_monoid_mult
+ by (intro_classes, simp_all add: eq_unit one_Quantity_ext_def times_Quantity_ext_def mult.assoc
+ ,simp add: mult.commute)
+
+instance Quantity_ext :: (ab_group_mult, enum, ab_group_mult) ab_group_mult
+ by (intro_classes, rule Quantity_eq_intro, simp_all add: eq_unit)
+
+text \<open> We can also define a partial order on quantities. \<close>
+
+instantiation Quantity_ext :: (ord, enum, ord) ord
+begin
+ definition less_eq_Quantity_ext :: "('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme \<Rightarrow> bool"
+ where "less_eq_Quantity_ext x y = (mag x \<le> mag y \<and> dim x = dim y \<and> more x \<le> more y)"
+ definition less_Quantity_ext :: "('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme \<Rightarrow> bool"
+ where "less_Quantity_ext x y = (x \<le> y \<and> \<not> y \<le> x)"
+
+instance ..
+
+end
+
+instance Quantity_ext :: (order, enum, order) order
+ by (intro_classes, auto simp add: less_Quantity_ext_def less_eq_Quantity_ext_def eq_unit)
+
+text \<open> We can define plus and minus as well, but these are partial operators as they are defined
+ only when the quantities have the same dimension. \<close>
+
+instantiation Quantity_ext :: (plus, enum, plus) plus
+begin
+definition plus_Quantity_ext :: "('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme"
+ where [si_def]:
+ "dim x = dim y \<Longrightarrow>
+ plus_Quantity_ext x y = \<lparr> mag = mag x + mag y, dim = dim x, \<dots> = more x + more y \<rparr>"
+instance ..
+end
+
+instantiation Quantity_ext :: (uminus, enum, uminus) uminus
+begin
+ definition uminus_Quantity_ext :: "('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme" where
+ [si_def]: "uminus_Quantity_ext x = \<lparr> mag = - mag x , dim = dim x, \<dots> = - more x \<rparr>"
+instance ..
+end
+
+instantiation Quantity_ext :: (minus, enum, minus) minus
+begin
+ definition minus_Quantity_ext :: "('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme \<Rightarrow> ('a, 'b, 'c) Quantity_scheme" where
+ [si_def]:
+ "dim x = dim y \<Longrightarrow>
+ minus_Quantity_ext x y = \<lparr> mag = mag x - mag y, dim = dim x, \<dots> = more x - more y \<rparr>"
+instance ..
+end
+
+subsection \<open> Measurement Systems \<close>
+
+class unit_system = unitary
+
+lemma unit_system_intro: "(UNIV::'s set) = {a} \<Longrightarrow> OFCLASS('s, unit_system_class)"
+ by (simp add: unit_system_class_def, rule unitary_intro)
+
+record ('a, 'd::enum, 's::unit_system) Measurement_System = "('a, 'd::enum) Quantity" +
+ unit_sys :: 's \<comment> \<open> The system of units being employed \<close>
+
+definition "mmore = Record.iso_tuple_snd Measurement_System_ext_Tuple_Iso"
+
+lemma mmore [simp]: "mmore \<lparr> unit_sys = x, \<dots> = y \<rparr> = y"
+ by (metis Measurement_System.ext_inject Measurement_System.ext_surjective comp_id mmore_def)
+
+lemma mmore_ext [simp]: "\<lparr>unit_sys = unit, \<dots> = mmore a\<rparr> = a"
+ apply (case_tac a, rename_tac b, case_tac b)
+ apply (simp add: Measurement_System_ext_def mmore_def Measurement_System_ext_Tuple_Iso_def Record.iso_tuple_snd_def Record.iso_tuple_cons_def Abs_Measurement_System_ext_inverse)
+ apply (rename_tac x y z)
+ apply (subgoal_tac "unit = y")
+ apply (simp)
+ apply (simp add: eq_unit)
+ done
+
+lemma Measurement_System_eq_intro:
+ assumes "mag x = mag y" "dim x = dim y" "more x = more y"
+ shows "x = y"
+ by (rule Quantity_eq_intro, simp_all add: assms)
+ (metis Measurement_System.surjective Quantity.select_convs(3) assms(3) mmore mmore_ext)
+
+instantiation Measurement_System_ext :: (unit_system, "zero") "zero"
+begin
+definition zero_Measurement_System_ext :: "('a, 'b) Measurement_System_ext"
+ where [si_def]: "zero_Measurement_System_ext = \<lparr> unit_sys = unit, \<dots> = 0 \<rparr>"
+instance ..
+end
+
+instantiation Measurement_System_ext :: (unit_system, "one") "one"
+begin
+definition one_Measurement_System_ext :: "('a, 'b) Measurement_System_ext"
+ where [si_def]: "one_Measurement_System_ext = \<lparr> unit_sys = unit, \<dots> = 1 \<rparr>"
+instance ..
+end
+
+instantiation Measurement_System_ext :: (unit_system, times) times
+begin
+definition times_Measurement_System_ext ::
+ "('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext"
+ where [si_def]: "times_Measurement_System_ext x y = \<lparr> unit_sys = unit, \<dots> = mmore x \<cdot> mmore y \<rparr>"
+instance ..
+end
+
+instantiation Measurement_System_ext :: (unit_system, inverse) inverse
+begin
+definition inverse_Measurement_System_ext :: "('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext" where
+ [si_def]: "inverse_Measurement_System_ext x = \<lparr> unit_sys = unit, \<dots> = inverse (mmore x) \<rparr>"
+definition divide_Measurement_System_ext ::
+ "('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext"
+ where [si_def]: "divide_Measurement_System_ext x y = \<lparr> unit_sys = unit, \<dots> = mmore x / mmore y \<rparr>"
+instance ..
+end
+
+instance Measurement_System_ext :: (unit_system, comm_monoid_mult) comm_monoid_mult
+ by (intro_classes, simp_all add: eq_unit one_Measurement_System_ext_def times_Measurement_System_ext_def mult.assoc, simp add: mult.commute)
+
+instance Measurement_System_ext :: (unit_system, ab_group_mult) ab_group_mult
+ by (intro_classes, simp_all add: si_def)
+
+instantiation Measurement_System_ext :: (unit_system, ord) ord
+begin
+ definition less_eq_Measurement_System_ext :: "('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext \<Rightarrow> bool"
+ where "less_eq_Measurement_System_ext x y = (mmore x \<le> mmore y)"
+ definition less_Measurement_System_ext :: "('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext \<Rightarrow> bool"
+ where "less_Measurement_System_ext x y = (x \<le> y \<and> \<not> y \<le> x)"
+instance ..
+
+end
+
+instance Measurement_System_ext :: (unit_system, order) order
+ by (intro_classes, simp_all add: less_eq_Measurement_System_ext_def less_Measurement_System_ext_def, metis mmore_ext)
+
+instantiation Measurement_System_ext :: (unit_system, plus) plus
+begin
+definition plus_Measurement_System_ext ::
+ "('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext"
+ where [si_def]:
+ "plus_Measurement_System_ext x y = \<lparr> unit_sys = unit, \<dots> = mmore x + mmore y \<rparr>"
+instance ..
+end
+
+instantiation Measurement_System_ext :: (unit_system, uminus) uminus
+begin
+ definition uminus_Measurement_System_ext :: "('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext" where
+ [si_def]: "uminus_Measurement_System_ext x = \<lparr> unit_sys = unit, \<dots> = - mmore x \<rparr>"
+instance ..
+end
+
+instantiation Measurement_System_ext :: (unit_system, minus) minus
+begin
+ definition minus_Measurement_System_ext ::
+ "('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext \<Rightarrow> ('a, 'b) Measurement_System_ext" where
+ [si_def]:
+ "minus_Measurement_System_ext x y = \<lparr> unit_sys = unit, \<dots> = mmore x - mmore y \<rparr>"
+instance ..
+end
+
+subsection \<open> Dimension Typed Quantities \<close>
+
+text \<open> We can now define the type of quantities with parametrised dimension types. \<close>
+
+typedef (overloaded) ('n, 'd::dim_type, 's::unit_system) QuantT ("_[_, _]" [999,0,0] 999)
+ = "{x :: ('n, sdim, 's) Measurement_System. dim x = QD('d)}"
+ morphisms fromQ toQ by (rule_tac x="\<lparr> mag = undefined, dim = QD('d), unit_sys = unit \<rparr>" in exI, simp)
+
+setup_lifting type_definition_QuantT
+
+text \<open> A dimension typed quantity is parameterised by two types: \<^typ>\<open>'a\<close>, the numeric type for the
+ magntitude, and \<^typ>\<open>'d\<close> for the dimension expression, which is an element of \<^class>\<open>dim_type\<close>.
+ The type \<^typ>\<open>('n, 'd, 's) QuantT\<close> is to \<^typ>\<open>('n, 'd, 's) Measurement_System\<close> as dimension types
+ are to \<^typ>\<open>Dimension\<close>. Specifically, an element of \<^typ>\<open>('n', 'd, 's) QuantT\<close> is a quantity whose
+ dimension is \<^typ>\<open>'d\<close>.
+
+ Intuitively, the formula \<^term>\<open>x :: 'n['d, 's]\<close> can be read as ``$x$ is a quantity of \<^typ>\<open>'d\<close>'',
+ for example it might be a quantity of length, or a quantity of mass. \<close>
+
+text \<open> Since quantities can have dimension type expressions that are distinct, but denote the same
+ dimension, it is necessary to define the following function for coercion between two dimension
+ expressions. This requires that the underlying dimensions are the same. \<close>
+
+definition coerceQuantT :: "'d\<^sub>2 itself \<Rightarrow> 'a['d\<^sub>1::dim_type, 's::unit_system] \<Rightarrow> 'a['d\<^sub>2::dim_type, 's]" where
+[si_def]: "QD('d\<^sub>1) = QD('d\<^sub>2) \<Longrightarrow> coerceQuantT t x = (toQ (fromQ x))"
+
+syntax
+ "_QCOERCE" :: "type \<Rightarrow> logic \<Rightarrow> logic" ("QCOERCE[_]")
+
+translations
+ "QCOERCE['t]" == "CONST coerceQuantT TYPE('t)"
+
+subsection \<open> Predicates on Typed Quantities \<close>
+
+text \<open> The standard HOL order \<^term>\<open>(\<le>)\<close> and equality \<^term>\<open>(=)\<close> have the homogeneous type
+ \<^typ>\<open>'a \<Rightarrow> 'a \<Rightarrow> bool\<close> and so they cannot compare values of different types. Consequently,
+ we define a heterogeneous order and equivalence on typed quantities. \<close>
+
+lift_definition qless_eq :: "'n::order['a::dim_type, 's::unit_system] \<Rightarrow> 'n['b::dim_type, 's] \<Rightarrow> bool" (infix "\<lesssim>\<^sub>Q" 50)
+ is "(\<le>)" .
+
+lift_definition qequiv :: "'n['a::dim_type, 's::unit_system] \<Rightarrow> 'n['b::dim_type, 's] \<Rightarrow> bool" (infix "\<cong>\<^sub>Q" 50)
+ is "(=)" .
+
+text \<open> These are both fundamentally the same as the usual order and equality relations, but they
+ permit potentially different dimension types, \<^typ>\<open>'a\<close> and \<^typ>\<open>'b\<close>. Two typed quantities are
+ comparable only when the two dimension types have the same semantic dimension.
+\<close>
+
+lemma qequiv_refl [simp]: "a \<cong>\<^sub>Q a"
+ by (simp add: qequiv_def)
+
+lemma qequiv_sym: "a \<cong>\<^sub>Q b \<Longrightarrow> b \<cong>\<^sub>Q a"
+ by (simp add: qequiv_def)
+
+lemma qequiv_trans: "\<lbrakk> a \<cong>\<^sub>Q b; b \<cong>\<^sub>Q c \<rbrakk> \<Longrightarrow> a \<cong>\<^sub>Q c"
+ by (simp add: qequiv_def)
+
+theorem qeq_iff_same_dim:
+ fixes x y :: "'a['d::dim_type, 's::unit_system]"
+ shows "x \<cong>\<^sub>Q y \<longleftrightarrow> x = y"
+ by (transfer, simp)
+
+lemma coerceQuant_eq_iff:
+ fixes x :: "'a['d\<^sub>1::dim_type, 's::unit_system]"
+ assumes "QD('d\<^sub>1) = QD('d\<^sub>2::dim_type)"
+ shows "(coerceQuantT TYPE('d\<^sub>2) x) \<cong>\<^sub>Q x"
+ by (metis qequiv.rep_eq assms coerceQuantT_def toQ_cases toQ_inverse)
+
+lemma coerceQuant_eq_iff2:
+ fixes x :: "'a['d\<^sub>1::dim_type, 's::unit_system]"
+ assumes "QD('d\<^sub>1) = QD('d\<^sub>2::dim_type)" and "y = (coerceQuantT TYPE('d\<^sub>2) x)"
+ shows "x \<cong>\<^sub>Q y"
+ using qequiv_sym assms(1) assms(2) coerceQuant_eq_iff by blast
+
+lemma updown_eq_iff:
+ fixes x :: "'a['d\<^sub>1::dim_type, 's::unit_system]" fixes y :: "'a['d\<^sub>2::dim_type, 's]"
+ assumes "QD('d\<^sub>1) = QD('d\<^sub>2::dim_type)" and "y = (toQ (fromQ x))"
+ shows "x \<cong>\<^sub>Q y"
+ by (simp add: assms(1) assms(2) coerceQuant_eq_iff2 coerceQuantT_def)
+
+text\<open>This is more general that \<open>y = x \<Longrightarrow> x \<cong>\<^sub>Q y\<close>, since x and y may have different type.\<close>
+
+lemma qeq:
+ fixes x :: "'a['d\<^sub>1::dim_type, 's::unit_system]" fixes y :: "'a['d\<^sub>2::dim_type, 's]"
+ assumes "x \<cong>\<^sub>Q y"
+ shows "QD('d\<^sub>1) = QD('d\<^sub>2)"
+ by (metis (full_types) qequiv.rep_eq assms fromQ mem_Collect_eq)
+
+subsection\<open> Operators on Typed Quantities \<close>
+
+text \<open> We define several operators on typed quantities. These variously compose the dimension types
+ as well. Multiplication composes the two dimension types. Inverse constructs and inverted
+ dimension type. Division is defined in terms of multiplication and inverse. \<close>
+
+lift_definition
+ qtimes :: "('n::comm_ring_1)['a::dim_type, 's::unit_system] \<Rightarrow> 'n['b::dim_type, 's] \<Rightarrow> 'n['a \<cdot>'b, 's]" (infixl "\<^bold>\<cdot>" 69)
+ is "(*)" by (simp add: dim_ty_sem_DimTimes_def times_Quantity_ext_def)
+
+lift_definition
+ qinverse :: "('n::field)['a::dim_type, 's::unit_system] \<Rightarrow> 'n['a\<^sup>-\<^sup>1, 's]" ("(_\<^sup>-\<^sup>\<one>)" [999] 999)
+ is "inverse" by (simp add: inverse_Quantity_ext_def dim_ty_sem_DimInv_def)
+
+abbreviation (input)
+ qdivide :: "('n::field)['a::dim_type, 's::unit_system] \<Rightarrow> 'n['b::dim_type, 's] \<Rightarrow> 'n['a/'b, 's]" (infixl "\<^bold>'/" 70) where
+"qdivide x y \<equiv> x \<^bold>\<cdot> y\<^sup>-\<^sup>\<one>"
+
+text \<open> We also provide some helpful notations for expressing heterogeneous powers. \<close>
+
+abbreviation qsq ("(_)\<^sup>\<two>" [999] 999) where "u\<^sup>\<two> \<equiv> u\<^bold>\<cdot>u"
+abbreviation qcube ("(_)\<^sup>\<three>" [999] 999) where "u\<^sup>\<three> \<equiv> u\<^bold>\<cdot>u\<^bold>\<cdot>u"
+abbreviation qquart ("(_)\<^sup>\<four>" [999] 999) where "u\<^sup>\<four> \<equiv> u\<^bold>\<cdot>u\<^bold>\<cdot>u\<^bold>\<cdot>u"
+
+abbreviation qneq_sq ("(_)\<^sup>-\<^sup>\<two>" [999] 999) where "u\<^sup>-\<^sup>\<two> \<equiv> (u\<^sup>\<two>)\<^sup>-\<^sup>\<one>"
+abbreviation qneq_cube ("(_)\<^sup>-\<^sup>\<three>" [999] 999) where "u\<^sup>-\<^sup>\<three> \<equiv> (u\<^sup>\<three>)\<^sup>-\<^sup>\<one>"
+abbreviation qneq_quart ("(_)\<^sup>-\<^sup>\<four>" [999] 999) where "u\<^sup>-\<^sup>\<four> \<equiv> (u\<^sup>\<three>)\<^sup>-\<^sup>\<one>"
+
+text \<open> Analogous to the \<^const>\<open>scaleR\<close> operator for vectors, we define the following scalar
+ multiplication that scales an existing quantity by a numeric value. This operator is
+ especially important for the representation of quantity values, which consist of a numeric
+ value and a unit. \<close>
+
+lift_definition scaleQ :: "'a \<Rightarrow> 'a::comm_ring_1['d::dim_type, 's::unit_system] \<Rightarrow> 'a['d, 's]" (infixr "*\<^sub>Q" 63)
+ is "\<lambda> r x. \<lparr> mag = r * mag x, dim = QD('d), unit_sys = unit \<rparr>" by simp
+
+text \<open> Finally, we instantiate the arithmetic types classes where possible. We do not instantiate
+ \<^class>\<open>times\<close> because this results in a nonsensical homogeneous product on quantities. \<close>
+
+instantiation QuantT :: (zero, dim_type, unit_system) zero
+begin
+lift_definition zero_QuantT :: "('a, 'b, 'c) QuantT" is "\<lparr> mag = 0, dim = QD('b), unit_sys = unit \<rparr>"
+ by simp
+instance ..
+end
+
+instantiation QuantT :: (one, dim_type, unit_system) one
+begin
+lift_definition one_QuantT :: "('a, 'b, 'c) QuantT" is "\<lparr> mag = 1, dim = QD('b), unit_sys = unit \<rparr>"
+ by simp
+instance ..
+end
+
+text \<open> The following specialised one element has both magnitude and dimension 1: it is a
+ dimensionless quantity. \<close>
+
+abbreviation qone :: "'n::one[\<one>, 's::unit_system]" ("\<one>") where "qone \<equiv> 1"
+
+text \<open> Unlike for semantic quantities, the plus operator on typed quantities is total, since the
+ type system ensures that the dimensions (and the dimension types) must be the same. \<close>
+
+instantiation QuantT :: (plus, dim_type, unit_system) plus
+begin
+lift_definition plus_QuantT :: "'a['b, 'c] \<Rightarrow> 'a['b, 'c] \<Rightarrow> 'a['b, 'c]"
+ is "\<lambda> x y. \<lparr> mag = mag x + mag y, dim = QD('b), unit_sys = unit \<rparr>"
+ by (simp)
+instance ..
+end
+
+text \<open> We can also show that typed quantities are commutative \<^emph>\<open>additive\<close> monoids. Indeed, addition
+ is a much easier operator to deal with in typed quantities, unlike product. \<close>
+
+instance QuantT :: (semigroup_add,dim_type,unit_system) semigroup_add
+ by (intro_classes, transfer, simp add: add.assoc)
+
+instance QuantT :: (ab_semigroup_add,dim_type,unit_system) ab_semigroup_add
+ by (intro_classes, transfer, simp add: add.commute)
+
+instance QuantT :: (monoid_add,dim_type,unit_system) monoid_add
+ by (intro_classes; (transfer, simp add: eq_unit))
+
+instance QuantT :: (comm_monoid_add,dim_type,unit_system) comm_monoid_add
+ by (intro_classes; transfer, simp)
+
+instantiation QuantT :: (uminus,dim_type,unit_system) uminus
+begin
+lift_definition uminus_QuantT :: "'a['b,'c] \<Rightarrow> 'a['b,'c]"
+ is "\<lambda> x. \<lparr> mag = - mag x, dim = dim x, unit_sys = unit \<rparr>" by (simp)
+instance ..
+end
+
+instantiation QuantT :: (minus,dim_type,unit_system) minus
+begin
+lift_definition minus_QuantT :: "'a['b,'c] \<Rightarrow> 'a['b,'c] \<Rightarrow> 'a['b,'c]"
+ is "\<lambda> x y. \<lparr> mag = mag x - mag y, dim = dim x, unit_sys = unit \<rparr>" by (simp)
+
+instance ..
+end
+
+instance QuantT :: (numeral,dim_type,unit_system) numeral ..
+
+text \<open> Moreover, types quantities also form an additive group. \<close>
+
+instance QuantT :: (ab_group_add,dim_type,unit_system) ab_group_add
+ by (intro_classes, (transfer, simp)+)
+
+text \<open> Typed quantities helpfully can be both partially and a linearly ordered. \<close>
+
+instantiation QuantT :: (order,dim_type,unit_system) order
+begin
+ lift_definition less_eq_QuantT :: "'a['b,'c] \<Rightarrow> 'a['b,'c] \<Rightarrow> bool" is "\<lambda> x y. mag x \<le> mag y" .
+ lift_definition less_QuantT :: "'a['b,'c] \<Rightarrow> 'a['b,'c] \<Rightarrow> bool" is "\<lambda> x y. mag x < mag y" .
+instance by (intro_classes, (transfer, simp add: unit_eq less_le_not_le Measurement_System_eq_intro)+)
+end
+
+instance QuantT :: (linorder,dim_type,unit_system) linorder
+ by (intro_classes, transfer, auto)
+
+instantiation QuantT :: (scaleR,dim_type,unit_system) scaleR
+begin
+lift_definition scaleR_QuantT :: "real \<Rightarrow> 'a['b,'c] \<Rightarrow> 'a['b,'c]"
+is "\<lambda> n q. \<lparr> mag = n *\<^sub>R mag q, dim = dim q, unit_sys = unit \<rparr>" by (simp)
+instance ..
+end
+
+instance QuantT :: (real_vector,dim_type,unit_system) real_vector
+ by (intro_classes, (transfer, simp add: eq_unit scaleR_add_left scaleR_add_right)+)
+
+instantiation QuantT :: (norm,dim_type,unit_system) norm
+begin
+lift_definition norm_QuantT :: "'a['b,'c] \<Rightarrow> real"
+is "\<lambda> x. norm (mag x)" .
+instance ..
+end
+
+instantiation QuantT :: (sgn_div_norm,dim_type,unit_system) sgn_div_norm
+begin
+definition sgn_QuantT :: "'a['b,'c] \<Rightarrow> 'a['b,'c]" where
+"sgn_QuantT x = x /\<^sub>R norm x"
+instance by (intro_classes, simp add: sgn_QuantT_def)
+end
+
+instantiation QuantT :: (dist_norm,dim_type,unit_system) dist_norm
+begin
+definition dist_QuantT :: "'a['b,'c] \<Rightarrow> 'a['b,'c] \<Rightarrow> real" where
+"dist_QuantT x y = norm (x - y)"
+instance
+ by (intro_classes, simp add: dist_QuantT_def)
+end
+
+instantiation QuantT :: ("{uniformity_dist,dist_norm}",dim_type,unit_system) uniformity_dist
+begin
+definition uniformity_QuantT :: "('a['b,'c] \<times> 'a['b,'c]) filter" where
+"uniformity_QuantT = (INF e\<in>{0 <..}. principal {(x, y). dist x y < e})"
+instance
+ by (intro_classes, simp add: uniformity_QuantT_def)
+end
+
+instantiation QuantT :: ("{dist_norm,open_uniformity,uniformity_dist}",dim_type,unit_system)
+ open_uniformity
+begin
+
+definition open_QuantT :: "('a['b,'c]) set \<Rightarrow> bool" where
+"open_QuantT U = (\<forall>x\<in>U. eventually (\<lambda>(x', y). x' = x \<longrightarrow> y \<in> U) uniformity)"
+instance by (intro_classes, simp add: open_QuantT_def)
+end
+
+text \<open> Quantities form a real normed vector space. \<close>
+
+instance QuantT :: (real_normed_vector,dim_type,unit_system) real_normed_vector
+ by (intro_classes; transfer, auto simp add: eq_unit norm_triangle_ineq)
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/ISQ_Units.thy b/thys/Physical_Quantities/ISQ_Units.thy
new file mode 100644
--- /dev/null
+++ b/thys/Physical_Quantities/ISQ_Units.thy
@@ -0,0 +1,27 @@
+section \<open> Units \<close>
+
+theory ISQ_Units
+ imports ISQ_Proof
+begin
+
+text \<open> Parallel to the base quantities, there are base units. In the implementation of
+ the SI unit system, we fix these to be precisely those quantities that have a base dimension
+ and a magnitude of \<^term>\<open>1\<close>. Consequently, a base unit corresponds to a unit in the algebraic
+ sense. \<close>
+
+lift_definition is_base_unit :: "'a::one['d::dim_type, 's::unit_system] \<Rightarrow> bool"
+ is "\<lambda> x. mag x = 1 \<and> is_BaseDim (dim x)" .
+
+definition mk_base_unit :: "'u itself \<Rightarrow> 's itself \<Rightarrow> ('a::one)['u::basedim_type, 's::unit_system]"
+ where "mk_base_unit t s = 1"
+
+syntax "_mk_base_unit" :: "type \<Rightarrow> type \<Rightarrow> logic" ("BUNIT'(_, _')")
+translations "BUNIT('a, 's)" == "CONST mk_base_unit TYPE('a) TYPE('s)"
+
+lemma mk_base_unit: "is_base_unit (mk_base_unit a s)"
+ by (simp add: mk_base_unit_def si_eq, transfer, simp add: is_BaseDim)
+
+lemma magQ_mk [si_eq]: "\<lbrakk>BUNIT('u::basedim_type, 's::unit_system)\<rbrakk>\<^sub>Q = 1"
+ by (simp add: mk_base_unit_def magQ_def si_eq, transfer, simp)
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/Power_int.thy b/thys/Physical_Quantities/Power_int.thy
new file mode 100644
--- /dev/null
+++ b/thys/Physical_Quantities/Power_int.thy
@@ -0,0 +1,47 @@
+section \<open> Integer Powers \<close>
+
+theory Power_int
+ imports "HOL.Real"
+begin
+
+text \<open> The standard HOL power operator is only for natural powers. This operator allows integers. \<close>
+
+definition intpow :: "'a::{linordered_field} \<Rightarrow> int \<Rightarrow> 'a" (infixr "^\<^sub>Z" 80) where
+"intpow x n = (if (n < 0) then inverse (x ^ nat (-n)) else (x ^ nat n))"
+
+lemma intpow_zero [simp]: "x ^\<^sub>Z 0 = 1"
+ by (simp add: intpow_def)
+
+lemma intpow_spos [simp]: "x > 0 \<Longrightarrow> x ^\<^sub>Z n > 0"
+ by (simp add: intpow_def)
+
+lemma intpow_one [simp]: "x ^\<^sub>Z 1 = x"
+ by (simp add: intpow_def)
+
+lemma one_intpow [simp]: "1 ^\<^sub>Z n = 1"
+ by (simp add: intpow_def)
+
+lemma intpow_plus: "x > 0 \<Longrightarrow> x ^\<^sub>Z (m + n) = x ^\<^sub>Z m * x ^\<^sub>Z n"
+ apply (simp add: intpow_def field_simps power_add)
+ apply (metis (no_types, hide_lams) abs_ge_zero add.commute add_diff_cancel_right' nat_add_distrib power_add uminus_add_conv_diff zabs_def)
+ done
+
+lemma intpow_mult_combine: "x > 0 \<Longrightarrow> x ^\<^sub>Z m * (x ^\<^sub>Z n * y) = x ^\<^sub>Z (m + n) * y"
+ by (simp add: intpow_plus)
+
+lemma intpow_pos [simp]: "n \<ge> 0 \<Longrightarrow> x ^\<^sub>Z n = x ^ nat n"
+ by (simp add: intpow_def)
+
+lemma intpow_uminus: "x ^\<^sub>Z -n = inverse (x ^\<^sub>Z n)"
+ by (simp add: intpow_def)
+
+lemma intpow_uminus_nat: "n \<ge> 0 \<Longrightarrow> x ^\<^sub>Z -n = inverse (x ^ nat n)"
+ by (simp add: intpow_def)
+
+lemma intpow_inverse: "inverse a ^\<^sub>Z n = inverse (a ^\<^sub>Z n)"
+ by (simp add: intpow_def power_inverse)
+
+lemma intpow_mult_distrib: "(x * y) ^\<^sub>Z m = x ^\<^sub>Z m * y ^\<^sub>Z m"
+ by (simp add: intpow_def power_mult_distrib)
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/ROOT b/thys/Physical_Quantities/ROOT
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/ROOT
@@ -0,0 +1,78 @@
+(*****************************************************************************
+ *
+ * Project : A Sound Type System for Physical Quantities, Units, and Measurements
+ *
+ * Version : 1.0
+ *
+ * Author : Simon Foster, Burkhart Wolff
+ *
+ * This file : Configuration
+ *
+ * Copyright (c) 2020 University of York, UK, Université Paris-Saclay, France
+ *
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ *
+ * * Neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ******************************************************************************)
+(* $Id:$ *)
+
+chapter AFP
+
+session "Physical_Quantities" (AFP) = "HOL" +
+ description \<open> Physical Quantities, Units, and Measurements \<close>
+ options [timeout = 600]
+ sessions
+ "HOL-Eisbach" "HOL-Decision_Procs"
+ theories
+ Power_int
+ Enum_extra
+ Groups_mult
+ ISQ
+ ISQ_Quantities
+ ISQ_Dimensions
+ CGS
+ ISQ_Algebra
+ ISQ_Proof
+ ISQ_Conversion
+ ISQ_Units
+ SI_Constants
+ SI_Derived
+ SI_Imperial
+ SI_Prefix
+ SI
+ SI_Units
+ SI_Astronomical
+ SI_Accepted
+ SI_Pretty
+ BIS
+
+ document_files
+ "root.tex"
+ "root.bib"
diff --git a/thys/Physical_Quantities/SI.thy b/thys/Physical_Quantities/SI.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/SI.thy
@@ -0,0 +1,5 @@
+section \<open> Meta-Theory for SI Units \<close>
+
+theory SI
+ imports SI_Units SI_Constants SI_Prefix SI_Derived SI_Accepted SI_Imperial
+begin end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/SI_Accepted.thy b/thys/Physical_Quantities/SI_Accepted.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/SI_Accepted.thy
@@ -0,0 +1,36 @@
+section \<open> Non-SI Units Accepted for SI use \<close>
+
+theory SI_Accepted
+ imports SI_Derived
+begin
+
+definition [si_def, si_eq]: "minute = 60 *\<^sub>Q second"
+
+definition [si_def, si_eq]: "hour = 60 *\<^sub>Q minute"
+
+definition [si_def, si_eq]: "day = 24 *\<^sub>Q hour"
+
+definition [si_def, si_eq]: "astronomical_unit = 149597870700 *\<^sub>Q metre"
+
+definition degree :: "'a::real_field[L/L]" where
+[si_def, si_eq]: "degree = (2\<cdot>(of_real pi) / 180) *\<^sub>Q radian"
+
+abbreviation degrees ("_\<degree>" [999] 999) where "n\<degree> \<equiv> n *\<^sub>Q degree"
+
+definition [si_def, si_eq]: "litre = 1/1000 *\<^sub>Q metre\<^sup>\<three>"
+
+definition [si_def, si_eq]: "tonne = 10^3 *\<^sub>Q kilogram"
+
+definition [si_def, si_eq]: "dalton = 1.66053906660 * (1 / 10^27) *\<^sub>Q kilogram"
+
+subsection \<open> Example Unit Equations \<close>
+
+lemma "1 *\<^sub>Q hour = 3600 *\<^sub>Q second"
+ by (si_simp)
+
+lemma "watt \<^bold>\<cdot> hour \<cong>\<^sub>Q 3600 *\<^sub>Q joule" by (si_calc)
+
+lemma "25 *\<^sub>Q metre \<^bold>/ second = 90 *\<^sub>Q (kilo *\<^sub>Q metre) \<^bold>/ hour"
+ by (si_calc)
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/SI_Astronomical.thy b/thys/Physical_Quantities/SI_Astronomical.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/SI_Astronomical.thy
@@ -0,0 +1,45 @@
+section \<open> Astronomical Constants \<close>
+
+theory SI_Astronomical
+ imports SI "HOL-Decision_Procs.Approximation"
+begin
+
+text \<open> We create a number of astronomical constants and prove relationships between some of them.
+ For this, we use the approximation method that can compute bounds on transcendental functions. \<close>
+
+definition julian_year :: "'a::field[T]" where
+[si_eq]: "julian_year = 365.25 *\<^sub>Q day"
+
+definition light_year :: "'a::field_char_0[L]" where
+"light_year = QCOERCE[L] (\<^bold>c \<^bold>\<cdot> julian_year)"
+
+text \<open> We need to apply a coercion in the definition of light year to convert the dimension type
+ from \<^typ>\<open>L \<cdot> T\<^sup>-\<^sup>1 \<cdot> T\<close> to \<^typ>\<open>L\<close>. The correctness of this coercion is confirmed by the following
+ equivalence theorem. \<close>
+
+lemma light_year: "light_year \<cong>\<^sub>Q \<^bold>c \<^bold>\<cdot> julian_year"
+ unfolding light_year_def by (si_calc)
+
+lemma light_year_eq [si_eq]: "\<lbrakk>light_year\<rbrakk>\<^sub>Q = \<lbrakk>\<^bold>c \<^bold>\<cdot> julian_year\<rbrakk>\<^sub>Q"
+ using light_year quant_equiv_iff by blast
+
+text \<open> HOL can characterise \<^const>\<open>pi\<close> exactly and so we also give an exact value for the parsec. \<close>
+
+definition parsec :: "real[L]" where
+[si_eq]: "parsec = 648000 / pi *\<^sub>Q astronomical_unit"
+
+text \<open> We calculate some conservative bounds on the parsec: it is somewhere between 3.26 and 3.27
+ light-years. \<close>
+
+lemma parsec_lb: "3.26 *\<^sub>Q light_year < parsec"
+ by (si_simp, approximation 12)
+
+lemma parsec_ub: "parsec < 3.27 *\<^sub>Q light_year"
+ by (si_simp, approximation 12)
+
+text\<open> The full beauty of the approach is perhaps revealed here, with the
+ type of a classical three-dimensional gravitation field:\<close>
+
+type_synonym gravitation_field = "real\<^sup>3[L] \<Rightarrow> (real\<^sup>3[L \<cdot> T\<^sup>-\<^sup>2])"
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/SI_Constants.thy b/thys/Physical_Quantities/SI_Constants.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/SI_Constants.thy
@@ -0,0 +1,96 @@
+section \<open> Physical Constants \<close>
+
+theory SI_Constants
+ imports SI_Units
+begin
+
+subsection \<open> Core Derived Units \<close>
+
+abbreviation (input) "hertz \<equiv> second\<^sup>-\<^sup>\<one>"
+
+abbreviation "radian \<equiv> metre \<^bold>\<cdot> metre\<^sup>-\<^sup>\<one>"
+
+abbreviation "steradian \<equiv> metre\<^sup>\<two> \<^bold>\<cdot> metre\<^sup>-\<^sup>\<two>"
+
+abbreviation "joule \<equiv> kilogram \<^bold>\<cdot> metre\<^sup>\<two> \<^bold>\<cdot> second\<^sup>-\<^sup>\<two>"
+
+type_synonym 'a joule = "'a[M \<cdot> L\<^sup>2 \<cdot> T\<^sup>-\<^sup>2, SI]"
+
+abbreviation "watt \<equiv> kilogram \<^bold>\<cdot> metre\<^sup>\<two> \<^bold>\<cdot> second\<^sup>-\<^sup>\<three>"
+
+type_synonym 'a watt = "'a[M \<cdot> L\<^sup>2 \<cdot> T\<^sup>-\<^sup>3, SI]"
+
+abbreviation "coulomb \<equiv> ampere \<^bold>\<cdot> second"
+
+type_synonym 'a coulomb = "'a[I \<cdot> T, SI]"
+
+abbreviation "lumen \<equiv> candela \<^bold>\<cdot> steradian"
+
+type_synonym 'a lumen = "'a[J \<cdot> (L\<^sup>2 \<cdot> L\<^sup>-\<^sup>2), SI]"
+
+subsection \<open> Constants \<close>
+
+text \<open> The most general types we support must form a field into which the natural numbers can
+ be injected. \<close>
+
+default_sort field_char_0
+
+text \<open> Hyperfine transition frequency of frequency of Cs \<close>
+
+abbreviation caesium_frequency:: "'a[T\<^sup>-\<^sup>1,SI]" ("\<Delta>v\<^sub>C\<^sub>s") where
+ "caesium_frequency \<equiv> 9192631770 *\<^sub>Q hertz"
+
+text \<open> Speed of light in vacuum \<close>
+
+abbreviation speed_of_light :: "'a[L \<cdot> T\<^sup>-\<^sup>1,SI]" ("\<^bold>c") where
+ "speed_of_light \<equiv> 299792458 *\<^sub>Q (metre\<^bold>\<cdot>second\<^sup>-\<^sup>\<one>)"
+
+text \<open> Planck constant \<close>
+
+abbreviation Planck :: "'a[M \<cdot> L\<^sup>2 \<cdot> T\<^sup>-\<^sup>2 \<cdot> T,SI]" ("\<^bold>h") where
+ "Planck \<equiv> (6.62607015 \<cdot> 1/(10^34)) *\<^sub>Q (joule\<^bold>\<cdot>second)"
+
+text \<open> Elementary charge \<close>
+
+abbreviation elementary_charge :: "'a[I \<cdot> T,SI]" ("\<^bold>e") where
+ "elementary_charge \<equiv> (1.602176634 \<cdot> 1/(10^19)) *\<^sub>Q coulomb"
+
+text \<open> The Boltzmann constant \<close>
+
+abbreviation Boltzmann :: "'a[M \<cdot> L\<^sup>2 \<cdot> T\<^sup>-\<^sup>2 \<cdot> \<Theta>\<^sup>-\<^sup>1,SI]" ("\<^bold>k") where
+ "Boltzmann \<equiv> (1.380649\<cdot>1/(10^23)) *\<^sub>Q (joule \<^bold>/ kelvin)"
+
+text \<open> The Avogadro number \<close>
+
+abbreviation Avogadro :: "'a[N\<^sup>-\<^sup>1,SI]" ("N\<^sub>A") where
+"Avogadro \<equiv> 6.02214076\<cdot>(10^23) *\<^sub>Q (mole\<^sup>-\<^sup>\<one>)"
+
+abbreviation max_luminous_frequency :: "'a[T\<^sup>-\<^sup>1,SI]" where
+"max_luminous_frequency \<equiv> (540\<cdot>10^12) *\<^sub>Q hertz"
+
+text \<open> The luminous efficacy of monochromatic radiation of frequency \<^const>\<open>max_luminous_frequency\<close>. \<close>
+
+abbreviation luminous_efficacy :: "'a[J \<cdot> (L\<^sup>2 \<cdot> L\<^sup>-\<^sup>2) \<cdot> (M \<cdot> L\<^sup>2 \<cdot> T\<^sup>-\<^sup>3)\<^sup>-\<^sup>1,SI]" ("K\<^sub>c\<^sub>d") where
+"luminous_efficacy \<equiv> 683 *\<^sub>Q (lumen\<^bold>/watt)"
+
+subsection \<open> Checking Foundational Equations of the SI System \<close>
+
+theorem second_definition:
+ "1 *\<^sub>Q second \<cong>\<^sub>Q (9192631770 *\<^sub>Q \<one>) \<^bold>/ \<Delta>v\<^sub>C\<^sub>s"
+ by si_calc
+
+theorem metre_definition:
+ "1 *\<^sub>Q metre \<cong>\<^sub>Q (\<^bold>c \<^bold>/ (299792458 *\<^sub>Q \<one>))\<^bold>\<cdot>second"
+ "1 *\<^sub>Q metre \<cong>\<^sub>Q (9192631770 / 299792458) *\<^sub>Q (\<^bold>c \<^bold>/ \<Delta>v\<^sub>C\<^sub>s)"
+ by si_calc+
+
+theorem kilogram_definition:
+ "((1 *\<^sub>Q kilogram)::'a kilogram) \<cong>\<^sub>Q (\<^bold>h \<^bold>/ (6.62607015 \<cdot> 1/(10^34) *\<^sub>Q \<one>))\<^bold>\<cdot>metre\<^sup>-\<^sup>\<two>\<^bold>\<cdot>second"
+ by si_calc
+
+
+abbreviation "approx_ice_point \<equiv> 273.15 *\<^sub>Q kelvin"
+
+default_sort type
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/SI_Derived.thy b/thys/Physical_Quantities/SI_Derived.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/SI_Derived.thy
@@ -0,0 +1,98 @@
+section \<open> Derived SI-Units\<close>
+
+theory SI_Derived
+ imports SI_Prefix
+begin
+
+subsection \<open> Definitions \<close>
+
+abbreviation "newton \<equiv> kilogram \<^bold>\<cdot> metre \<^bold>\<cdot> second\<^sup>-\<^sup>\<two>"
+
+type_synonym 'a newton = "'a[M \<cdot> L \<cdot> T\<^sup>-\<^sup>2, SI]"
+
+abbreviation "pascal \<equiv> kilogram \<^bold>\<cdot> metre\<^sup>-\<^sup>\<one> \<^bold>\<cdot> second\<^sup>-\<^sup>\<two>"
+
+type_synonym 'a pascal = "'a[M \<cdot> L\<^sup>-\<^sup>1 \<cdot> T\<^sup>-\<^sup>2, SI]"
+
+abbreviation "volt \<equiv> kilogram \<^bold>\<cdot> metre\<^sup>\<two> \<^bold>\<cdot> second\<^sup>-\<^sup>\<three> \<^bold>\<cdot> ampere\<^sup>-\<^sup>\<one>"
+
+type_synonym 'a volt = "'a[M \<cdot> L\<^sup>2 \<cdot> T\<^sup>-\<^sup>3 \<cdot> I\<^sup>-\<^sup>1, SI]"
+
+abbreviation "farad \<equiv> kilogram\<^sup>-\<^sup>\<one> \<^bold>\<cdot> metre\<^sup>-\<^sup>\<two> \<^bold>\<cdot> second\<^sup>\<four> \<^bold>\<cdot> ampere\<^sup>\<two>"
+
+type_synonym 'a farad = "'a[M\<^sup>-\<^sup>1 \<cdot> L\<^sup>-\<^sup>2 \<cdot> T\<^sup>4 \<cdot> I\<^sup>2, SI]"
+
+abbreviation "ohm \<equiv> kilogram \<^bold>\<cdot> metre\<^sup>\<two> \<^bold>\<cdot> second\<^sup>-\<^sup>\<three> \<^bold>\<cdot> ampere\<^sup>-\<^sup>\<two>"
+
+type_synonym 'a ohm = "'a[M \<cdot> L\<^sup>2 \<cdot> T\<^sup>-\<^sup>3 \<cdot> I\<^sup>-\<^sup>2, SI]"
+
+abbreviation "siemens \<equiv> kilogram\<^sup>-\<^sup>\<one> \<^bold>\<cdot> metre\<^sup>-\<^sup>\<two> \<^bold>\<cdot> second\<^sup>\<three> \<^bold>\<cdot> ampere\<^sup>\<two>"
+
+abbreviation "weber \<equiv> kilogram \<^bold>\<cdot> metre\<^sup>\<two> \<^bold>\<cdot> second\<^sup>-\<^sup>\<two> \<^bold>\<cdot> ampere\<^sup>-\<^sup>\<one>"
+
+abbreviation "tesla \<equiv> kilogram \<^bold>\<cdot> second\<^sup>-\<^sup>\<two> \<^bold>\<cdot> ampere\<^sup>-\<^sup>\<one>"
+
+abbreviation "henry \<equiv> kilogram \<^bold>\<cdot> metre\<^sup>\<two> \<^bold>\<cdot> second\<^sup>-\<^sup>\<two> \<^bold>\<cdot> ampere\<^sup>-\<^sup>\<two>"
+
+abbreviation "lux \<equiv> candela \<^bold>\<cdot> steradian \<^bold>\<cdot> metre\<^sup>-\<^sup>\<two>"
+
+abbreviation (input) "becquerel \<equiv> second\<^sup>-\<^sup>\<one>"
+
+abbreviation "gray \<equiv> metre\<^sup>\<two> \<^bold>\<cdot> second\<^sup>-\<^sup>\<two>"
+
+abbreviation "sievert \<equiv> metre\<^sup>\<two> \<^bold>\<cdot> second\<^sup>-\<^sup>\<two>"
+
+abbreviation "katal \<equiv> mole \<^bold>\<cdot> second\<^sup>-\<^sup>\<one>"
+
+definition degrees_celcius :: "'a::field_char_0 \<Rightarrow> 'a[\<Theta>]" ("_\<degree>C" [999] 999)
+ where [si_eq]: "degrees_celcius x = (x *\<^sub>Q kelvin) + approx_ice_point"
+
+definition [si_eq]: "gram = milli *\<^sub>Q kilogram"
+
+subsection \<open> Equivalences \<close>
+
+lemma joule_alt_def: "joule \<cong>\<^sub>Q newton \<^bold>\<cdot> metre"
+ by si_calc
+
+lemma watt_alt_def: "watt \<cong>\<^sub>Q joule \<^bold>/ second"
+ by si_calc
+
+lemma volt_alt_def: "volt = watt \<^bold>/ ampere"
+ by simp
+
+lemma farad_alt_def: "farad \<cong>\<^sub>Q coulomb \<^bold>/ volt"
+ by si_calc
+
+lemma ohm_alt_def: "ohm \<cong>\<^sub>Q volt \<^bold>/ ampere"
+ by si_calc
+
+lemma siemens_alt_def: "siemens \<cong>\<^sub>Q ampere \<^bold>/ volt"
+ by si_calc
+
+lemma weber_alt_def: "weber \<cong>\<^sub>Q volt \<^bold>\<cdot> second"
+ by si_calc
+
+lemma tesla_alt_def: "tesla \<cong>\<^sub>Q weber \<^bold>/ metre\<^sup>\<two>"
+ by si_calc
+
+lemma henry_alt_def: "henry \<cong>\<^sub>Q weber \<^bold>/ ampere"
+ by si_calc
+
+lemma lux_alt_def: "lux = lumen \<^bold>/ metre\<^sup>\<two>"
+ by simp
+
+lemma gray_alt_def: "gray \<cong>\<^sub>Q joule \<^bold>/ kilogram"
+ by si_calc
+
+lemma sievert_alt_def: "sievert \<cong>\<^sub>Q joule \<^bold>/ kilogram"
+ by si_calc
+
+subsection \<open> Properties \<close>
+
+lemma kilogram: "kilo *\<^sub>Q gram = kilogram"
+ by (si_simp)
+
+lemma celcius_to_kelvin: "T\<degree>C = (T *\<^sub>Q kelvin) + (273.15 *\<^sub>Q kelvin)"
+ by (si_simp)
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/SI_Imperial.thy b/thys/Physical_Quantities/SI_Imperial.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/SI_Imperial.thy
@@ -0,0 +1,77 @@
+section \<open> Imperial Units via SI Units \<close>
+
+theory SI_Imperial
+ imports SI_Accepted
+begin
+
+subsection \<open> Units of Length \<close>
+
+default_sort field_char_0
+
+text \<open> The units of length are defined in terms of the international yard, as standardised in 1959. \<close>
+
+definition yard :: "'a[L]" where
+[si_eq]: "yard = 0.9144 *\<^sub>Q metre"
+
+definition foot :: "'a[L]" where
+[si_eq]: "foot = 1/3 *\<^sub>Q yard"
+
+lemma foot_alt_def: "foot = 0.3048 *\<^sub>Q metre"
+ by (si_simp)
+
+definition inch :: "'a[L]" where
+[si_eq]: "inch = (1 / 36) *\<^sub>Q yard"
+
+lemma inch_alt_def: "inch = 25.4 *\<^sub>Q milli *\<^sub>Q metre"
+ by (si_simp)
+
+definition mile :: "'a[L]" where
+[si_eq]: "mile = 1760 *\<^sub>Q yard"
+
+lemma mile_alt_def: "mile = 1609.344 *\<^sub>Q metre"
+ by (si_simp)
+
+definition nautical_mile :: "'a[L]" where
+[si_eq]: "nautical_mile = 1852 *\<^sub>Q metre"
+
+subsection \<open> Units of Mass \<close>
+
+text \<open> The units of mass are defined in terms of the international yard, as standardised in 1959. \<close>
+
+definition pound :: "'a[M]" where
+[si_eq]: "pound = 0.45359237 *\<^sub>Q kilogram"
+
+definition ounce :: "'a[M]" where
+[si_eq]: "ounce = 1/16 *\<^sub>Q pound"
+
+definition stone :: "'a[M]" where
+[si_eq]: "stone = 14 *\<^sub>Q pound"
+
+subsection \<open> Other Units \<close>
+
+definition knot :: "'a[L \<cdot> T\<^sup>-\<^sup>1]" where
+[si_eq]: "knot = 1 *\<^sub>Q (nautical_mile \<^bold>/ hour)"
+
+definition pint :: "'a[Volume]" where
+[si_eq]: "pint = 0.56826125 *\<^sub>Q litre"
+
+definition gallon :: "'a[Volume]" where
+[si_eq]: "gallon = 8 *\<^sub>Q pint"
+
+definition degrees_farenheit :: "'a \<Rightarrow> 'a[\<Theta>]" ("_\<degree>F" [999] 999)
+ where [si_eq]: "degrees_farenheit x = (x + 459.67)\<cdot>5/9 *\<^sub>Q kelvin"
+
+default_sort type
+
+subsection \<open> Unit Equations \<close>
+
+lemma miles_to_feet: "mile = 5280 *\<^sub>Q foot"
+ by si_simp
+
+lemma mph_to_kmh: "1 *\<^sub>Q (mile \<^bold>/ hour) = 1.609344 *\<^sub>Q ((kilo *\<^sub>Q metre) \<^bold>/ hour)"
+ by si_simp
+
+lemma farenheit_to_celcius: "T\<degree>F = ((T - 32) \<cdot> 5/9)\<degree>C"
+ by si_simp
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/SI_Prefix.thy b/thys/Physical_Quantities/SI_Prefix.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/SI_Prefix.thy
@@ -0,0 +1,89 @@
+section \<open> SI Prefixes \<close>
+
+theory SI_Prefix
+ imports SI_Constants
+begin
+
+subsection \<open> Definitions \<close>
+
+text \<open> Prefixes are simply numbers that can be composed with units using the scalar
+ multiplication operator \<^const>\<open>scaleQ\<close>. \<close>
+
+default_sort ring_char_0
+
+definition deca :: "'a" where [si_eq]: "deca = 10^1"
+
+definition hecto :: "'a" where [si_eq]: "hecto = 10^2"
+
+definition kilo :: "'a" where [si_eq]: "kilo = 10^3"
+
+definition mega :: "'a" where [si_eq]: "mega = 10^6"
+
+definition giga :: "'a" where [si_eq]: "giga = 10^9"
+
+definition tera :: "'a" where [si_eq]: "tera = 10^12"
+
+definition peta :: "'a" where [si_eq]: "peta = 10^15"
+
+definition exa :: "'a" where [si_eq]: "exa = 10^18"
+
+definition zetta :: "'a" where [si_eq]: "zetta = 10^21"
+
+definition yotta :: "'a" where [si_eq]: "yotta = 10^24"
+
+default_sort field_char_0
+
+definition deci :: "'a" where [si_eq]: "deci = 1/10^1"
+
+definition centi :: "'a" where [si_eq]: "centi = 1/10^2"
+
+definition milli :: "'a" where [si_eq]: "milli = 1/10^3"
+
+definition micro :: "'a" where [si_eq]: "micro = 1/10^6"
+
+definition nano :: "'a" where [si_eq]: "nano = 1/10^9"
+
+definition pico :: "'a" where [si_eq]: "pico = 1/10^12"
+
+definition femto :: "'a" where [si_eq]: "femto = 1/10^15"
+
+definition atto :: "'a" where [si_eq]: "atto = 1/10^18"
+
+definition zepto :: "'a" where [si_eq]: "zepto = 1/10^21"
+
+definition yocto :: "'a" where [si_eq]: "yocto = 1/10^24"
+
+subsection \<open> Examples \<close>
+
+lemma "2.3 *\<^sub>Q (centi *\<^sub>Q metre)\<^sup>\<three> = 2.3 \<cdot> 1/10^6 *\<^sub>Q metre\<^sup>\<three>"
+ by (si_simp)
+
+lemma "1 *\<^sub>Q (centi *\<^sub>Q metre)\<^sup>-\<^sup>\<one> = 100 *\<^sub>Q metre\<^sup>-\<^sup>\<one>"
+ by (si_simp)
+
+subsection \<open> Binary Prefixes \<close>
+
+text \<open> Although not in general applicable to physical quantities, we include these prefixes
+ for completeness. \<close>
+
+default_sort ring_char_0
+
+definition kibi :: "'a" where [si_eq]: "kibi = 2^10"
+
+definition mebi :: "'a" where [si_eq]: "mebi = 2^20"
+
+definition gibi :: "'a" where [si_eq]: "gibi = 2^30"
+
+definition tebi :: "'a" where [si_eq]: "tebi = 2^40"
+
+definition pebi :: "'a" where [si_eq]: "pebi = 2^50"
+
+definition exbi :: "'a" where [si_eq]: "exbi = 2^60"
+
+definition zebi :: "'a" where [si_eq]: "zebi = 2^70"
+
+definition yobi :: "'a" where [si_eq]: "yobi = 2^80"
+
+default_sort type
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/SI_Pretty.thy b/thys/Physical_Quantities/SI_Pretty.thy
new file mode 100644
--- /dev/null
+++ b/thys/Physical_Quantities/SI_Pretty.thy
@@ -0,0 +1,121 @@
+section \<open> Parsing and Pretty Printing of SI Units \<close>
+
+theory SI_Pretty
+ imports SI
+begin
+
+subsection \<open> Syntactic SI Units \<close>
+
+text \<open> The following syntactic representation can apply at both the type and value level. \<close>
+
+nonterminal si
+
+syntax
+ "_si_metre" :: "si" ("m")
+ "_si_kilogram" :: "si" ("kg")
+ "_si_second" :: "si" ("s")
+ "_si_ampere" :: "si" ("A")
+ "_si_kelvin" :: "si" ("K")
+ "_si_mole" :: "si" ("mol")
+ "_si_candela" :: "si" ("cd")
+
+ "_si_square" :: "si \<Rightarrow> si" ("(_)\<^sup>2" [999] 999)
+ "_si_cube" :: "si \<Rightarrow> si" ("(_)\<^sup>3" [999] 999)
+ "_si_quart" :: "si \<Rightarrow> si" ("(_)\<^sup>4" [999] 999)
+
+ "_si_inverse" :: "si \<Rightarrow> si" ("(_\<^sup>-\<^sup>1)" [999] 999)
+ "_si_invsquare" :: "si \<Rightarrow> si" ("(_)\<^sup>-\<^sup>2" [999] 999)
+ "_si_invcube" :: "si \<Rightarrow> si" ("(_)\<^sup>-\<^sup>3" [999] 999)
+ "_si_invquart" :: "si \<Rightarrow> si" ("(_)\<^sup>-\<^sup>4" [999] 999)
+
+ "_si_times" :: "si \<Rightarrow> si \<Rightarrow> si" (infixl "\<cdot>" 70)
+
+subsection \<open> Type Notation \<close>
+
+text \<open> Pretty notation for SI units at the type level. \<close>
+
+no_type_notation SIUnitT ("_[_]" [999,0] 999)
+
+syntax
+ "_si_unit" :: "type \<Rightarrow> si \<Rightarrow> type" ("_[_]" [999,0] 999)
+ "_si_print" :: "type \<Rightarrow> si" ("SIPRINT'(_')")
+
+translations
+ (type) "'a[SIPRINT('d)]" == (type) "'a['d, SI]"
+ (si) "SIPRINT('d)\<^sup>2" == (si) "SIPRINT('d\<^sup>2)"
+ (si) "SIPRINT('d)\<^sup>3" == (si) "SIPRINT('d\<^sup>3)"
+ (si) "SIPRINT('d)\<^sup>4" == (si) "SIPRINT('d\<^sup>4)"
+ (si) "SIPRINT('d)\<^sup>-\<^sup>1" == (si) "SIPRINT('d\<^sup>-\<^sup>1)"
+ (si) "SIPRINT('d)\<^sup>-\<^sup>2" == (si) "SIPRINT('d\<^sup>-\<^sup>2)"
+ (si) "SIPRINT('d)\<^sup>-\<^sup>3" == (si) "SIPRINT('d\<^sup>-\<^sup>3)"
+ (si) "SIPRINT('d)\<^sup>-\<^sup>4" == (si) "SIPRINT('d\<^sup>-\<^sup>4)"
+ (si) "SIPRINT('d\<^sub>1) \<cdot> SIPRINT('d\<^sub>2)" == (si) "SIPRINT('d\<^sub>1 \<cdot> 'd\<^sub>2)"
+ (si) "m" == (si) "SIPRINT(L)"
+ (si) "kg" == (si) "SIPRINT(M)"
+ (si) "s" == (si) "SIPRINT(T)"
+ (si) "A" == (si) "SIPRINT(I)"
+ (si) "K" == (si) "SIPRINT(\<Theta>)"
+ (si) "mol" == (si) "SIPRINT(N)"
+ (si) "cd" == (si) "SIPRINT(J)"
+
+ "_si_invsquare x" <= "_si_inverse (_si_square x)"
+ "_si_invcube x" <= "_si_inverse (_si_cube x)"
+ "_si_invquart x" <= "_si_inverse (_si_quart x)"
+
+ "_si_invsquare x" <= "_si_square (_si_inverse x)"
+ "_si_invcube x" <= "_si_cube (_si_inverse x)"
+ "_si_invquart x" <= "_si_quart (_si_inverse x)"
+
+typ "real[m\<cdot>s\<^sup>-\<^sup>2]"
+typ "real[m\<cdot>s\<^sup>-\<^sup>2\<cdot>A\<^sup>2]"
+term "5 *\<^sub>Q joule"
+
+subsection \<open> Value Notations \<close>
+
+text \<open> Pretty notation for SI units at the type level. Currently, it is not possible to support
+ prefixes, as this would require a more sophisticated cartouche parser. \<close>
+
+definition "SIQ n u = n *\<^sub>Q u"
+
+syntax
+ "_si_term" :: "si \<Rightarrow> logic" ("SI'(_')")
+ "_siq_term" :: "logic \<Rightarrow> si \<Rightarrow> logic" ("SI[_, _]")
+ "_siq_print" :: "logic \<Rightarrow> si"
+
+translations
+ "_siq_term n u" => "CONST SIQ n (_si_term u)"
+ "_siq_term n (_siq_print u)" <= "CONST SIQ n u"
+ "_si_term (_si_times x y)" == "(_si_term x) \<^bold>\<cdot> (_si_term y)"
+ "_si_term (_si_inverse x)" == "(_si_term x)\<^sup>-\<^sup>\<one>"
+ "_si_term (_si_square x)" == "(_si_term x)\<^sup>\<two>"
+ "_si_term (_si_cube x)" == "(_si_term x)\<^sup>\<two>"
+ "SI(m)" => "CONST metre"
+ "SI(kg)" => "CONST kilogram"
+ "SI(s)" => "CONST second"
+ "SI(A)" => "CONST ampere"
+ "SI(K)" => "CONST kelvin"
+ "SI(mol)" => "CONST mole"
+ "SI(cd)" => "CONST candela"
+
+ "_si_inverse (_siq_print x)" <= "_siq_print (x\<^sup>-\<^sup>\<one>)"
+ "_si_invsquare (_siq_print x)" <= "_siq_print (x\<^sup>-\<^sup>\<two>)"
+ "_si_invcube (_siq_print x)" <= "_siq_print (x\<^sup>-\<^sup>\<three>)"
+ "_si_invquart (_siq_print x)" <= "_siq_print (x\<^sup>-\<^sup>\<four>)"
+
+ "_si_square (_siq_print x)" <= "_siq_print (x\<^sup>\<two>)"
+ "_si_cube (_siq_print x)" <= "_siq_print (x\<^sup>\<three>)"
+ "_si_quart (_siq_print x)" <= "_siq_print (x\<^sup>\<four>)"
+ "_si_times (_siq_print x) (_siq_print y)" <= "_siq_print (x \<^bold>\<cdot> y)"
+
+ "_si_metre" <= "_siq_print (CONST metre)"
+ "_si_kilogram" <= "_siq_print (CONST kilogram)"
+ "_si_second" <= "_siq_print (CONST second)"
+ "_si_ampere" <= "_siq_print (CONST ampere)"
+ "_si_kelvin" <= "_siq_print (CONST kelvin)"
+ "_si_mole" <= "_siq_print (CONST mole)"
+ "_si_candela" <= "_siq_print (CONST candela)"
+
+term "SI[5, m\<^sup>2]"
+term "SI[22, m\<cdot>s\<^sup>-\<^sup>1]"
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/SI_Units.thy b/thys/Physical_Quantities/SI_Units.thy
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/SI_Units.thy
@@ -0,0 +1,109 @@
+chapter \<open> International System of Units \<close>
+
+section \<open> SI Units Semantics \<close>
+
+theory SI_Units
+ imports ISQ
+begin
+
+text \<open> An SI unit is simply a particular kind of quantity with an SI tag. \<close>
+
+typedef SI = "UNIV :: unit set" by simp
+
+instance SI :: unit_system
+ by (rule unit_system_intro[of "Abs_SI ()"], metis (full_types) Abs_SI_cases UNIV_eq_I insert_iff old.unit.exhaust)
+
+abbreviation "SI \<equiv> unit :: SI"
+
+type_synonym ('n, 'd) SIUnitT = "('n, 'd, SI) QuantT" ("_[_]" [999,0] 999)
+
+text \<open> We now define the seven base units. Effectively, these definitions axiomatise given names
+ for the \<^term>\<open>1\<close> elements of the base quantities. \<close>
+
+abbreviation "metre \<equiv> BUNIT(L, SI)"
+abbreviation "kilogram \<equiv> BUNIT(M, SI)"
+abbreviation "ampere \<equiv> BUNIT(I, SI)"
+abbreviation "kelvin \<equiv> BUNIT(\<Theta>, SI)"
+abbreviation "mole \<equiv> BUNIT(N, SI)"
+abbreviation "candela \<equiv> BUNIT(J, SI)"
+
+text \<open> The second is commonly used in unit systems other than SI. Consequently, we define it
+ polymorphically, and require that the system type instantiate a type class to use it. \<close>
+
+class time_second = unit_system
+
+instance SI :: time_second ..
+
+abbreviation "second \<equiv> BUNIT(T, 'a::time_second)"
+
+text \<open>Note that as a consequence of our construction, the term \<^term>\<open>metre\<close> is a SI Unit constant of
+SI-type \<^typ>\<open>'a[L, SI]\<close>, so a unit of dimension \<^typ>\<open>Length\<close> with the magnitude of type \<^typ>\<open>'a\<close>.
+A magnitude instantiation can be, e.g., an integer, a rational number, a real number, or a vector of
+type \<^typ>\<open>real\<^sup>3\<close>. Note than when considering vectors, dimensions refer to the \<^emph>\<open>norm\<close> of the vector,
+not to its components. \<close>
+
+lemma BaseUnits:
+ "is_base_unit metre" "is_base_unit second" "is_base_unit kilogram" "is_base_unit ampere"
+ "is_base_unit kelvin" "is_base_unit mole" "is_base_unit candela"
+ by (simp_all add: mk_base_unit)
+
+text \<open> The effect of the above encoding is that we can use the SI base units as synonyms for their
+ corresponding dimensions at the type level. \<close>
+
+type_synonym 'a metre = "'a[Length, SI]"
+type_synonym 'a second = "'a[Time, SI]"
+type_synonym 'a kilogram = "'a[Mass, SI]"
+type_synonym 'a ampere = "'a[Current, SI]"
+type_synonym 'a kelvin = "'a[Temperature, SI]"
+type_synonym 'a mole = "'a[Amount, SI]"
+type_synonym 'a candela = "'a[Intensity, SI]"
+
+text \<open> We can therefore construct a quantity such as \<^term>\<open>5 :: rat metre\<close>, which unambiguously
+ identifies that the unit of $5$ is metres using the type system. This works because each base
+ unit it the one element. \<close>
+
+subsection \<open> Example Unit Equations \<close>
+
+lemma "(metre \<^bold>\<cdot> second\<^sup>-\<^sup>\<one>) \<^bold>\<cdot> second \<cong>\<^sub>Q metre"
+ by (si_calc)
+
+subsection \<open> Metrification \<close>
+
+class metrifiable = unit_system +
+ fixes convschema :: "'a itself \<Rightarrow> ('a, SI) Conversion" ("schema\<^sub>C")
+
+instantiation SI :: metrifiable
+begin
+lift_definition convschema_SI :: "SI itself \<Rightarrow> (SI, SI) Conversion"
+is "\<lambda> s.
+ \<lparr> cLengthF = 1
+ , cMassF = 1
+ , cTimeF = 1
+ , cCurrentF = 1
+ , cTemperatureF = 1
+ , cAmountF = 1
+ , cIntensityF = 1 \<rparr>" by simp
+instance ..
+end
+
+abbreviation metrify :: "('a::field_char_0)['d::dim_type, 's::metrifiable] \<Rightarrow> 'a['d::dim_type, SI]" where
+"metrify \<equiv> qconv (convschema (TYPE('s)))"
+
+text \<open> Conversion via SI units \<close>
+
+abbreviation qmconv ::
+ "'s\<^sub>1 itself \<Rightarrow> 's\<^sub>2 itself
+ \<Rightarrow> ('a::field_char_0)['d::dim_type, 's\<^sub>1::metrifiable]
+ \<Rightarrow> 'a['d::dim_type, 's\<^sub>2::metrifiable]" where
+"qmconv s\<^sub>1 s\<^sub>2 x \<equiv> qconv (inv\<^sub>C (schema\<^sub>C s\<^sub>2) \<circ>\<^sub>C schema\<^sub>C s\<^sub>1) x"
+
+syntax
+ "_qmconv" :: "type \<Rightarrow> type \<Rightarrow> logic" ("QMC'(_ \<rightarrow> _')")
+
+translations
+ "QMC('s\<^sub>1 \<rightarrow> 's\<^sub>2)" == "CONST qmconv TYPE('s\<^sub>1) TYPE('s\<^sub>2)"
+
+lemma qmconv_self: "QMC('s::metrifiable \<rightarrow> 's) = id"
+ by (simp add: fun_eq_iff)
+
+end
\ No newline at end of file
diff --git a/thys/Physical_Quantities/document/adb-long.bib b/thys/Physical_Quantities/document/adb-long.bib
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/document/adb-long.bib
@@ -0,0 +1,80 @@
+% $Id: adb-long.bib 6518 2010-01-24 14:18:10Z brucker $
+@PREAMBLE{ {\providecommand{\ac}[1]{\textsc{#1}} }
+ # {\providecommand{\acs}[1]{\textsc{#1}} }
+ # {\providecommand{\acf}[1]{\textsc{#1}} }
+ # {\providecommand{\TAP}{T\kern-.1em\lower-.5ex\hbox{A}\kern-.1em P} }
+ # {\providecommand{\leanTAP}{\mbox{\sf lean\it\TAP}} }
+ # {\providecommand{\holz}{\textsc{hol-z}} }
+ # {\providecommand{\holocl}{\textsc{hol-ocl}} }
+ # {\providecommand{\isbn}{\textsc{isbn}} }
+ # {\providecommand{\Cpp}{C++} }
+ # {\providecommand{\Specsharp}{Spec\#} }
+ # {\providecommand{\doi}[1]{\href{http://dx.doi.org/#1}{doi:
+ {\urlstyle{rm}\nolinkurl{#1}}}}} }
+@STRING{conf-tphols="\acs{tphols}" }
+@STRING{iso = {International Organization for Standardization} }
+@STRING{j-ar = "Journal of Automated Reasoning" }
+@STRING{j-cacm = "Communications of the \acs{acm}" }
+@STRING{j-acta-informatica = "Acta Informatica" }
+@STRING{j-sosym = "Software and Systems Modeling" }
+@STRING{j-sttt = "International Journal on Software Tools for Technology" }
+@STRING{j-ist = "Information and Software Technology" }
+@STRING{j-toplas= "\acs{acm} Transactions on Programming Languages and
+ Systems" }
+@STRING{j-tosem = "\acs{acm} Transactions on Software Engineering and
+ Methodology" }
+@STRING{j-eceasst="Electronic Communications of the \acs{easst}" }
+@STRING{j-fac = "Formal Aspects of Computing" }
+@STRING{j-ucs = "Journal of Universal Computer Science" }
+@STRING{j-sl = "Journal of Symbolic Logic" }
+@STRING{j-fp = "Journal of Functional Programming" }
+@STRING{j-tkde = {\acs{ieee} Transaction on Knowledge and Data Engineering} }
+@STRING{j-tse = {\acs{ieee} Transaction on Software Engineering} }
+@STRING{j-entcs = {Electronic Notes in Theoretical Computer Science} }
+@STRING{s-lnai = "Lecture Notes in Computer Science" }
+@STRING{s-lncs = "Lecture Notes in Computer Science" }
+@STRING{s-lnbip = "Lecture Notes in Business Information Processing" }
+@String{j-computer = "Computer"}
+@String{j-tissec = "\acs{acm} Transactions on Information and System Security"}
+@STRING{omg = {Object Management Group} }
+@STRING{j-ipl = {Information Processing Letters} }
+@STRING{j-login = ";login: the USENIX Association newsletter" }
+
+@STRING{PROC = "Proceedings of the " }
+
+
+% Publisher:
+% ==========
+@STRING{pub-awl = {Addison-Wesley Longman, Inc.} }
+@STRING{pub-awl:adr={Reading, MA, \acs{usa}} }
+@STRING{pub-springer={Springer-Verlag} }
+@STRING{pub-springer:adr={Heidelberg} }
+@STRING{pub-cup = {Cambridge University Press} }
+@STRING{pub-cup:adr={New York, \acs{ny}, \acs{usa}} }
+@STRING{pub-mit = {\acs{mit} Press} }
+@STRING{pub-mit:adr={Cambridge, Massachusetts} }
+@STRING{pub-springer-ny={Springer-Verlag} }
+,
+@STRING{pub-springer-netherlands={Springer Netherlands} }
+@STRING{pub-springer-netherlands:adr={} }
+@STRING{pub-springer-ny:adr={New York, \acs{ny}, \acs{usa}} }
+@STRING{pub-springer-london={Springer-Verlag} }
+@STRING{pub-springer-london:adr={London} }
+@STRING{pub-ieee= {\acs{ieee} Computer Society} }
+@STRING{pub-ieee:adr={Los Alamitos, \acs{ca}, \acs{usa}} }
+@STRING{pub-prentice={Prentice Hall, Inc.} }
+@STRING{pub-prentice:adr={Upper Saddle River, \acs{nj}, \acs{usa}} }
+@STRING{pub-acm = {\acs{acm} Press} }
+@STRING{pub-acm:adr={New York, \acs{ny} \acs{usa}} }
+@STRING{pub-oxford={Oxford University Press, Inc.} }
+@STRING{pub-oxford:adr={New York, \acs{ny}, \acs{usa}} }
+@STRING{pub-kluwer={Kluwer Academic Publishers} }
+@STRING{pub-kluwer:adr={Dordrecht} }
+@STRING{pub-elsevier={Elsevier Science Publishers} }
+@STRING{pub-elsevier:adr={Amsterdam} }
+@STRING{pub-north={North-Holland Publishing Co.} }
+@STRING{pub-north:adr={Nijmegen, The Netherlands} }
+@STRING{pub-ios = {\textsc{ios} Press} }
+@STRING{pub-ios:adr={Amsterdam, The Netherlands} }
+@STRING{pub-heise={Heise Zeitschriften Verlag} }
+@STRING{pub-heise:adr={Hannover, Germany} }
diff --git a/thys/Physical_Quantities/document/root.bib b/thys/Physical_Quantities/document/root.bib
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/document/root.bib
@@ -0,0 +1,11074 @@
+
+% $Id: fmde.bib 6539 2010-01-29 10:33:20Z brucker $
+@InProceedings{ zhang.ea:dynamic:2003,
+ author = {Guangsen Zhang and Manish Parashar},
+ title = {Dynamic Context-aware Access Control for Grid Applications},
+ booktitle = {GRID '03: Proceedings of the Fourth Internapv tional Workshop
+ on Grid Computing},
+ year = 2003,
+ pages = 101,
+ address = {Washington, DC, USA},
+ publisher = pub-ieee,
+ isbn = {0-7695-2026-X},
+ tags = {ReadingList, SoKNOS, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ thomas:role-based:1996,
+ author = {Roshan Thomas},
+ title = {Role-based access control and distributed object-based
+ enterprise computing},
+ booktitle = {RBAC '95: Proceedings of the first ACM Workshop on
+ Role-based access control},
+ year = 1996,
+ pages = 21,
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ isbn = {0-89791-759-6},
+ location = {Gaithersburg, Maryland, United States},
+ doi = {10.1145/270152.270194},
+ tags = {ReadingList, SoKNOS, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Article{ harrison.ea:protection:1976,
+ author = {Michael A. Harrison and Walter L. Ruzzo and Jeffrey D.
+ Ullman},
+ title = {Protection in operating systems},
+ journal = j-cacm,
+ year = 1976,
+ volume = 19,
+ number = 8,
+ pages = {461--471},
+ issn = {0001-0782},
+ doi = {10.1145/360303.360333},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ tags = {ReadingList, SoKNOS, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ hafner.ea:modeling:2007,
+ author = {Michael Hafner and Mukhtiar Memon and Muhammad Alam},
+ title = {Modeling and Enforcing Advanced Access Control Policies in
+ Healthcare Systems with \textsc{Sectet}},
+ booktitle = {MoDELS Workshops},
+ year = 2007,
+ pages = {132--144},
+ doi = {10.1007/978-3-540-69073-3_15},
+ crossref = {giese:models:2007}
+}
+
+@Proceedings{ giese:models:2007,
+ editor = {Holger Giese},
+ title = {Models in Software Engineering, Workshops and Symposia at
+ MoDELS 2007, Nashville, TN, USA, September 30 - October 5,
+ 2007, Reports and Revised Selected Papers},
+ booktitle = {MoDELS Workshops},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 5002,
+ year = 2008,
+ isbn = {978-3-540-69069-6}
+}
+
+@InProceedings{ hu.ea:dynamic:2004,
+ author = {Junzhe Hu and Alfred C. Weaver},
+ title = {Dynamic, Context-Aware Access Control for Distributed
+ Healthcare Applications},
+ booktitle = PROC # { the First Workshop on Pervasive Security,
+ Privacy and Trust (\acs{pspt})},
+ year = 2004,
+ tags = {SoKNOS, AccessControl},
+ abstract = {The rapid worldwide deployment of the Internet and Web is
+ the enabler of a new generation of e-healthcare
+ applications, but the provision of a security architecture
+ that can ensure the privacy and security of sensitive
+ healthcare data is still an open question. Current
+ solutions to this problem (mostly built on static RBAC
+ models) are application-dependent and do not address the
+ intricate security requirements of healthcare applications.
+ The healthcare industry requires flexible, on-demand
+ authentication, extensible context-aware access control,
+ and dynamic authorization enforcement. With on-demand
+ authentication, users are authenticated according to their
+ task-specific situations. Extensible context-aware access
+ control enables administrators to specify more precise and
+ fine-grain authorization polices for any application.
+ Dynamic authorization enforcement makes authorization
+ decisions based upon runtime parameters rather than simply
+ the role of the user. In this paper we describe a dynamic,
+ context-aware security infrastructure that can fulfill the
+ security requirements of healthcare applications and that
+ can also be easily adapted to offer security support for
+ similar enterprise applications.},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@TechReport{ spc:break-glass:2004,
+ title = {Break-Glass: An Approach to Granting Emergency Access to
+ Healthcare Systems},
+ year = 2004,
+ abstract = {This white paper discusses a simple yet effective
+ emergency-access solution, sometimes called
+ ``break-glass.'' The purpose of break-glass is to allow
+ operators emergency access to the system in cases where the
+ normal authentication cannot be successfully completed or
+ is not working properly. The systems include medical data
+ acquisition devices as well as information systems which
+ are collectively referred to as Medical Information Systems
+ (MedIS).},
+ institution = {Joint \acs{nema}/\acs{cocir}/\acs{jira} Security and
+ Privacy Committee (\acs{spc})},
+ type = {White paper},
+ tags = {ReadingList, SoKNOS, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ ferreira.ea:how:2006,
+ author = {A. Ferreira and R. Cruz-Correia and L. Antunes and P.
+ Farinha and E. Oliveira-Palhares and D.W. Chadwick and A.
+ Costa-Pereira},
+ title = {How to Break Access Control in a Controlled Manner},
+ booktitle = PROC # {\acs{ieee} International Symposium
+ on Computer-Based Medical Systems (\acs{cbms})},
+ year = 2006,
+ pages = {847--854},
+ abstract = {The electronic medical record (EMR) integrates
+ heterogeneous information within a healthcare institution
+ stressing the need for security and access control. The
+ Biostatistics and Medical Informatics Department from Porto
+ Faculty of Melsdicine has recently implemented a virtual
+ EMR (VEMR) in order to integrate patient information and
+ clinical reports within a university hospital. With more
+ than 500 medical doctors using the system on a daily basis,
+ an access control policy and model were implemented.
+ However, the healthcare environment has unanticipated
+ situations (i.e. emergency situations) where access to
+ information is essential. Most traditional policies do not
+ allow for overriding. A policy that allows for
+ "Break-The-Glass (BTG)" was implemented in order to
+ override access control whilst providing for
+ non-repudiation mechanisms for its usage. The policy was
+ easily integrated within the model confirming its
+ modularity and the fact that user intervention in defining
+ security procedures is crucial to its successful
+ implementation and use},
+ keywords = {access control, medical administrative data processing,
+ security of dataaccess control, clinical reports,
+ electronic medical record, healthcare institution, patient
+ information, university hospital},
+ doi = {10.1109/CBMS.2006.95},
+ issn = {1063-7125},
+ tags = {ReadingList, SoKNOS, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Article{ basin.ea:model:2006,
+ author = {David A. Basin and J\"{u}rgen Doser and Torsten
+ Lodderstedt},
+ title = {Model driven security: From {UML} models to access control
+ infrastructures},
+ journal = j-tosem,
+ year = 2006,
+ volume = 15,
+ number = 1,
+ pages = {39--91},
+ issn = {1049-331X},
+ doi = {10.1145/1125808.1125810},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ tags = {ReadingList, SoKNOS, AccessControl, SecureUML, MDS},
+ clearance = {unclassified},
+ abstract = {We present a new approach to building secure systems. In
+ our approach, which we call Model Driven Security,
+ designers specify system models along with their security
+ requirements and use tools to automatically generate system
+ architectures from the models including complete,
+ configured access control infrastructures. Rather than
+ fixing one particular modeling language for this process,
+ we propose a general schema for constructing such languages
+ that combines languages for modeling systems with languages
+ for modeling security. We present several instances of this
+ schema thatcombine (both syntactically and semantically)
+ different UML modeling languages with a security modeling
+ language for formalizing access control requirements. From
+ models in the combined languages, we automatically generate
+ access control infrastructures for server-based
+ applications, built from declarative and programmatic
+ access control mechanisms. The modeling languages and
+ generation process are semantically well-founded and are
+ based on an extension of Role-Based Access Control. We have
+ implemented this approach ina UML-based CASE-tool and
+ report on experiments.},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ schaad.ea:role-based:2001,
+ author = {Andreas Schaad and Jonathan Moffett and Jeremy Jacob},
+ title = {The role-based access control system of a European bank: a
+ case study and discussion},
+ booktitle = PROC # { the sixth \acs{acm} symposium on Access
+ control models and technologies (\acs{sacmat})},
+ year = 2001,
+ pages = {3--9},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ isbn = {1-58113-350-2},
+ location = {Chantilly, Virginia, United States},
+ doi = {10.1145/373256.373257},
+ tags = {ReadingList, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ beznosov:requirements:1998,
+ author = {Konstantin Beznosov},
+ title = {Requirements for access control: \acs{us} Healthcare
+ domain},
+ booktitle = PROC # { the third \acs{acm} workshop on Role-based
+ access control (\acs{rbac})},
+ year = 1998,
+ pages = 43,
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ isbn = {1-58113-113-5},
+ location = {Fairfax, Virginia, United States},
+ doi = {10.1145/286884.286892},
+ tags = {ReadingList, SoKNOS, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ etalle.ea:posteriori:2007,
+ author = {Sandro Etalle and William H. Winsborough},
+ title = {A posteriori compliance control},
+ booktitle = PROC # { the 12th \acs{acm} symposium on Access
+ control models and technologies (\acs{sacmat})},
+ year = 2007,
+ pages = {11--20},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ isbn = {978-1-59593-745-2},
+ location = {Sophia Antipolis, France},
+ doi = {10.1145/1266840.1266843},
+ tags = {ReadingList, SoKNOS, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ lupu.ea:policy:1996,
+ author = {Emil C. Lupu and Damian A. Marriott and Morris S. Sloman
+ and Nicholas Yialelis},
+ title = {A policy based role framework for access control},
+ booktitle = {RBAC '95: Proceedings of the first ACM Workshop on
+ Role-based access control},
+ year = 1996,
+ pages = 11,
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ isbn = {0-89791-759-6},
+ location = {Gaithersburg, Maryland, United States},
+ doi = {10.1145/270152.270171},
+ tags = {ReadingList, SoKNOS, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Article{ wainer.ea:dw-rbac:2007,
+ author = {Jacques Wainer and Akhil Kumar and Paulo Barthelmess},
+ title = {DW-RBAC: A formal security model of delegation and
+ revocation in workflow systems},
+ journal = {Inf. Syst.},
+ year = 2007,
+ volume = 32,
+ number = 3,
+ pages = {365--384},
+ abstract = {One reason workflow systems have been criticized as being
+ inflexible is that they lack support for delegation. This
+ paper shows how delegation can be introduced in a workflow
+ system by extending the role-based access control (RBAC)
+ model. The current RBAC model is a security mechanism to
+ implement access control in organizations by allowing users
+ to be assigned to roles and privileges to be associated
+ with the roles. Thus, users can perform tasks based on the
+ privileges possessed by their own role or roles they
+ inherit by virtue of their organizational position.
+ However, there is no easy way to handle delegations within
+ this model. This paper tries to treat the issues
+ surrounding delegation in workflow systems in a
+ comprehensive way. We show how delegations can be
+ incorporated into the RBAC model in a simple and
+ straightforward manner. The new extended model is called
+ RBAC with delegation in a workflow context (DW-RBAC). It
+ allows for delegations to be specified from a user to
+ another user, and later revoked when the delegation is no
+ longer required. The implications of such specifications
+ and their subsequent revocations are examined. Several
+ formal definitions for assertion, acceptance, execution and
+ revocation are provided, and proofs are given for the
+ important properties of our delegation framework.},
+ issn = {0306-4379},
+ doi = {http://dx.doi.org/10.1016/j.is.2005.11.008},
+ publisher = pub-elsevier,
+ address = {Oxford, UK, UK},
+ tags = {ReadingList, SoKNOS},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ bertino.ea:flexible:1997,
+ author = {Elisa Bertino and Elena Ferrari and Vijayalakshmi Atluri},
+ title = {A flexible model supporting the specification and
+ enforcement of role-based authorization in workflow
+ management systems},
+ booktitle = {RBAC '97: Proceedings of the second ACM workshop on
+ Role-based access control},
+ year = 1997,
+ pages = {1--12},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ isbn = {0-89791-985-8},
+ location = {Fairfax, Virginia, United States},
+ doi = {10.1145/266741.266746},
+ tags = {ReadingList, SoKNOS, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ bracha.ea:mixin-based:1990,
+ author = {Gilad Bracha and William Cook},
+ title = {Mixin-based inheritance},
+ booktitle = {OOPSLA/ECOOP '90: Proceedings of the European conference
+ on object-oriented programming on Object-oriented
+ programming systems, languages, and applications},
+ year = 1990,
+ pages = {303--311},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ isbn = {0-201-52430-X},
+ location = {Ottawa, Canada},
+ doi = {10.1145/97945.97982},
+ tags = {ReadingList, OOP},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ park.ea:towards:2002,
+ author = {Jaehong Park and Ravi Sandhu},
+ title = {Towards usage control models: beyond traditional access
+ control},
+ booktitle = {SACMAT '02: Proceedings of the seventh ACM symposium on
+ Access control models and technologies},
+ year = 2002,
+ pages = {57--64},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ isbn = {1-58113-496-7},
+ location = {Monterey, California, USA},
+ doi = {10.1145/507711.507722},
+ tags = {ReadingList, AccessControl, SoKNOS},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Article{ graham.ea:associations:1997,
+ author = {Ian Graham and Julia Bischof and Brian Henderson-Sellers},
+ title = {Associations Considered a Bad Thing},
+ journal = {JOOP},
+ year = 1997,
+ volume = 9,
+ number = 9,
+ pages = {41--48},
+ tags = {ReadingList, OOP},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ scharli.ea:traits:2003,
+ author = {Nathanael Sch{\"a}rli and St{\'e}phane Ducasse and Oscar
+ Nierstrasz and Andrew P. Black},
+ title = {Traits: Composable Units of Behaviour},
+ booktitle = {ECOOP},
+ year = 2003,
+ pages = {248--274},
+ ee = {http://springerlink.metapress.com/openurl.asp?genre=article{\&}issn=0302-9743{\&}volume=2743{\&}spage=248}
+ ,
+ crossref = {cardelli:ecoop:2003},
+ tags = {ReadingList, OOP},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ cardelli:ecoop:2003,
+ title = {ECOOP 2003 - Object-Oriented Programming, 17th European
+ Conference, Darmstadt, Germany, July 21-25, 2003,
+ Proceedings},
+ year = 2003,
+ editor = {Luca Cardelli},
+ volume = 2743,
+ series = s-lncs,
+ publisher = pub-springer,
+ booktitle = {ECOOP},
+ isbn = {3-540-40531-3},
+ tags = {ReadingList, OOP},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ wolter.ea:modelling:2008,
+ author = {Christian Wolter and Michael Menzel and Christoph Meinel},
+ title = {Modelling Security Goals in Business Processes},
+ booktitle = {Modellierung},
+ year = 2008,
+ pages = {197--212},
+ crossref = {kuhne.ea:modellierung:2008},
+ tags = {ReadingList, MDS, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ kuhne.ea:modellierung:2008,
+ title = {Modellierung 2008, 12.-14. M{\"a}rz 2008, Berlin},
+ year = 2008,
+ editor = {Thomas K{\"u}hne and Wolfgang Reisig and Friedrich
+ Steimann},
+ volume = 127,
+ series = {LNI},
+ publisher = {GI},
+ booktitle = {Modellierung},
+ isbn = {978-3-88579-221-5},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ wolter.ea:deriving:2007,
+ author = {Christian Wolter and Andreas Schaad and Christoph Meinel},
+ title = {Deriving XACML Policies from Business Process Models},
+ booktitle = {WISE Workshops},
+ year = 2007,
+ pages = {142--153},
+ ee = {http://dx.doi.org/10.1007/978-3-540-77010-7_15},
+ crossref = {weske.ea:web:2007},
+ tags = {ReadingList, SoKNOS, MDS},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ weske.ea:web:2007,
+ title = {Web Information Systems Engineering - WISE 2007 Workshops,
+ WISE 2007 International Workshops, Nancy, France, December
+ 3, 2007, Proceedings},
+ year = 2007,
+ editor = {Mathias Weske and Mohand-Said Hacid and Claude Godart},
+ volume = 4832,
+ series = s-lncs,
+ publisher = pub-springer,
+ booktitle = {WISE Workshops},
+ isbn = {978-3-540-77009-1},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ sandhu.ea:nist:2000,
+ author = {Ravi S. Sandhu and David F. Ferraiolo and D. Richard
+ Kuhn},
+ title = {The NIST model for role-based access control: towards a
+ unified standard},
+ booktitle = {ACM Workshop on Role-Based Access Control},
+ year = 2000,
+ pages = {47--63},
+ doi = {10.1145/344287.344301},
+ tags = {ReadingList, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Article{ ferraiolo.ea:proposed:2001,
+ author = {David F. Ferraiolo and Ravi S. Sandhu and Serban I.
+ Gavrila and D. Richard Kuhn and Ramaswamy Chandramouli},
+ title = {Proposed \acs{nist} standard for role-based access
+ control},
+ journal = j-tissec,
+ year = 2001,
+ pub = pub-acm,
+ address = pub-acm:adr,
+ volume = 4,
+ number = 3,
+ pages = {224--274},
+ doi = {10.1145/501978.501980},
+ tags = {ReadingList, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ drouineaud.ea:first:2004,
+ author = {Michael Drouineaud and Maksym Bortin and Paolo Torrini and
+ Karsten Sohr},
+ title = {A First Step Towards Formal Verification of Security
+ Policy Properties for \acs{rbac}},
+ booktitle = {QSIC},
+ year = 2004,
+ pages = {60--67},
+ doi = {10.1109/QSIC.2004.1357945},
+ crossref = {anonymous:qsic:2004},
+ tags = {AccessControl, FormalMethods, TheoremProving},
+ abstract = {Considering the current expansion of IT-infrastructure the
+ security of the data inside this infrastructure becomes
+ increasingly important. Therefore assuring certain security
+ properties of IT-systems by formal methods is desirable. So
+ far in security formal methods have mostly been used to
+ prove properties of security protocols. However, access
+ control is an indispensable part of security inside a given
+ IT-system, which has not yet been sufficiently examined
+ using formal methods. The paper presents an example of a
+ RBAC security policy having the dual control property. This
+ is proved in a first-order linear temporal logic (LTL) that
+ has been embedded in the theorem prover Isabelle/HOL by the
+ authors. Thus the correctness of the proof is assured by
+ Isabelle/HOL. The authors consider first-order LTL a good
+ formalism for expressing RBAC authorisation constraints and
+ deriving properties from given RBAC security policies.
+ Furthermore it might also be applied to safety-related
+ issues in similar manner.},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ anonymous:qsic:2004,
+ title = {4th International Conference on Quality Software (QSIC
+ 2004), 8-10 September 2004, Braunschweig, Germany},
+ year = 2004,
+ address = pub-ieee:adr,
+ publisher = pub-ieee,
+ booktitle = {QSIC},
+ isbn = {0-7695-2207-6},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ sohr.ea:specification:2005,
+ author = {Karsten Sohr and Gail-Joon Ahn and Martin Gogolla and Lars
+ Migge},
+ title = {Specification and Validation of Authorisation Constraints
+ Using UML and OCL},
+ booktitle = {ESORICS},
+ year = 2005,
+ pages = {64--79},
+ ee = {http://dx.doi.org/10.1007/11555827_5},
+ crossref = {vimercati.ea:computer:2005},
+ abstracts = {Abstract. Authorisation constraints can help the policy
+ architect design and express higher-level security policies
+ for organisations such as financial institutes or
+ governmental agencies. Although the importance of
+ constraints has been addressed in the literature, there
+ does not exist a systematic way to validate and test
+ authorisation constraints. In this paper, we attempt to
+ specify non-temporal constraints and history-based
+ constraints in Object Constraint Language (OCL) which is a
+ constraint specification language of Unified Modeling
+ Language (UML) and describe how we can facilitate the USE
+ tool to validate and test such policies. We also discuss
+ the issues of identification of conflicting constraints and
+ missing constraints. },
+ tags = {AccessControl, SecureUML},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ vimercati.ea:computer:2005,
+ title = {Computer Security - ESORICS 2005, 10th European Symposium
+ on Research in Computer Security, Milan, Italy, September
+ 12-14, 2005, Proceedings},
+ year = 2005,
+ editor = {Sabrina De Capitani di Vimercati and Paul F. Syverson and
+ Dieter Gollmann},
+ volume = 3679,
+ series = s-lncs,
+ publisher = pub-springer,
+ booktitle = {ESORICS},
+ isbn = {3-540-28963-1},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ wolter.ea:modeling:2007,
+ author = {Christian Wolter and Andreas Schaad},
+ title = {Modeling of Task-Based Authorization Constraints in BPMN},
+ booktitle = {BPM},
+ year = 2007,
+ pages = {64--79},
+ ee = {http://dx.doi.org/10.1007/978-3-540-75183-0_5},
+ crossref = {alonso.ea:business:2007},
+ tags = {ReadingList, SoKNOS, MDS, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ alonso.ea:business:2007,
+ title = {Business Process Management, 5th International Conference,
+ BPM 2007, Brisbane, Australia, September 24-28, 2007,
+ Proceedings},
+ year = 2007,
+ editor = {Gustavo Alonso and Peter Dadam and Michael Rosemann},
+ volume = 4714,
+ series = s-lncs,
+ publisher = pub-springer,
+ booktitle = {BPM},
+ isbn = {978-3-540-75182-3},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Article{ sohr.ea:analyzing:2008,
+ author = {Karsten Sohr and Michael Drouineaud and Gail-Joon Ahn and
+ Martin Gogolla},
+ title = {Analyzing and Managing Role-Based Access Control
+ Policies},
+ journal = j-tkde,
+ year = 2008,
+ doi = {10.1109/TKDE.2008.28},
+ abstract = {Today more and more security-relevant data is stored on
+ computer systems; security-critical business processes are
+ mapped to their digital counterparts. This situation
+ applies to various domains such as health care industry,
+ digital government, and financial service institutes
+ requiring that different security requirements must be
+ fulfilled. Authorisation constraints can help the policy
+ architect design and express higher-level organisational
+ rules. Although the importance of authorisation constraints
+ has been addressed in the literature, there does not exist
+ a systematic way to verify and validate authorisation
+ constraints. In this paper, we specify both non-temporal
+ and history-based authorisation constraints in the Object
+ Constraint Language (OCL) and first-order linear temporal
+ logic (LTL). Based upon these specifications, we attempt to
+ formally verify role-based access control policies with the
+ help of a theorem prover and to validate policies with the
+ USE system, a validation tool for OCL constraints. We also
+ describe an authorisation engine, which supports the
+ enforcement of authorisation constraints.},
+ tags = {ReadingList, AccessControl},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Article{ samuel.ea:context-aware:2008,
+ author = {Samuel, A. and Ghafoor, A. and Bertino, E.},
+ title = {Context-Aware Adaptation of Access-Control Policies},
+ journal = {Internet Computing, IEEE},
+ year = 2008,
+ volume = 12,
+ number = 1,
+ pages = {51--54},
+ abstract = {Today, public-service delivery mechanisms such as
+ hospitals, police, and fire departments rely on digital
+ generation, storage, and analysis of vital information. To
+ protect critical digital resources, these organizations
+ employ access-control mechanisms, which define rules under
+ which authorized users can access the resources they need
+ to perform organizational tasks. Natural or man-made
+ disasters pose a unique challenge, whereby previously
+ defined constraints can potentially debilitate an
+ organization's ability to act. Here, the authors propose
+ employing contextual parameters - specifically, activity
+ context in the form of emergency warnings - to adapt
+ access-control policies according to a priori
+ configuration.},
+ keywords = {authorisation, disasters, organisational
+ aspectsaccess-control policy, context-aware adaptation,
+ digital resource protection, natural disaster,
+ organizational task, public-service delivery mechanism},
+ doi = {10.1109/MIC.2008.6},
+ issn = {1089-7801},
+ tags = {ReadingList, AccessControl, SoKNOS},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Article{ adam.ea:secure:2007,
+ author = {Nabil Adam and Ahmet Kozanoglu and Aabhas Paliwal and
+ Basit Shafiq},
+ title = {Secure Information Sharing in a Virtual Multi-Agency Team
+ Environment},
+ journal = j-entcs,
+ year = 2007,
+ volume = 179,
+ pages = {97--109},
+ issn = {1571-0661},
+ abstract = {This paper proposes a two tier RBAC approach for secure
+ and selective information sharing among virtual
+ multi-agency response team (VMART) and allows expansion of
+ the VMART by admitting new collaborators (government
+ agencies or NGOs) as need arise. A coordinator Web Service
+ for each member agency is proposed. The coordinator Web
+ Service is responsible for authentication, information
+ dissemination, information acquisition, role creation and
+ enforcement of predefined access control policies. Secure,
+ selective and fine-grained information sharing is realized
+ through the encryption of XML documents according to RBAC
+ policies defined for the corresponding XML schema.},
+ doi = {http://dx.doi.org/10.1016/j.entcs.2006.08.034},
+ publisher = pub-elsevier,
+ address = pub-elsevier:adr,
+ tags = {ReadingList, SoKNOS},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ alam.ea:framework:2006,
+ author = {Muhammad Alam and Michael Hafner and Ruth Breu and Stefan
+ Unterthiner},
+ title = {A Framework for Modeling Restricted Delegation in Service
+ Oriented Architecture},
+ booktitle = {TrustBus},
+ year = 2006,
+ pages = {142--151},
+ ee = {http://dx.doi.org/10.1007/11824633_15},
+ crossref = {fischer-hubner.ea:trust:2006},
+ tags = {ReadingList, SoKNOS},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ fischer-hubner.ea:trust:2006,
+ title = {Trust and Privacy in Digital Business, Third International
+ Conference, TrustBus 2006, Krakow, Poland, September 4-8,
+ 2006, Proceedings},
+ year = 2006,
+ editor = {Simone Fischer-H{\"u}bner and Steven Furnell and Costas
+ Lambrinoudakis},
+ volume = 4083,
+ series = s-lncs,
+ publisher = pub-springer,
+ booktitle = {TrustBus},
+ isbn = {3-540-37750-6},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ el-atawy.ea:policy:2005,
+ author = {Adel El-Atawy and K. Ibrahim and H. Hamed and Ehab
+ Al-Shaer},
+ title = {Policy segmentation for intelligent firewall testing},
+ booktitle = {NPSec 05},
+ year = 2005,
+ pages = {67--72},
+ month = nov,
+ publisher = pub-ieee,
+ day = 6,
+ keywords = {computer networks, intelligent networks, telecommunication
+ security, telecommunication traffic intelligent firewall
+ testing, network security, network traffic, packet
+ filtering algorithms, policy segmentation},
+ acknowledgement={none},
+ tags = {ReadingList, Testing, FWTesting},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ el-atawy.ea:automated:2007,
+ author = {Adel El-Atawy and Taghrid Samak and Zein Wali and Ehab
+ Al-Shaer and Frank Lin and Christopher Pham and Sheng Li},
+ title = {An Automated Framework for Validating Firewall Policy
+ Enforcement},
+ booktitle = {\acs{policy} '07},
+ year = 2007,
+ pages = {151--160},
+ publisher = pub-ieee,
+ acknowledgement={none},
+ tags = {ReadingList, Testing, FWTesting},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ bishop.ea:engineering:2006,
+ author = {Steve Bishop and Matthew Fairbairn and Michael Norrish and
+ Peter Sewell and Michael Smith and Keith Wansbrough},
+ title = {Engineering with logic: \acs{hol} specification and
+ symbolic-evaluation testing for \acs{tcp} implementations},
+ booktitle = {\acs{popl}},
+ year = 2006,
+ pages = {55--66},
+ crossref = {morrisett.ea:proceedings:2006},
+ acknowledgement={none},
+ tags = {ReadingList, FWTesting, Testing},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ morrisett.ea:proceedings:2006,
+ title = {\acs{popl}},
+ year = 2006,
+ editor = {J. Gregory Morrisett and Simon L. Peyton Jones},
+ publisher = pub-acm,
+ booktitle = {\acs{popl}},
+ adress = pub-acm:adr,
+ acknowledgement={none},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ marmorstein.ea:firewall:2006,
+ author = {Robert Marmorstein and Phil Kearns},
+ title = {Firewall analysis with policy-based host classification},
+ booktitle = {\acs{lisa}'06},
+ year = 2006,
+ pages = {4--4},
+ publisher = {\acs{usenix} Association},
+ location = {Washington, \acs{dc}},
+ acknowledgement={none},
+ tags = {ReadingList, FWTesting, Testing},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ richters.ea:formalizing:1998,
+ abstract = {We present a formal semantics for the Object Constraint
+ Language (OCL) which is part of the Unified Modeling
+ Language (UML) - an emerging standard language and notation
+ for object-oriented analysis and design. In context of
+ information systems modeling, UML class diagrams can be
+ utilized for describing the overall structure, whereas
+ additional integrity constraints and queries are specified
+ with OCL expressions. By using OCL, constraints and queries
+ can be specified in a formal yet comprehensible way.
+ However, the OCL itself is currently defined only in a
+ semi-formal way. Thus the semantics of constraints is in
+ general not precisely defined. Our approach gives precise
+ meaning to OCL concepts and to some central aspects of UML
+ class models. A formal semantics facilitates verification,
+ validation and simulation of models and helps to improve
+ the quality of models and software designs.},
+ bibkey = {richters.ea:formalizing:1998},
+ author = {Mark Richters and Martin Gogolla},
+ title = {On Formalizing the \acs{uml} Object Constraint Language
+ \acs{ocl}},
+ pages = {449--464},
+ doi = {10.1007/b68220},
+ crossref = {ling.ea:conceptual:1998},
+ acknowledgement={brucker, 2007-02-19},
+ tags = {MDE},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ ling.ea:conceptual:1998,
+ language = {USenglish},
+ editor = {Tok Wang Ling and Sudha Ram and Mong-Li Lee},
+ booktitle = {Conceptual Modeling---{ER} '98},
+ title = {Conceptual Modeling---{ER} '98},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 1507,
+ doi = {10.1007/b68220},
+ year = 1998,
+ isbn = {978-3-540-65189-5},
+ acknowledgement={brucker, 2007-02-19},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ cook.ea::amsterdam:2002,
+ abstract = {In November 1998 the authors participated in a two-day
+ workshop on the Object Constraint Language (OCL) in
+ Amsterdam. The focus was to clarify issues about the
+ semantics and the use of OCL, and to discuss useful and
+ necessary extensions of OCL. Various topics have been
+ raised and clarified. This manifesto contains the results
+ of that workshop and the following work on these topics.
+ Overview of OCL.},
+ author = {Steve Cook and Anneke Kleppe and Richard Mitchell and
+ Bernhard Rumpe and Jos Warmer and Alan Wills},
+ title = {The Amsterdam Manifesto on \acs{ocl}},
+ pages = {115--149},
+ crossref = {clark.ea:object:2002},
+ acknowledgement={brucker, 2007-02-19},
+ tags = {MDE},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ gogolla.ea:expressing:2001,
+ author = {Martin Gogolla and Mark Richters},
+ bibkey = {gogolla.ea:expressing:2001},
+ abstract = {The Unified Modeling Language \acs{uml} is a complex
+ language offering many modeling features. Especially the
+ description of static structures with class diagrams is
+ supported by a rich set of primitives. This paper shows how
+ to transfrom \acs{uml} class diagrams involving cardinality
+ constraints, qualifiers, association classes, aggregations,
+ compositions, and generalizations into equivalent \acs{uml}
+ class diagrams employing only binary associations and
+ \acs{ocl} constraints. Thus we provide a better
+ understanding of \acs{uml} features. By reducing more
+ complex features in terms of basic ones, we suggest an easy
+ way users can gradually extend the set of \acs{uml}
+ elements they commonly apply in the modeling process.},
+ title = {Expressing \acs{uml} Class Diagrams Properties with
+ \acs{ocl}},
+ pages = {85--114},
+ crossref = {clark.ea:object:2002},
+ acknowledgement={brucker, 2007-02-19},
+ tags = {MDE},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ richters.ea:ocl:2001,
+ abstract = {{The Object Constraint Language \acs{ocl} allows to
+ formally specify constraints on a \acs{uml} model. We
+ present a formal syntax and semantics for \acs{ocl} based
+ on set theory including expressions, invariants and pre-
+ and postconditions. A formal foundation for \acs{ocl} makes
+ the meaning of constraints precise and helps to eliminate
+ ambiguities and inconsistencies. A precise language de
+ nition is also a prerequisite for implementing CASE tools
+ providing enhanced support for \acs{uml} models and
+ \acs{ocl} constraints. We give a survey of some \acs{ocl}
+ tools and discuss one of the tools in some more detail. The
+ design and implementation of the USE tool supporting the
+ validation of \acs{uml} models and \acs{ocl} constraints is
+ based on the formal approach presented in this paper.}},
+ bibkey = {richters.ea:ocl:2001},
+ author = {Mark Richters and Martin Gogolla},
+ title = {\acs{ocl}: Syntax, Semantics, and Tools.},
+ pages = {42--68},
+ crossref = {clark.ea:object:2002},
+ acknowledgement={brucker, 2007-02-19},
+ tags = {MDE},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ hennicker.ea:precise:2002,
+ author = {Rolf Hennicker and Heinrich Hu{\ss}mann and Michel Bidoit},
+ title = {On the Precise Meaning of \acs{ocl} Constraints},
+ pages = {69--84},
+ crossref = {clark.ea:object:2002},
+ abstract = {When OCL is applied in concrete examples, many questions
+ arise about the precise meaning of OCL constraints. The
+ same kind of difficulties appears when automatic support
+ tools for OCL are designed. These questions are due to the
+ lack of a precise semantics of OCL constraints in the
+ context of a UML model. The aim of this paper is to
+ contribute to a clarification of several issues, like
+ interpretation of invariants and pre- and postconditions,
+ treatment of undefined values, inheritance of constraints,
+ transformation rules for OCL constraints and computation of
+ proof obligations. Our study is based on a formal, abstract
+ semantics of OCL.},
+ bibkey = {hennicker.ea:precise:2002},
+ acknowledgement={brucker, 2007-02-19},
+ tags = {MDE},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ clark.ea:object:2002,
+ editor = {Tony Clark and Jos Warmer},
+ booktitle = {Object Modeling with the \acs{ocl}: The Rationale behind
+ the Object Constraint Language},
+ title = {Object Modeling with the \acs{ocl}: The Rationale behind
+ the Object Constraint Language},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2263,
+ year = 2002,
+ isbn = {3-540-43169-1},
+ acknowledgement={brucker, 2007-02-19},
+ tags = {MDE},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ cengarle.ea:formal:2001,
+ author = {Mar\'{\i}a Victoria Cengarle and Alexander Knapp},
+ title = {A Formal Semantics for \acs{ocl} 1.4},
+ year = 2001,
+ abstract = {The OCL 1.4 specification introduces let-declarations for
+ adding auxiliary class features in static structures of the
+ UML. We provide a type inference system and a big-step
+ operational semantics for the OCL 1.4 that treat UML static
+ structures and UML object models and accommodate for
+ additional declarations; the operational semantics
+ satisfies a subject reduction property with respect to the
+ type inference system. We also discuss an alternative,
+ non-operational interpretation of let-declarations as
+ constraints.},
+ pages = {118--133},
+ crossref = {gogolla.ea:uml:2001},
+ acknowledgement={brucker, 2007-02-19},
+ tags = {MDE},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ gogolla.ea:uml:2001,
+ editor = {Martin Gogolla and Cris Kobryn},
+ booktitle = {\acs{uml} 2001---The Unified Modeling Language. Modeling
+ Languages, Concepts, and Tools},
+ title = {\acs{uml} 2001---The Unified Modeling Language. Modeling
+ Languages, Concepts, and Tools},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2185,
+ year = 2001,
+ isbn = {3-540-42667-1},
+ location = {Toronto, Canada},
+ acknowledgement={brucker, 2007-02-19},
+ tags = {MDE},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@TechReport{ balzer.ea:objects:2008,
+ author = {Stephanie Balzer and Alexandra Burns and Thomas R. Gross},
+ title = {Objects in Context: An Empirical Study of Object
+ Relationships},
+ institution = {\acs{eth} Zurich},
+ year = 2008,
+ abstract = {Object collaborations are at the core of all
+ object-oriented programming, yet current class-based
+ objectoriented programming languages do not provide an
+ explicit construct to capture the relationships between
+ objects. This paper reports on an empirical study that
+ investigates the occurrence of object collaborations to
+ assess the need of intrinsic support for relationships in a
+ programming language. We introduce a categorization of
+ possible forms of object collaborations and their
+ corresponding implementation patterns when using a
+ traditional class-based object-oriented language (Java) and
+ analyze 25 Java programs (ranging from 4 to 6275 classes)
+ with the Relationship Detector for Java (RelDJ) to identify
+ occurrences of these patterns. The empirical results show
+ that object collaborations are indeed a frequent phenomenon
+ and reveal that collaborationrelated code does not remain
+ encapsulated in a single class. These observations strongly
+ support efforts to define language constructs to express
+ object relationships: relationships allow the encapsulation
+ of a frequently occurring phenomenon and increase program
+ expressiveness. },
+ keywords = {Relationship-based Programming Languages, First-class
+ Relationships, Object Collaborations, Java, Bytecode
+ Analysis},
+ tags = {ReadingList, OOP},
+ clearance = {unclassified},
+ timestap = {2008-05-28},
+ number = 594
+}
+
+@InProceedings{ owre.ea:pvs:1996,
+ author = {Sam Owre and S. Rajan and John M. Rushby and Natarajan
+ Shankar and Mandayam K. Srivas},
+ title = {\acs{pvs}: Combining Specification, Proof Checking, and
+ Model Checking},
+ year = 1996,
+ bibkey = {owre.ea:pvs:1996},
+ pages = {411--414},
+ crossref = {alur.ea:computer:1996},
+ doi = {10.1007/3-540-61474-5_91},
+ acknowledgement={brucker, 2007-02-19},
+ tags = {TheoremProving, FormalMethods},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ alur.ea:computer:1996,
+ editor = {Rajeev Alur and Thomas A. Henzinger},
+ booktitle = {Computer Aided Verification (\acs{cav})},
+ title = {Computer Aided Verification (\acs{cav})},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 1102,
+ year = 1996,
+ location = {New Brunswick, \acs{nj}, \acs{usa}},
+ doi = {10.1007/3-540-61474-5},
+ isbn = {3-540-61474-5},
+ acknowledgement={brucker, 2007-02-19},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ naraschewski.ea:object-oriented:1998,
+ author = {Wolfgang Naraschewski and Markus Wenzel},
+ title = {Object-Oriented Verification Based on Record Subtyping in
+ Higher-Order Logic.},
+ pages = {349--366},
+ doi = {10.1007/BFb0055146},
+ crossref = {grundy.ea:theorem:1998},
+ abstract = {We show how extensible records with structural subtyping
+ can be represented directly in Higher-Order Logic
+ (\acs{hol}). Exploiting some specific properties of
+ \acs{hol}, this encoding turns out to be extremely simple.
+ In particular, structural subtyping is subsumed by naive
+ parametric polymorphism, while overridable generic
+ functions may be based on overloading. Taking \acs{hol}
+ plus extensible records as a starting point, we then set
+ out to build an environment for object-oriented
+ specification and verification (HOOL). This framework
+ offers several well-known concepts like classes, objects,
+ methods and late-binding. All of this is achieved by very
+ simple means within \acs{hol}. },
+ keywords = {Isabelle/\acs{hol}, extensible records,
+ object-orientation, verification},
+ bibkey = {naraschewski.ea:object-oriented:1998},
+ acknowledgement={brucker, 2007-02-19},
+ tags = {TheoremProving, FormalMethods},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ grundy.ea:theorem:1998,
+ editor = {Jim Grundy and Malcolm C. Newey},
+ title = {Theorem Proving in Higher Order Logics (\acs{tphols})},
+ booktitle = {Theorem Proving in Higher Order Logics (\acs{tphols})},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 1479,
+ year = 1998,
+ doi = {10.1007/BFb0055125},
+ isbn = {3-540-64987-5},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ oheimb.ea:hoare:2002,
+ author = {David von Oheimb and Tobias Nipkow},
+ title = {Hoare Logic for {NanoJava}: Auxiliary Variables, Side
+ Effects, and Virtual Methods Revisited},
+ pages = {89--105},
+ doi = {10.1007/3-540-45614-7_6},
+ crossref = {eriksson.ea:fme:2002},
+ acknowledgement={brucker, 2007-02-19},
+ abstract = {We define NanoJava, a kernel of Java tailored to the
+ investigation of Hoare logics. We then introduce a Hoare
+ logic for this language featuring an elegant new approach
+ for expressing auxiliary variables: by universal
+ quantification on the outer logical level. Furthermore, we
+ give simple means of handling side-effecting expressions
+ and dynamic binding within method calls. The logic is
+ proved sound and (relatively) complete using
+ Isabelle/\acs{hol}.},
+ keywords = {Languages, Reliability, Theory, Verification},
+ tags = {OOP, FormalMethods},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Proceedings{ eriksson.ea:fme:2002,
+ editor = {Lars-Henrik Eriksson and Peter Alexander Lindsay},
+ booktitle = {\acs{fme} 2002: Formal Methods---Getting {IT} Right},
+ title = {\acs{fme} 2002: Formal Methods---Getting {IT} Right},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2391,
+ doi = {10.1007/3-540-45614-7},
+ year = 2002,
+ isbn = {3-540-43928-5},
+ acknowledgement={brucker, 2007-02-19},
+ tags = {noTAG},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@Article{ rudnicki:obvious:1987,
+ author = {Piotr Rudnicki},
+ key = {Rudnicki},
+ journal = j-ar,
+ title = {Obvious Inferences},
+ year = 1987,
+ month = dec,
+ volume = 3,
+ doi = {10.1007/BF00247436},
+ number = 4,
+ abstract = {The notion of 'obvious' inference in predicate logic is
+ discussed from the viewpoint of proof- checker applications
+ in logic and mathematics education. A class of inferences
+ in predicate logic is defined and it is proposed to
+ identify it with the class of 'obvious' logical inferences.
+ The definition is compared with other approaches. The
+ algorithm for implementing the "obviousness' decision
+ procedure follows directly from the definition.},
+ pages = {383--394},
+ publisher = pub-springer-netherlands,
+ address = pub-springer-netherlands:adr,
+ tags = {noTAG},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ stroustrup:what:1987,
+ author = {Bjarne Stroustrup},
+ title = {What is "Object-Oriented Programming?"},
+ booktitle = {ECOOP},
+ year = 1987,
+ pages = {51--70},
+ abstract = {"Object-Oriented Programming" and "Data ion" have become
+ very common terms. Unfortunately, few people agree on what
+ they mean. I will offer informal definitions that appear to
+ make sense in the context of languages like Ada, C++,
+ Modula-2, Simula67, and Smalltalk. The general idea is to
+ equate "support for data abstraction" with the ability to
+ define and use new types and equate "support for
+ object-oriented programming" with the ability to express
+ type hierarchies. Features necessary to support these
+ programming styles in a general purpose programming
+ language will be discussed. The presentation centers around
+ C++ but is not limited to facilities provided by that
+ language.},
+ crossref = {bezivin.ea:ecoop87:1987}
+}
+
+@Proceedings{ bezivin.ea:ecoop87:1987,
+ editor = {Jean B{\'e}zivin and Jean-Marie Hullot and Pierre Cointe
+ and Henry Lieberman},
+ title = {ECOOP'87 European Conference on Object-Oriented
+ Programming, Paris, France, June 15-17, 1987, Proceedings},
+ booktitle = {ECOOP},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 276,
+ year = 1987,
+ isbn = {3-540-18353-1},
+ location = {Paris, France}
+}
+
+@Book{ nipkow.ea:isabelle:2002,
+ author = {Tobias Nipkow and Lawrence C. Paulson and Markus Wenzel},
+ title = {Isabelle/\acs{hol}---A Proof Assistant for Higher-Order
+ Logic},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2283,
+ doi = {10.1007/3-540-45949-9},
+ abstract = {This book is a self-contained introduction to interactive
+ proof in higher-order logic (\acs{hol}), using the proof
+ assistant Isabelle2002. It is a tutorial for potential
+ users rather than a monograph for researchers. The book has
+ three parts.
+
+ 1. Elementary Techniques shows how to model functional
+ programs in higher-order logic. Early examples involve
+ lists and the natural numbers. Most proofs are two steps
+ long, consisting of induction on a chosen variable followed
+ by the auto tactic. But even this elementary part covers
+ such advanced topics as nested and mutual recursion. 2.
+ Logic and Sets presents a collection of lower-level tactics
+ that you can use to apply rules selectively. It also
+ describes Isabelle/\acs{hol}'s treatment of sets, functions
+ and relations and explains how to define sets inductively.
+ One of the examples concerns the theory of model checking,
+ and another is drawn from a classic textbook on formal
+ languages. 3. Advanced Material describes a variety of
+ other topics. Among these are the real numbers, records and
+ overloading. Advanced techniques are described involving
+ induction and recursion. A whole chapter is devoted to an
+ extended example: the verification of a security protocol. },
+ year = 2002,
+ acknowledgement={brucker, 2007-02-19},
+ bibkey = {nipkow.ea:isabelle:2002},
+ tags = {noTAG},
+ clearance = {unclassified},
+ timestap = {2008-05-26}
+}
+
+@InProceedings{ kerber.ea:mechanization:1994,
+ author = {Manfred Kerber and Michael Kohlhase},
+ title = {A Mechanization of Strong Kleene Logic for Partial
+ Functions},
+ pages = {371--385},
+ crossref = {bundy:automated:1994},
+ abstract = {Even though it is not very often admitted, partial
+ functions do play a significant role in many practical
+ applications of deduction systems. Kleene has already given
+ a semantic account of partial functions using three-valued
+ logic decades ago, but there has not been a satisfactory
+ mechanization. Recent years have seen a thorough
+ investigation of the framework of many-valued
+ truth-functional logics. However, strong Kleene logic,
+ where quantification is restricted and therefore not
+ truth-functional, does not fit the framework directly. We
+ solve this problem by applying recent methods from sorted
+ logics. This paper presents a resolution calculus that
+ combines the proper treatment of partial functions with the
+ efficiency of sorted calculi.},
+ doi = {10.1007/3-540-58156-1_26},
+ acknowledgement={brucker, 2007-02-19},
+ bibkey = {kerber.ea:mechanization:1994}
+}
+
+@Proceedings{ bundy:automated:1994,
+ editor = {Alan Bundy},
+ booktitle = {Automated Deduction---\acs{cade}-12},
+ title = {Automated Deduction---\acs{cade}-12},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ location = {Nancy, France},
+ volume = 814,
+ year = 1994,
+ isbn = {3-540-58156-1},
+ acknowledgement={brucker, 2007-02-19},
+ doi = {10.1007/3-540-58156-1}
+}
+
+@InProceedings{ hahnle:towards:1991,
+ author = {Reiner H{\"a}hnle},
+ title = {Towards an Efficient Tableau Proof Procedure for
+ Multiple-Valued Logics},
+ pages = {248--260},
+ crossref = {borger.ea:computer:1991},
+ doi = {10.1007/3-540-54487-9_62},
+ abstract = {One of the obstacles against the use of tableau-based
+ theorem provers for non-standard logics is the inefficiency
+ of tableau systems in practical applications, though they
+ are highly intuitive and extremely flexible from a proof
+ theoretical point of view. We present a method for
+ increasing the efficiency of tableau systems in the case of
+ multiple-valued logics by introducing a generalized notion
+ of signed formulas and give sound and complete tableau
+ systems for arbitrary propositional finite-valued logics.},
+ acknowledgement={brucker, 2007-02-19},
+ bibkey = {hahnle:towards:1991}
+}
+
+@Proceedings{ borger.ea:computer:1991,
+ editor = {Egon B{\"o}rger and Hans Kleine B{\"u}ning and Michael M.
+ Richter and Wolfgang Sch{\"o}nfeld},
+ title = {Computer Science Logic (\acs{csl})},
+ booktitle = {Computer Science Logic (\acs{csl})},
+ series = s-lncs,
+ volume = 533,
+ year = 1991,
+ doi = {10.1007/3-540-54487-9},
+ isbn = {978-3-540-54487-6},
+ acknowledgement={brucker, 2007-02-19},
+ publisher = pub-springer,
+ address = pub-springer:adr
+}
+
+@InProceedings{ berghofer.ea:inductive:1999,
+ author = {Stefan Berghofer and Markus Wenzel},
+ title = {Inductive datatypes in \acs{hol}---lessons learned in
+ Formal-Logic Engineering},
+ pages = {19--36},
+ crossref = {bertot.ea:theorem:1999},
+ bibkey = {berghofer.ea:inductive:1999},
+ month = sep,
+ doi = {10.1007/3-540-48256-3_3},
+ acknowledgement={brucker, 2007-02-19}
+}
+
+@Proceedings{ bertot.ea:theorem:1999,
+ editor = {Yves Bertot and Gilles Dowek and Andr{\'e} Hirschowitz and
+ C. Paulin and Laurent Th{\'e}ry},
+ title = {Theorem Proving in Higher Order Logics (\acs{tphols})},
+ booktitle = {Theorem Proving in Higher Order Logics (\acs{tphols})},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 1690,
+ acknowledgement={brucker, 2007-02-19},
+ location = {Nice, France},
+ year = 1999,
+ isbn = {3-540-66463-7}
+}
+
+@Proceedings{ geuvers.ea:types:2003,
+ editor = {Herman Geuvers and Freek Wiedijk},
+ title = {Types for Proofs and Programs (\acs{types})},
+ booktitle = {Types for Proofs and Programs (\acs{types})},
+ publisher = pub-springer,
+ location = {Nijmegen},
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2646,
+ language = {USenglish},
+ year = 2003,
+ isbn = {3-540-14031-X},
+ acknowledgement={brucker, 2007-02-19}
+}
+
+@InProceedings{ angelo.ea:degrees:1994,
+ author = {Catia M. Angelo and Luc J. M. Claesen and Hugo De Man},
+ title = {Degrees of Formality in Shallow Embedding Hardware
+ Description Languages in \acs{hol}},
+ pages = {89--100},
+ doi = {10.1007/3-540-57826-9_127},
+ crossref = {joyce.ea:higher:1994},
+ bibkey = {angelo.ea:degrees:1994},
+ acknowledgement={brucker, 2007-02-19}
+}
+
+@Proceedings{ joyce.ea:higher:1994,
+ editor = {Jeffrey J. Joyce and Carl-Johan H. Seger},
+ title = {Higher Order Logic Theorem Proving and Its Applications
+ (\acs{hug})},
+ booktitle = {Higher Order Logic Theorem Proving and Its Applications
+ (\acs{hug})},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ abstract = {Theorem proving based techniques for formal hardware
+ verification have been evolving constantly and researchers
+ are getting able to reason about more complex issues than
+ it was possible or practically feasible in the past. It is
+ often the case that a model of a system is built in a
+ formal logic and then reasoning about this model is carried
+ out in the logic. Concern is growing on how to consistently
+ interface a model built in a formal logic with an informal
+ CAD environment. Researchers have been investigating how to
+ define the formal semantics of hardware description
+ languages so that one can formally reason about models
+ informally dealt with in a CAD environment. At the
+ University of Cambridge, the embedding of hardware
+ description languages in a logic is classified in two
+ categories: deep embedding and shallow embedding. In this
+ paper we argue that there are degrees of formality in
+ shallow embedding a language in a logic. The choice of the
+ degree of formality is a trade-off between the security of
+ the embedding and the amount and complexity of the proof
+ effort in the logic. We also argue that the design of a
+ language could consider this verifiability issue. There are
+ choices in the design of a language that can make it easier
+ to improve the degree of formality, without implying
+ serious drawbacks for the CAD environment.},
+ volume = 780,
+ year = 1994,
+ doi = {10.1007/3-540-57826-9},
+ isbn = {3-540-57826-9},
+ acknowledgement={brucker, 2007-02-19}
+}
+
+@InProceedings{ huffman.ea:axiomatic:2005,
+ author = {Brian Huffman and John Matthews and Peter White},
+ title = {Axiomatic Constructor Classes in {Isabelle}/\acs{holcf}.},
+ pages = {147--162},
+ doi = {10.1007/11541868_10},
+ crossref = {hurd.ea:theorem:2005},
+ acknowledgement={brucker, 2007-02-19},
+ bibkey = {huffman.ea:axiomatic:2005},
+ abstract = {We have definitionally extended Isabelle/HOLCF to support
+ axiomatic Haskell-style constructor classes. We have
+ subsequently defined the functor and monad classes,
+ together with their laws, and implemented state and
+ resumption monad transformers as generic constructor class
+ instances. This is a step towards our goal of giving
+ modular denotational semantics for concurrent lazy
+ functional programming languages, such as GHC Haskell.}
+}
+
+@InProceedings{ marche.ea:reasoning:2005,
+ author = {Claude March{\'e} and Christine Paulin-Mohring},
+ title = {Reasoning About {Java} Programs with Aliasing and Frame
+ Conditions},
+ pages = {179--194},
+ crossref = {hurd.ea:theorem:2005},
+ abstract = {Several tools exist for reasoning about Java programs
+ annotated with JML specifications. A main issue is to deal
+ with possible aliasing between objects and to handle
+ correctly the frame conditions limiting the part of memory
+ that a method is allowed to modify. Tools designed for
+ automatic use (like ESC/Java) are not complete and even not
+ necessarily correct. On the other side, tools which offer a
+ full modeling of the program require a heavy user
+ interaction for discharging proof obligations. In this
+ paper, we present the modeling of Java programs used in the
+ Krakatoa tool, which generates proof obligations expressed
+ in a logic language suitable for both automatic and
+ interactive reasoning. Using the Simplify automatic theorem
+ prover, we are able to establish automatically more
+ properties than static analysis tools, with a method which
+ is guaranteed to be sound, assuming only the correctness of
+ our logical interpretation of programs and
+ specifications.},
+ doi = {10.1007/11541868_12},
+ acknowledgement={brucker, 2007-02-19},
+ bibkey = {marche.ea:reasoning:2005}
+}
+
+@Proceedings{ hurd.ea:theorem:2005,
+ editor = {Joe Hurd and Thomas F. Melham},
+ title = {Theorem Proving in Higher Order Logics (\acs{tphols})},
+ booktitle = {Theorem Proving in Higher Order Logics (\acs{tphols})},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 3603,
+ doi = {10.1007/11541868},
+ year = 2005,
+ isbn = {978-3-540-28372-0},
+ acknowledgement={brucker, 2007-02-19}
+}
+
+@InProceedings{ leino.ea:modular:2005,
+ author = {K. Rustan M. Leino and Peter M{\"u}ller},
+ title = {Modular Verification of Static Class Invariants.},
+ pages = {26--42},
+ doi = {10.1007/11526841_4},
+ abstract = {Object invariants describe the consistency of
+ object-oriented data structures and are central to
+ reasoning about the correctness of object-oriented
+ software. But object invariants are not the only
+ consistency conditions on which a program may depend. The
+ data in object-oriented programs consists not just of
+ object fields, but also of static fields, which hold data
+ that is shared among objects. The consistency of static
+ fields is described by static class invariants, which are
+ enforced at the class level. Static class invariants can
+ also mention instance fields, describing the consistency of
+ dynamic data structures rooted in static fields. Sometimes
+ there are even consistency conditions that relate the
+ instance fields of many or all objects of a class; static
+ class invariants describe these relations, too, since they
+ cannot be enforced by any one object in isolation. This
+ paper presents a systematic way (a methodology) for
+ specifying and verifying static class invariants in
+ object-oriented programs. The methodology supports the
+ three major uses of static fields and invariants in the
+ Java library. The methodology is amenable to static,
+ modular verification and is sound.},
+ crossref = {fitzgerald.ea:fm:2005},
+ acknowledgement={brucker, 2007-02-19}
+}
+
+@InProceedings{ basin.ea:verification:2005,
+ author = {David A. Basin and Hironobu Kuruma and Kazuo Takaragi and
+ Burkhart Wolff},
+ abstract = {We report on a case study in using \holz, an embedding of
+ Z in higher-order logic, to specify and verify a security
+ architecture for administering digital signatures. We have
+ used \holz{} to formalize and combine both data-oriented
+ and process-oriented architectural views. Afterwards, we
+ formalized temporal requirements in Z and carried out
+ verification in higher-order logic. The same architecture
+ has been previously verified using the SPIN model checker.
+ Based on this, we provide a detailed comparison of these
+ two di erent approaches to formalization (infinite state
+ with rich data types versus finite state) and verification
+ (theorem proving versus model checking). Contrary to common
+ belief, our case study suggests that Z is well suited for
+ temporal reasoning about process models with rich data.
+ Moreover, our comparison highlights the advantages of this
+ approach and provides evidence that, in the hands of
+ experienced users, theorem proving is neither substantially
+ more time-consuming nor more complex than model checking.},
+ title = {Verification of a Signature Architecture with \holz},
+ pages = {269--285},
+ crossref = {fitzgerald.ea:fm:2005},
+ language = {USenglish},
+ acknowledgement={brucker, 2007-02-19},
+ doi = {10.1007/11526841_19},
+ bibkey = {basin.ea:verification:2005}
+}
+
+@Proceedings{ fitzgerald.ea:fm:2005,
+ editor = {John Fitzgerald and Ian J. Hayes and Andrzej Tarlecki},
+ booktitle = {{FM} 2005: Formal Methods},
+ title = {{FM} 2005: Formal Methods},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 3582,
+ year = 2005,
+ acknowledgement={brucker, 2007-02-19},
+ doi = {10.1007/11526841},
+ isbn = {978-3-540-27882-5},
+ location = {Newcastle, UK}
+}
+
+@InProceedings{ barnett.ea:spec:2004,
+ author = {Mike Barnett and K. Rustan M. Leino and Wolfram Schulte},
+ abstract = "Spec# is the latest in a long line of work on programming
+ languages and systems aimed at improving the development of
+ correct software. This paper describes the goals and
+ architecture of the Spec# programming system, consisting of
+ the object-oriented Spec# programming language, the Spec#
+ compiler, and the Boogie static program verifier. The
+ language includes constructs for writing specifications
+ that capture programmer intentions about how methods and
+ data are to be used, the compiler emits run-time checks to
+ enforce these specifications, and the verifier can check
+ the consistency between a program and its specifications.",
+ language = {USenglish},
+ title = {The {\Specsharp} programming system: An overview},
+ pages = {49--69},
+ crossref = {barthe.ea:construction:2005},
+ bibkey = {barnett.ea:spec:2004},
+ doi = {10.1007/b105030},
+ acknowledgement={brucker, 2007-02-19},
+ month = may # {~25}
+}
+
+@Proceedings{ barthe.ea:construction:2005,
+ editor = {Gilles Barthe and Lilian Burdy and Marieke Huisman and
+ Jean-Louis Lanet and Traian Muntean},
+ title = {Construction and Analysis of Safe, Secure, and
+ Interoperable Smart Devices (\acs{cassis})},
+ booktitle = {Construction and Analysis of Safe, Secure, and
+ Interoperable Smart Devices (\acs{cassis})},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 3362,
+ year = 2005,
+ isbn = {978-3-540-24287-1},
+ acknowledgement={brucker, 2007-02-19},
+ doi = {10.1007/b105030}
+}
+
+@InProceedings{ jacobs.ea:java:2004,
+ author = {Bart Jacobs and Erik Poll},
+ title = {{Java} Program Verification at {Nijmegen}: Developments
+ and Perspective.},
+ doi = {10.1007/b102118},
+ pages = {134--153},
+ acknowledgement={brucker, 2007-02-19},
+ abstract = {This paper presents a historical overview of the work on
+ Java program verification at the University of Nijmegen
+ (the Netherlands) over the past six years (1997-2003). It
+ describes the development and use of the LOOP tool that is
+ central in this work. Also, it gives a perspective on the
+ field.},
+ crossref = {futatsugi.ea:software:2004}
+}
+
+@Proceedings{ futatsugi.ea:software:2004,
+ editor = {Kokichi Futatsugi and Fumio Mizoguchi and Naoki Yonezaki},
+ title = {Software Security---Theories and Systems (\acs{isss})},
+ booktitle = {Software Security---Theories and Systems (\acs{isss})},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ acknowledgement={brucker, 2007-02-19},
+ volume = 3233,
+ year = 2004,
+ doi = {10.1007/b102118},
+ isbn = {978-3-540-23635-1}
+}
+
+@InProceedings{ meyer.ea:architecture:2000,
+ author = {J{\"o}rg Meyer and Arnd Poetzsch-Heffter},
+ title = {An Architecture for Interactive Program Provers},
+ abstract = {Formal specification and verification techniques can
+ improve the quality of programs by enabling the analysis
+ and proof of semantic program properties. This paper
+ describes the modular architecture of an interactive
+ program prover that we are currently developing for a Java
+ subset. In particular, it discusses the integration of a
+ programming language-specific prover component with a
+ general purpose theorem prover.},
+ pages = {63--77},
+ crossref = {graf.ea:tools:2000}
+}
+
+@Proceedings{ graf.ea:tools:2000,
+ editor = {Susanne Graf and Michael I. Schwartzbach},
+ booktitle = {Tools and Algorithms for the Construction and Analysis of
+ Systems (\acs{tacas})},
+ title = {Tools and Algorithms for the Construction and Analysis of
+ Systems (\acs{tacas})},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 1785,
+ year = 2000,
+ isbn = {3-540-67282-6}
+}
+
+@InProceedings{ markovic.ea:ocl:2006,
+ author = {Sali{\v s}a Markovi{\'c} and Thomas Baar},
+ language = {USenglish},
+ doi = {10.1007/11880240_46},
+ acknowledgement={brucker, 2007-02-19},
+ pages = {661--675},
+ title = {An {\acs{ocl}} Semantics Specified with {\textsc{qvt}}},
+ crossref = {nierstrasz.ea:model:2006},
+ abstract = {Metamodeling became in the last decade a widely accepted
+ tool to describe the (abstract) syntax of modeling
+ languages in a concise, but yet precise way. For the
+ description of the language's semantics, the situation is
+ less satisfactory and formal semantics definitions are
+ still seen as a challenge. In this paper, we propose an
+ approach to specify the semantics of modeling languages in
+ a graphical way. As an example, we describe the evaluation
+ semantics of OCL by transformation rules written in the
+ graphical formalism QVT. We believe that the graphical
+ format of our OCL semantics has natural advantages with
+ respect to understandability compared to existing
+ formalizations of OCL's semantics. Our semantics can also
+ be seen as a reference implementation of an OCL evaluator,
+ because the transformation rules can be executed by any QVT
+ compliant transformation engine.}
+}
+
+@InProceedings{ pons.ea:ocl-based:2006,
+ author = {Claudia Pons and Diego Garcia},
+ title = {An {OCL}-Based Technique for Specifying and Verifying
+ Refinement-Oriented Transformations in {MDE}},
+ booktitle = {MoDELS},
+ year = 2006,
+ pages = {646--660},
+ doi = {10.1007/11880240_45},
+ crossref = {nierstrasz.ea:model:2006}
+}
+
+@InProceedings{ kosiuczenko:specification:2006,
+ author = {Piotr Kosiuczenko},
+ title = {Specification of Invariability in \acs{ocl}},
+ pages = {676--691},
+ doi = {10.1007/11880240_47},
+ crossref = {nierstrasz.ea:model:2006},
+ abstract = {The paradigm of contractual specification provides a
+ transparent way of specifying systems. It clearly
+ distinguishes between client and implementer obligations.
+ One of the best known languages used for this purpose is
+ OCL. Nevertheless, OCL does not provide primitives for a
+ compact specification of what remains unchanged when a
+ method is executed. In this paper, problems with specifying
+ invariability are listed and some weaknesses of existing
+ solutions are pointed out. The question of specifying
+ invariability in OCL is studied and a simple but expressive
+ and flexible extension is proposed. It is shown that this
+ extension has a simple OCL based semantics.}
+}
+
+@Proceedings{ nierstrasz.ea:model:2006,
+ editor = {Oscar Nierstrasz and Jon Whittle and David Harel and
+ Gianna Reggio},
+ title = {Model Driven Engineering Languages and Systems
+ (\acs{models})},
+ booktitle = {Model Driven Engineering Languages and Systems
+ (\acs{models})},
+ address = pub-springer:adr,
+ location = {Genova, Italy},
+ publisher = pub-springer,
+ series = s-lncs,
+ acknowledgement={brucker, 2007-02-19},
+ volume = 4199,
+ year = 2006,
+ doi = {10.1007/11880240},
+ isbn = {978-3-540-45772-5}
+}
+
+@InProceedings{ syme:proving:1999,
+ author = {Don Syme},
+ title = {Proving {Java} Type Soundness},
+ pages = {83--118},
+ crossref = {alves-foss:formal:1999},
+ acknowledgement={brucker, 2007-02-19},
+ abstract = {This chapter describes a machine checked proof of the type
+ soundness of a subset of Java (we call this subset
+ Javatex2html_wrap_inline102). In Chapter 3, a formal
+ semantics for approximately the same subset was presented
+ by Drossopoulou and Eisenbach. The work presented here
+ serves two roles: it complements the written semantics by
+ correcting and clarifying some details; and it demonstrates
+ the utility of formal, machine checking when exploring a
+ large and detailed proof based on operational semantics.},
+ bibkey = {syme:proving:1999}
+}
+
+@InProceedings{ flatt.ea:programmers:1999,
+ author = {Matthew Flatt and Shriram Krishnamurthi and Matthias
+ Felleisen},
+ title = {A Programmer's Reduction Semantics for Classes and
+ Mixins.},
+ doi = {10.1007/3-540-48737-9_7},
+ pages = {241--269},
+ crossref = {alves-foss:formal:1999},
+ acknowledgement={brucker, 2007-02-19},
+ abstract = {While class-based object-oriented programming languages
+ provide a flexible mechanism for re-using and managing
+ related pieces of code, they typically lack linguistic
+ facilities for specifying a uniform extension of many
+ classes with one set of fields and methods. As a result,
+ programmers are unable to express certain abstractions over
+ classes. In this paper we develop a model of class-to-class
+ functions that we refer to as mixins. A mixin function maps
+ a class to an extended class by adding or overriding fields
+ and methods. Programming with mixins is similar to
+ programming with single inheritance classes, but mixins
+ more directly encourage programming to interfaces. The
+ paper develops these ideas within the context of Java. The
+ results are an intuitive model of an essential Java subset;
+ an extension that explains and models mixins; and type
+ soundness theorems for these languages.}
+}
+
+@InProceedings{ drossopoulou.ea:describing:1999,
+ author = {Sophia Drossopoulou and Susan Eisenbach},
+ title = {Describing the Semantics of {Java} and Proving Type
+ Soundness},
+ pages = {41--82},
+ doi = {10.1007/3-540-48737-9_2},
+ crossref = {alves-foss:formal:1999},
+ acknowledgement={brucker, 2007-02-19},
+ abstract = {Java combines the experience from the development of
+ several object oriented languages, such as C++, Smalltalk
+ and CLOS. The philosophy of the language designers was to
+ include only features with already known semantics, and to
+ provide a small and simple language.
+
+ Nevertheless, we feel that the introduction of some new
+ features in Java, as well as the specific combination of
+ features, justifies a study of the Java formal semantics.
+ The use of interfaces, reminiscent of [6,10] is a
+ simplification of the signatures extension for C++ [4] and
+ is - to the best of our knowledge - novel. The mechanism
+ for dynamic method binding is that of C++, but we know of
+ no formal definition. Java adopts the Smalltalk [15]
+ approach whereby all object variables are implicitly
+ pointers.
+
+ Furthermore, although there are a large number of studies
+ of the semantics of isolated programming language features
+ or of minimal programming languages [1,31,34] there have
+ not been many studies of the formal semantics of actual
+ programming languages. In addition, the interplay of
+ features which are very well understood in isolation, might
+ introduce unexpected effects. }
+}
+
+@InProceedings{ oheimb.ea:machine-checking:1999,
+ author = {David von Oheimb and Tobias Nipkow},
+ title = {Machine-Checking the {Java} Specification: Proving
+ Type-Safety},
+ pages = {119--156},
+ crossref = {alves-foss:formal:1999},
+ acknowledgement={brucker, 2007-02-19},
+ bibkey = {oheimb.ea:machine-checking:1999}
+}
+
+@Proceedings{ alves-foss:formal:1999,
+ editor = {Jim Alves-Foss},
+ title = {Formal Syntax and Semantics of {Java}},
+ booktitle = {Formal Syntax and Semantics of {Java}},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 1523,
+ year = 1999,
+ isbn = {3-540-66158-1},
+ acknowledgement={brucker, 2007-02-19},
+ bibkey = {alves-foss:formal:1999}
+}
+
+@InProceedings{ smith.ea:encoding:2002,
+ author = {Graeme Smith and Florian Kamm{\"u}ller and Thomas Santen},
+ title = {Encoding {Object-Z} in {Isabelle}/{\acs{hol}}.},
+ pages = {82--99},
+ doi = {10.1007/3-540-45648-1_5},
+ crossref = {bert.ea:zb:2002},
+ abstract = {In this paper, we present a formalization of the reference
+ semantics of Object-Z in the higher-order logic (HOL)
+ instantiation of the generic theorem prover Isabelle,
+ Isabelle/HOL. This formalization has the effect of both
+ clarifying the semantics and providing the basis for a
+ theorem prover for Object-Z. The work builds on an earlier
+ encoding of a value semantics for object-oriented Z in
+ Isabelle/HOL and a denotational semantics of Object-Z based
+ on separating the internal and external effects of class
+ methods.},
+ keywords = {Object-Z, reference semantics, higher-order logic,
+ Isabelle},
+ acknowledgement={brucker, 2007-02-19}
+}
+
+@Proceedings{ bert.ea:zb:2002,
+ editor = {Didier Bert and Jonathan P. Bowen and Martin C. Henson and
+ Ken Robinson},
+ title = {{ZB} 2002: Formal Specification and Development in {Z} and
+ {B}},
+ booktitle = {{ZB} 2002: Formal Specification and Development in {Z} and
+ {B}},
+ location = {Grenoble, France},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2272,
+ year = 2002,
+ isbn = {3-540-43166-7},
+ acknowledgement={brucker, 2007-02-19},
+ bibkey = {bert.ea:zb:2002}
+}
+
+@InProceedings{ paulson:formulation:1990,
+ author = {Lawrence C. Paulson},
+ title = {A formulation of the simple theory of types (for
+ {Isabelle})},
+ pages = {246--274},
+ doi = {10.1007/3-540-52335-9_58},
+ crossref = {martin-lof.ea:colog-88:1990},
+ acknowledgement={brucker, 2007-02-19},
+ abstract = {Simple type theory is formulated for use with the generic
+ theorem prover Isabelle. This requires explicit type
+ inference rules. There are function, product, and subset
+ types, which may be empty. Descriptions (the eta-operator)
+ introduce the Axiom of Choice. Higher-order logic is
+ obtained through reflection between formulae and terms of
+ type bool. Recursive types and functions can be formally
+ constructed. Isabelle proof procedures are described. The
+ logic appears suitable for general mathematics as well as
+ computational problems. }
+}
+
+@Proceedings{ martin-lof.ea:colog-88:1990,
+ editor = {Per Martin-L{\"o}f and Grigori Mints},
+ title = {\acs{colog}-88},
+ booktitle = {\acs{colog}-88},
+ location = {Tallinn, USSR},
+ publisher = pub-springer,
+ acknowledgement={brucker, 2007-02-19},
+ address = pub-springer:adr,
+ doi = {10.1007/3-540-52335-9},
+ series = s-lncs,
+ volume = 417,
+ year = 1990,
+ isbn = {3-540-52335-9}
+}
+
+@InProceedings{ beckert.ea:dynamic:2006,
+ author = {Bernhard Beckert and Andr{\'e} Platzer},
+ title = {Dynamic Logic with Non-rigid Functions.},
+ pages = {266--280},
+ acknowledgement={brucker, 2007-02-19},
+ doi = {10.1007/11814771_23},
+ abstract = {We introduce a dynamic logic that is enriched by non-rigid
+ functions, i.e., functions that may change their value from
+ state to state (during program execution), and we present a
+ (relatively) complete sequent calculus for this logic. In
+ conjunction with dynamically typed object enumerators,
+ non-rigid functions allow to embed notions of
+ object-orientation in dynamic logic, thereby forming a
+ basis for verification of object-oriented programs. A
+ semantical generalisation of substitutions, called state
+ update, which we add to the logic, constitutes the central
+ technical device for dealing with object aliasing during
+ function modification. With these few extensions, our
+ dynamic logic captures the essential aspects of the complex
+ verification system KeY and, hence, constitutes a
+ foundation for object-oriented verification with the
+ principles of reasoning that underly the successful KeY
+ case studies.},
+ crossref = {furbach.ea:automated:2006}
+}
+
+@Proceedings{ furbach.ea:automated:2006,
+ editor = {Ulrich Furbach and Natarajan Shankar},
+ doi = {10.1007/11814771},
+ title = {Automated Reasoning (\acs{ijcar})},
+ booktitle = {Automated Reasoning (\acs{ijcar})},
+ location = {Seattle, WA},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ acknowledgement={brucker, 2007-02-19},
+ series = s-lncs,
+ volume = 4130,
+ year = 2006,
+ isbn = {978-3-540-37187-8}
+}
+
+@InProceedings{ yatake.ea:implementing:2005,
+ author = {Kenro Yatake and Toshiaki Aoki and Takuya Katayama},
+ title = {Implementing Application-Specific Object-Oriented Theories
+ in {\acs{hol}}},
+ acknowledgement={brucker, 2007-02-19},
+ doi = {10.1007/11560647_33},
+ pages = {501--516},
+ abstract = {This paper presents a theory of Object-Oriented concepts
+ embedded shallowly in HOL for the verification of OO
+ analysis models. The theory is application-specific in the
+ sense that it is automatically constructed depending on the
+ type information of the application. This allows objects to
+ have attributes of arbitrary types, making it possible to
+ verify models using not only basic types but also highly
+ abstracted types specific to the target domain. The theory
+ is constructed by definitional extension based on the
+ operational semantics of a heap memory model, which
+ guarantees the soundness of the theory. This paper mainly
+ focuses on the implementation details of the theory.},
+ crossref = {hung.ea:theoretical:2005}
+}
+
+@Proceedings{ hung.ea:theoretical:2005,
+ editor = {Dang Van Hung and Martin Wirsing},
+ title = {Theoretical Aspects of Computing---\acs{ictac} 2005},
+ booktitle = {Theoretical Aspects of Computing---\acs{ictac} 2005},
+ location = {Hanoi, Vietnam},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ doi = {10.1007/11560647},
+ series = s-lncs,
+ acknowledgement={brucker, 2007-02-19},
+ volume = 3722,
+ year = 2005,
+ isbn = {3-540-29107-5}
+}
+
+@InProceedings{ aspinall:proof:2000,
+ author = {David Aspinall},
+ title = {{P}roof {G}eneral: A Generic Tool for Proof Development},
+ acknowledgement={brucker, 2007-02-19},
+ pages = {38--42},
+ crossref = {graf.ea:tools:2000-b},
+ abstract = {This note describes Proof General, a tool for developing
+ machine proofs with an interactive proof assistant.
+ Interaction is based around a proof script, which is the
+ target of a proof development. Proof General provides a
+ powerful user-interface with relatively little effort,
+ alleviating the need for a proof assistant to provide its
+ own GUI, and providing a uniform appearance for diverse
+ proof assistants.
+
+ Proof General has a growing user base and is currently used
+ for several interactive proof systems, including Coq, LEGO,
+ and Isabelle. Support for others is on the way. Here we
+ give a brief overview of what Proof General does and the
+ philosophy behind it; technical details are available
+ elsewhere. The program and user documentation are available
+ on the web at http://www.dcs.ed.ac.uk/home/proofgen.}
+}
+
+@InProceedings{ beckert.ea:many-valued:1992,
+ author = {Bernhard Beckert and Stefan Gerberding and Reiner
+ H{\"a}hnle and Werner Kernig},
+ title = {The Many-Valued Tableau-Based Theorem Prover {\threeTAP}},
+ acknowledgement={brucker, 2007-02-19},
+ pages = {758--760},
+ bibkey = {beckert.ea:many-valued:1992},
+ crossref = {kapur:automated:1992},
+ doi = {10.1007/3-540-55602-8_219}
+}
+
+@Proceedings{ kapur:automated:1992,
+ editor = {Deepak Kapur},
+ title = {Automated Deduction---\acs{cade}-11},
+ booktitle = {Automated Deduction---\acs{cade}-11},
+ location = {Saratoga Springs, \acs{ny}, \acs{usa}},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ doi = {10.1007/3-540-55602-8},
+ series = s-lncs,
+ volume = 607,
+ year = 1992,
+ acknowledgement={brucker, 2007-02-19},
+ isbn = {978-3-540-55602-2}
+}
+
+@Article{ ahrendt.ea:key:2005,
+ bibkey = {ahrendt.ea:key:2005},
+ author = {Wolfgang Ahrendt and Thomas Baar and Bernhard Beckert and
+ Richard Bubel and Martin Giese and Reiner H\"ahnle and
+ Wolfram Menzel and Wojciech Mostowski and Andreas Roth and
+ Steffen Schlager and Peter H. Schmitt},
+ title = {The {\KeY} Tool},
+ doi = {10.1007/s10270-004-0058-x},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ journal = j-sosym,
+ volume = 4,
+ number = 1,
+ year = 2005,
+ pages = {32--54},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Article{ cengarle.ea:ocl:2004,
+ journal = j-sosym,
+ volume = 3,
+ pages = {9--30},
+ number = 1,
+ year = 2004,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ issn = {1619-1366},
+ doi = {10.1007/s10270-003-0035-9},
+ title = {{\acs{ocl}} 1.4/5 vs. 2.0 Expressions Formal semantics and
+ expressiveness},
+ author = {Mar{\`\i}a Victoria Cengarle and Alexander Knapp},
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {cengarle.ea:ocl:2004}
+}
+
+@Article{ toval.ea:emerging:2003,
+ journal = j-sosym,
+ pages = {248--261},
+ volume = 2,
+ number = 4,
+ year = 2003,
+ publisher = pub-springer,
+ doi = {10.1007/s10270-003-0031-0},
+ address = pub-springer:adr,
+ issn = {1619-1366},
+ month = dec,
+ title = {Emerging {\acs{ocl}} tools},
+ author = {Jos{\'e} Ambrosio Toval and V{\`\i}ctor Requena and
+ Jos{\'e} Luis Fern{\'a}ndez},
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {toval.ea:emerging:2003}
+}
+
+@Article{ bubel.ea:formal:2005,
+ author = {Richard Bubel and Reiner H\"{a}hnle},
+ title = {Integration of informal and formal development of
+ object-oriented safety-critical software.},
+ year = 2005,
+ journal = j-sttt,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ issn = {1433-2779},
+ volume = 7,
+ number = 3,
+ language = {USenglish},
+ doi = {10.1007/s10009-004-0166-5},
+ pages = {197--211},
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {bubel.ea:formal:2005}
+}
+
+@Proceedings{ stepney.ea:object:1992,
+ abstract = {This collection of papers draws together a variety of
+ approaches for adding OO concepts and structuring
+ capability to the Z formal specification language. Each
+ approach is used to specify the same two problems, to allow
+ a comparison. },
+ editor = {Susan Stepney and Rosalind Barden and David Cooper},
+ isbn = {3-540-19778-8},
+ language = {USenglish},
+ public = {yes},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = {Workshops in Computing},
+ topic = {formalism},
+ title = {Object Orientation in {Z}},
+ year = 1992,
+ keywords = {Object Orientation, Z},
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {stepney.ea:object:1992}
+}
+
+@InProceedings{ hamie.ea:reflections:1998,
+ bibkey = {hamie.ea:reflections:1998},
+ author = {Ali Hamie and Franco Civello and John Howse and Stuart
+ Kent and Richard Mitchell},
+ title = {{Reflections on the Object Constraint Language}},
+ year = 1998,
+ doi = {10.1007/b72309},
+ topic = {formalism},
+ acknowledgement={brucker, 2007-04-23},
+ pages = {162--172},
+ crossref = {bezivin.ea:unified:1999},
+ abstract = {The \acf{ocl}, which forms part of the \acs{uml} set of
+ modelling notations, is a precise, textual language for
+ expressing constraints that cannot be shown
+ diagrammatically in \acs{uml}. This paper reflects on a
+ number of aspects of the syntax and semantics of the
+ \acs{ocl}, and makes proposals for clarification or
+ extension. Specifically, the paper suggests that: the
+ concept of flattening collections of collections is
+ unnecessary, state models should be connectable to class
+ models, defining object creation should be made more
+ convenient, \acs{ocl} should be based on a 2-valued logic,
+ set subtraction should be covered more fully, and a "let"
+ feature should be introduced. }
+}
+
+@Proceedings{ bezivin.ea:unified:1999,
+ editor = {Jean B{\'e}zivin and Pierre-Alain Muller},
+ doi = {10.1007/b72309},
+ booktitle = {The Unified Modeling Language. \guillemotleft
+ \acs{uml}\guillemotright'98: Beyond the Notation},
+ title = {The Unified Modeling Language. \guillemotleft
+ \acs{uml}\guillemotright'98: Beyond the Notation},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ acknowledgement={brucker, 2007-04-23},
+ series = s-lncs,
+ volume = 1618,
+ year = 1999,
+ isbn = {3-540-66252-9}
+}
+
+@Book{ guttag.ea:larch:1993,
+ author = {John V. Guttag and James J. Horning},
+ title = {{Larch}: Languages and Tools for Formal Specification},
+ publisher = pub-springer-ny,
+ address = pub-springer-ny:adr,
+ series = {Texts and Monographs in Computer Science},
+ year = 1993,
+ isbn = {0-387-94006-5},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Article{ beckert.ea:refinement:2005,
+ title = {Refinement and Retrenchment for Programming Language Data
+ Types},
+ author = {Bernhard Beckert and Steffen Schlager},
+ journal = j-fac,
+ volume = 17,
+ number = 4,
+ acknowledgement={brucker, 2007-04-23},
+ pages = {423--442},
+ year = 2005,
+ doi = {10.1007/s00165-005-0073-x},
+ publisher = pub-springer,
+ address = pub-springer:adr
+}
+
+@Article{ nipkow:winskel:1998,
+ author = {Tobias Nipkow},
+ title = {Winskel is (almost) Right: Towards a Mechanized Semantics
+ Textbook},
+ publisher = pub-springer,
+ journal = j-fac,
+ volume = 10,
+ number = 2,
+ doi = {10.1007/s001650050009},
+ pages = {171--186},
+ abstract = {We present a formalization of the first 100 pages of
+ Winskel's textbook `The Formal Semantics of Programming
+ Languages' in the theorem prover Isabelle/\acs{hol}: 2
+ operational, 2 denotational, 2 axiomatic semantics, a
+ verification condition generator, and the necessary
+ soundness, completeness and equivalence proofs, all for a
+ simple imperative programming language.},
+ acknowledgement={brucker, 2007-04-23},
+ year = 1998,
+ bibkey = {nipkow:winskel:1998}
+}
+
+@InCollection{ dupuy.ea:using:2000,
+ author = {Sophie Dupuy and Ang{\`e}s Front-Conte and Christophe
+ Saint-Marcel},
+ chapter = 6,
+ title = {Using \acs{uml} with a Behaviour-Driven Method},
+ page = {97--112},
+ acknowledgement={brucker, 2007-04-23},
+ crossref = {frappier.ea:software:2000}
+}
+
+@Book{ frappier.ea:software:2000,
+ editor = {Marc Frappier and Henri Habrias},
+ title = {Software Specification Methods: An Overview Using a Case
+ Study},
+ acknowledgement={brucker, 2007-04-23},
+ publisher = pub-springer-london,
+ address = pub-springer-london:adr,
+ year = 2000,
+ isbn = {1-85233-353-7},
+ series = {Formal Approaches to Computing and Information
+ Technology}
+}
+
+@InProceedings{ hamie.ea:interpreting:1998,
+ bibkey = {hamie.ea:interpreting:1998},
+ author = {Ali Hamie and John Howse and Stuart Kent},
+ title = {Interpreting the {Object Constraint Language}},
+ abstract = {The \acf{ocl}, which forms part of the \acs{uml} 1.1. set
+ of modelling notations is a precise, textual language for
+ expressing constraints that cannot be shown in the standard
+ diagrammatic notation used in \acs{uml}. A semantics for
+ \acs{ocl} lays the foundation for building CASE tools that
+ support integrity checking of the whole \acs{uml} models,
+ not just the component expressed using \acs{ocl}. This
+ paper provides a semantics for \acs{ocl}, at the same time
+ providing a semantics for classes, associations, attributes
+ and states. },
+ pages = {288--295},
+ ee = {http://csdl.computer.org/comp/proceedings/apsec/1998/9183/00/91830288abs.htm}
+ ,
+ doi = {10.1109/apsec.1998.733731},
+ keywords = {OCL},
+ acknowledgement={brucker, 2007-04-23},
+ topic = {formalism},
+ crossref = {ieee:apsec:1998}
+}
+
+@Proceedings{ ieee:apsec:1998,
+ bibkey = {ieee:apsec:1998},
+ booktitle = PROC # { Asia Pacific Conference in Software
+ Engineering (\acs{apsec})},
+ title = PROC # { Asia Pacific Conference in Software
+ Engineering (\acs{apsec})},
+ publisher = pub-ieee,
+ address = pub-ieee:adr,
+ acknowledgement={brucker, 2007-04-23},
+ year = 1998,
+ isbn = {0-8186-9183-2}
+}
+
+@InProceedings{ mandel.ea:ocl:1999,
+ author = {Luis Mandel and Mar{\`i}a Victoria Cengarle},
+ bibkey = {mandel.ea:ocl:1999},
+ language = {USenglish},
+ topic = {formalism},
+ public = {yes},
+ title = {On the expressive power of {\acs{ocl}}},
+ acknowledgement={brucker, 2007-04-23},
+ timestamp = 962971498,
+ abstract = {This paper examines the expressive power of \acs{ocl} in
+ terms of navigability and computability. First the
+ expressive power of \acs{ocl} is compared with the
+ relational calculus; it is showed that \acs{ocl} is not
+ equivalent to the relational calculus. Then an algorithm
+ computing the transitive closure of a binary relation
+ operation that cannot be encoded in the relational calculus
+ is expressed in \acs{ocl}. Finally the equivalence of
+ \acs{ocl} with a Turing machine is pondered.},
+ pages = {854--874},
+ crossref = {wing.ea:world:1999},
+ ee = {http://link.springer.de/link/service/series/0558/bibs/1708/17080854.htm}
+
+}
+
+@Proceedings{ wing.ea:world:1999,
+ editor = {Jeannette M. Wing and Jim Woodcock and Jim Davies},
+ booktitle = {World Congress on Formal Methods in the Development of
+ Computing Systems (FM)},
+ title = {World Congress on Formal Methods in the Development of
+ Computing Systems (FM)},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ acknowledgement={brucker, 2007-04-23},
+ series = s-lncs,
+ volume = 1708,
+ year = 1999,
+ isbn = {3-540-66587-0}
+}
+
+@Book{ spivey:z-notation:1992,
+ bibkey = {spivey:z-notation:1992},
+ author = {J. M. Spivey},
+ title = {The {Z} Notation: A Reference Manual},
+ publisher = pub-prentice,
+ address = pub-prentice:adr,
+ edition = {2nd},
+ length = 150,
+ year = 1992,
+ isbn = {0-139-78529-9},
+ acknowledgement={brucker, 2007-04-23},
+ abstract = {This is a revised edition of the first widely available
+ reference manual on Z originally published in 1989. The
+ book provides a complete and definitive guide to the use of
+ Z in specifying information systems, writing specifications
+ and designing implementations. \par Contents: Tutorial
+ introduction; Background; The Z language; The mathematical
+ tool-kit; Sequential systems; Syntax summary; Changes from
+ the first edition; Glossary.}
+}
+
+@Book{ jones:vdm:1990,
+ bibkey = {jones:vdm:1990},
+ author = {Cliff B.\ Jones},
+ title = {Systematic Software Development Using \acs{vdm}},
+ publisher = pub-prentice,
+ address = pub-prentice:adr,
+ year = 1990,
+ size = 333,
+ edition = {2nd},
+ note = {0-13-880733-7},
+ abstract = {This book deals with the Vienna Development Method. The
+ approach explains formal (functional) specifications and
+ verified design with an emphasis on the study of proofs in
+ the development process.},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Article{ liskov.ea:behavioral:1994,
+ bibkey = {liskov.ea:behavioral:1994},
+ abstract = {The use of hierarchy is an important component of
+ object-oriented design.Hierarchy allows the use of type
+ families, in whichhigher level supertypes capture the
+ behavior that all of their subtypes havein common. For this
+ methodology to be effective,it is necessary to have a clear
+ understanding of how subtypes and supertypesare related.
+ This paper takes the position thatthe relationship should
+ ensure that any property proved about supertypeobjects also
+ holds for its subtype objects. It presentstwo ways of
+ defining the subtype relation, each of which meets this
+ criterion,and each of which is easy for programmers touse.
+ The subtype relation is based on the specifications of the
+ sub- and supertypes; the paper presents a way of
+ specifyingtypes that makes it convenient to define the
+ subtype relation. The paper alsodiscusses the ramifications
+ of this notion ofsubtyping on the design of type
+ families.},
+ author = {Barbara H. Liskov and Jeannette M. Wing},
+ journal = j-toplas,
+ month = nov,
+ pages = {1811--1841},
+ issn = {0164-0925},
+ keywords = {languages, verficiation},
+ language = {USenglish},
+ number = 6,
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ doi = {10.1145/197320.197383},
+ public = {yes},
+ title = {A behavioral notion of subtyping},
+ volume = 16,
+ year = 1994,
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Book{ winskel:semantics:1993,
+ bibkey = {winskel:semantics:1993},
+ author = {Glynn Winskel},
+ title = {The Formal Semantics of Programming Languages},
+ publisher = pub-mit,
+ address = pub-mit:adr,
+ isbn = {0-262-23169-7},
+ pages = 384,
+ year = 1993,
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Book{ andrews:introduction:2002,
+ author = {Peter B. Andrews},
+ title = {Introduction to Mathematical Logic and Type Theory: To
+ Truth through Proof},
+ year = 2002,
+ isbn = {1-402-00763-9},
+ edition = {2nd},
+ publisher = pub-kluwer,
+ address = pub-kluwer:adr,
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {andrews:introduction:2002}
+}
+
+@PhDThesis{ santen:mechanized:1999,
+ author = {Thomas Santen},
+ title = {A Mechanized Logical Model of {Z} and Object-Oriented
+ Specification},
+ school = {Technical University Berlin},
+ year = 1999,
+ month = jun,
+ annote = {Also available as book: Shaker Verlag, Aachen. ISBN:
+ 3826576500},
+ bibkey = {santen:mechanized:1999},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Book{ kleene:mathematics:1971,
+ bibkey = {kleene:mathematics:1971},
+ author = {Stephen C. Kleene},
+ title = {Introduction to Meta Mathematics},
+ publisher = {Wolters-Noord\-hoff Publishing},
+ address = {Amsterdam},
+ isbn = {0-7204-2103-9},
+ year = 1971,
+ note = {Originally published by Van Nostrand, 1952},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Book{ gordon.ea:hol:1993,
+ bibkey = {gordon.ea:hol:1993},
+ author = {Mike J. C. Gordon and Tom F. Melham},
+ title = {Introduction to \acs{hol}: a theorem proving environment
+ for higher order logic},
+ publisher = pub-cup,
+ address = pub-cup:adr,
+ year = 1993,
+ pages = 472,
+ isbn = {0-521-44189-7},
+ month = jul,
+ abstract = {Currently being applied to a wide variety of problems,
+ Higher-Order Logic (\acs{hol}) is a proof development
+ system intended for applications to both hardware and
+ software. This self-contained description contains a
+ tutorial introduction and most of the material needed for
+ day-to-day work.},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@PhDThesis{ richters:precise:2002,
+ author = {Mark Richters},
+ title = {A Precise Approach to Validating {\acs{uml}} Models and
+ {\acs{ocl}} Constraints},
+ school = {Universit{\"a}t Bremen},
+ year = 2002,
+ address = {Logos Verlag, Berlin, \acs{biss} Monographs, No. 14},
+ isbn = {3-89722-842-4},
+ abstract = {We present a precise approach that allows an analysis and
+ validation of \acs{uml} models and OCL constraints. We
+ focus on models and constraints specified in the analysis
+ and early design stage of a software development process.
+ For this purpose, a suitable subset of \acs{uml}
+ corresponding to information that is usually represented in
+ class diagrams is identified and formally defined. This
+ basic modeling language provides a context for all OCL
+ constraints. We define a formal syntax and semantics of OCL
+ types, operations, expressions, invariants, and
+ pre-/postconditions. We also give solutions for problems
+ with the current OCL definition and discuss possible
+ extensions. A metamodel for OCL is introduced that defines
+ the abstract syntax of OCL expressions and the structure of
+ types and values. The metamodel approach allows a seamless
+ integration with the \acs{uml} metamodeling architecture
+ and makes the benefits of a precise OCL definition easier
+ accessible. The OCL metamodel also allows to define
+ context-sensitive conditions for well-formed OCL
+ expressions more precisely. These conditions can now be
+ specified with OCL whereas they previously were specified
+ only informally. In order to demonstrate the practical
+ applicability of our work, we have realized substantial
+ parts of it in a tool supporting the validation of models
+ and constraints. Design specifications can be ``executed''
+ and animated thus providing early feedback in an iterative
+ development process. Our approach offers novel ways for
+ checking user data against specifications, for automating
+ test procedures, and for checking CASE tools for standards
+ conformance. Therefore, this work contributes to the goal
+ of improving the overall quality of software systems by
+ combining theoretical and practical techniques.},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Booklet{ cc:cc-part3:2006,
+ bibkey = {cc:cc-part3:2006},
+ key = {Common Criteria},
+ institution = {Common Criteria},
+ language = {USenglish},
+ month = sep,
+ year = 2006,
+ public = {yes},
+ title = {Common Criteria for Information Technology Security
+ Evaluation (Version 3.1), {Part} 3: Security assurance
+ components},
+ note = {Available as document
+ \href{http://www.commoncriteriaportal.org/public/files/CCPART3V3.1R1.pdf}
+ {CCMB-2006-09-003}},
+ number = {CCMB-2006-09-003},
+ acknowledgement={brucker, 2007-04-24}
+}
+
+@Booklet{ omg:ocl:1997,
+ bibkey = {omg:ocl:1997},
+ key = omg,
+ abstract = {This document introduces and defines the Object Constraint
+ Language (\acs{ocl}), a formal language to express side
+ effect-free constraints. Users of the Unified Modeling
+ Language and other languages can use \acs{ocl} to specify
+ constraints and other expressions attached to their models.
+ \acs{ocl} was used in the \acs{uml} Semantics document to
+ specify the well-formedness rules of the \acs{uml}
+ metamodel. Each well-formedness rule in the static
+ semantics sections in the \acs{uml} Semantics document
+ contains an \acs{ocl} expression, which is an invariant for
+ the involved class. The grammar for \acs{ocl} is specified
+ at the end of this document. A parser generated from this
+ grammar has correctly parsed all the constraints in the
+ \acs{uml} Semantics document, a process which improved the
+ correctness of the specifications for \acs{ocl} and \acs{uml}.},
+ institution = omg,
+ language = {USenglish},
+ month = sep,
+ note = {Available as \acs{omg} document
+ \href{http://www.omg.org/cgi-bin/doc?ad/97-08-08}
+ {ad/97-08-08}},
+ keywords = {\acs{uml}, OCL},
+ topic = {formalism},
+ public = {yes},
+ title = {Object Constraint Language Specification (Version 1.1)},
+ year = 1997,
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Booklet{ omg:xmi:2000,
+ bibkey = {omg:xmi:2000},
+ key = omg,
+ abstract = {The main purpose of XMI is to enable easy interchange of
+ metadata between modeling tools (based on the
+ \acs{omg}-\acs{uml}) and metadata repositories
+ (\acs{omg}-MOF based) in distributed heterogeneous
+ environments. XMI integrates three key industry standards:
+ XML, \acs{uml}, MOF.},
+ publisher = omg,
+ language = {USenglish},
+ month = nov,
+ year = 2000,
+ keywords = {\acs{uml}, XML, XMI},
+ topic = {formalism},
+ public = {yes},
+ title = {\acs{omg} \acs{xml} Metadata Interchange (\acs{xmi})
+ Specification (Version 1.1)},
+ note = {Available as \acs{omg} document
+ \href{http://www.omg.org/cgi-bin/doc?formal/00-11-02}
+ {formal/00-11-02}},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Booklet{ omg:ocl:2003,
+ bibkey = {omg:ocl:2003},
+ key = omg,
+ abstract = {This document introduces and defines the Object Constraint
+ Language (OCL), a formal language to express side
+ effect-free constraints. Users of the Unified Modeling
+ Language and other languages can use OCL to specify
+ constraints and other expressions attached to their models.
+ OCL was used in the \acs{uml} Semantics document to specify
+ the well-formedness rules of the \acs{uml} metamodel. Each
+ well-formedness rule in the static semantics sections in
+ the \acs{uml} Semantics document contains an OCL
+ expression, which is an invariant for the involved class.
+ The grammar for OCL is specified at the end of this
+ document. A parser generated from this grammar has
+ correctly parsed all the constraints in the \acs{uml}
+ Semantics document, a process which improved the
+ correctness of the specifications for OCL and \acs{uml}.},
+ publisher = omg,
+ language = {USenglish},
+ month = oct,
+ keywords = {\acs{uml}, OCL},
+ topic = {formalism},
+ public = {yes},
+ note = {Available as \acs{omg} document
+ \href{http://www.omg.org/cgi-bin/doc?ptc/03-10-14}
+ {ptc/03-10-14}},
+ title = {\acs{uml} 2.0 \acs{ocl} Specification},
+ year = 2003,
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Booklet{ omg:uml:2003,
+ bibkey = {omg:uml:2003},
+ key = omg,
+ abstract = {The Unified Modeling Language (\acs{uml}) provides system
+ architects working on object analysis and design with one
+ consistent language for specifying, visualizing,
+ constructing, and documenting the artifacts of software
+ systems, as well as for business modeling.This
+ specification represents the convergence of best practices
+ in the object-technology industry. \acs{uml} is the proper
+ successor to the object modeling languages of three
+ previouslyleading object-oriented methods (Booch, OMT, and
+ OOSE). The \acs{uml} is the union of thesemodeling
+ languages and more, since it includes additional
+ expressiveness to handle modelingproblems that these
+ methods did not fully address.One of the primary goals of
+ \acs{uml} is to advance the state of the industry by
+ enabling objectvisual modeling tool interoperability.
+ However, in order to enable meaningful exchange ofmodel
+ information between tools, agreement on semantics and
+ notation is required. \acs{uml} meets the following
+ requirements: \begin{enumerate} \item Formal definition of
+ a common object analysis and design (OA\&D) metamodel to
+ representthe semantics of OA\&D models, which include
+ static models, behavioral models, usagemodels, and
+ architectural models. \item IDL specifications for
+ mechanisms for model interchange between OA\&D tools.
+ Thisdocument includes a set of IDL interfaces that support
+ dynamic construction and traversal ofa user model. \item
+ readable notation for representing OA\&D models.
+ \end{enumerate} This document defines the \acs{uml}
+ notation, an elegant graphic syntax for consistently
+ expressing the \acs{uml}'s richsemantics. Notation is an
+ essential part of OA\&D modeling and the \acs{uml}.},
+ publisher = omg,
+ language = {USenglish},
+ month = mar,
+ year = 2003,
+ note = {Available as \acs{omg} document
+ \href{http://www.omg.org/cgi-bin/doc?formal/03-03-01}
+ {formal/03-03-01}},
+ keywords = {\acs{uml}, OCL},
+ topic = {formalism},
+ public = {yes},
+ title = {Unified Modeling Language Specification (Version 1.5)},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Booklet{ omg:ocl:2006,
+ bibkey = {omg:ocl:2006},
+ key = omg,
+ abstract = {This document introduces and defines the Object Constraint
+ Language (OCL), a formal language to express side
+ effect-free constraints. Users of the Unified Modeling
+ Language and other languages can use OCL to specify
+ constraints and other expressions attached to their models.
+ OCL was used in the \acs{uml} Semantics document to specify
+ the well-formedness rules of the \acs{uml} metamodel. Each
+ well-formedness rule in the static semantics sections in
+ the \acs{uml} Semantics document contains an OCL
+ expression, which is an invariant for the involved class.
+ The grammar for OCL is specified at the end of this
+ document. A parser generated from this grammar has
+ correctly parsed all the constraints in the \acs{uml}
+ Semantics document, a process which improved the
+ correctness of the specifications for OCL and \acs{uml}.},
+ publisher = omg,
+ language = {USenglish},
+ month = apr,
+ keywords = {\acs{uml}, OCL},
+ topic = {formalism},
+ note = {Available as \acs{omg} document
+ \href{http://www.omg.org/cgi-bin/doc?formal/06-05-01}
+ {formal/06-05-01}},
+ public = {yes},
+ title = {\acs{uml} 2.0 \acs{ocl} Specification},
+ year = 2006,
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Booklet{ omg:uml:2005,
+ bibkey = {omg:uml:2005},
+ key = omg,
+ publisher = omg,
+ language = {USenglish},
+ note = {Available as \acs{omg} document
+ \href{http://www.omg.org/cgi-bin/doc?formal/05-07-04}
+ {formal/05-07-04}},
+ keywords = {\acs{uml}},
+ topic = {formalism},
+ public = {yes},
+ title = {\acs{uml} 2.0 Superstructure Specification},
+ year = 2005,
+ month = jul,
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@PhDThesis{ oheimb:analyzing:2001,
+ author = {David von Oheimb},
+ title = {Analyzing {J}ava in {Isabelle/\acs{hol}}: Formalization,
+ Type Safety and {H}oare Logic},
+ school = {Technische Universit\"{a}t M\"{u}nchen},
+ year = 2001,
+ crclassification={D.2.4, D.3.1, F.3.1},
+ crgenterms = {Languages, Verification, Theory},
+ keywords = {Java, formalization, operational semantics, type
+ soundness, axiomatic semantics, Isabelle/HOL},
+ abstract = {This thesis deals with machine-checking a large
+ sublanguage of sequential Java, covering nearly all
+ features, in particular the object-oriented ones. It shows
+ that embedding such a language in a theorem prover and
+ deducing practically important properties is meanwhile
+ possible and explains in detail how this can be achieved.
+ We formalize the abstract syntax, and the static semantics
+ including the type system and well-formedness conditions,
+ as well as an operational (evaluation) semantics of the
+ language. Based on these definitions, we can express
+ soundness of the type system, an important design goal
+ claimed to be reached by the designers of Java, and prove
+ that type safety holds indeed. Moreover, we give an
+ axiomatic semantics of partial correctness for both
+ statements and (side-effecting) expressions. We prove the
+ soundness of this semantics relative to the operational
+ semantics, and even prove completeness. We further give a
+ small but instructive application example. A direct outcome
+ of this work is the confirmation that the design and
+ specification of Java (or at least the subset considered)
+ is reasonable, yet some omissions in the language
+ specification and possibilities for generalizing the design
+ can be pointed out. The second main contribution is a sound
+ and complete Hoare logic, where the soundness proof for our
+ Hoare logic gives new insights into the role of type
+ safety. To our knowledge, this logic is the first one for
+ an object-oriented language that has been proved complete.
+ By-products of this work are a new general technique for
+ handling side-effecting expressions and their results, the
+ discovery of the strongest possible rule of consequence,
+ and a new rule for flexible handling of mutual recursion.
+ All definitions and proofs have been done fully formally
+ with the interactive theorem prover Isabelle/HOL,
+ representing one of its major applications. This approach
+ guarantees not only rigorous definitions, but also gives
+ maximal confidence in the results obtained. Thus this
+ thesis demonstrates that machine-checking the design of an
+ important non-trivial programming language and conducting
+ meta-theory on it entirely within a theorem proving system
+ has become a reality. },
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {oheimb:analyzing:2001}
+}
+
+@Article{ chiarada.ea:improving:2006,
+ bibkey = {chiarada.ea:improving:2006},
+ language = {USenglish},
+ public = {yes},
+ title = {Improving the {\acs{ocl}} Semantics Definition by Applying
+ Dynamic Meta Modeling and Design Patterns},
+ author = {Juan Mart{\'\i}n Chiarad{\'\i}a and Claudia Pons},
+ editor = {Birgith Demuth and Dan Chiorean and Martin Gogolla and Jos
+ Warmer},
+ issn = {1863-2122},
+ volume = 5,
+ year = 2006,
+ acknowledgement={brucker, 2007-04-23},
+ journal = j-eceasst
+}
+
+@PhDThesis{ schirmer:verification:2006,
+ author = {Norbert Schirmer},
+ title = {Verification of Sequential Imperative Programs in
+ {I}sabelle/{\acs{hol}}},
+ school = {Technische Universit\"at M\"unchen},
+ year = 2006,
+ acknowledgement={brucker, 2007-04-23},
+ abstract = {The purpose of this thesis is to create a verification
+ environment for sequential imperative programs. First a
+ general language model is proposed, which 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.
+
+ For this language a Hoare logic for both partial and total
+ correctness is developed and on top of it a verification
+ condition generator is implemented. The Hoare logic is
+ designed to allow the integration of program analysis or
+ software model checking into the verification.
+
+ To demonstrate the continuity to a real programming
+ language a subset of C is embedded into the verification
+ environment.
+
+ The whole work is developed in the theorem prover Isabelle.
+ Therefore the correctness is machine-checked and in
+ addition the rich infrastructure of the general purpose
+ theorem prover Isabelle can be employed for the
+ verification of imperative programs.
+
+ }
+}
+
+@Article{ harel.ea:meaningful:2004,
+ author = {David Harel and Bernhard Rumpe},
+ title = {Meaningful Modeling: What's the Semantics of
+ ``Semantics''?},
+ journal = {\acs{ieee} Computer},
+ year = 2004,
+ pages = {64--72},
+ volume = 37,
+ issn = {0018-9162},
+ number = 10,
+ month = oct,
+ publisher = pub-ieee,
+ address = pub-ieee:adr,
+ doi = {10.1109/MC.2004.172},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Book{ hahnle:automated:1994,
+ author = {Reiner H{\"a}hnle},
+ title = {Automated Deduction in Multiple-valued Logics},
+ publisher = pub-oxford,
+ address = pub-oxford:adr,
+ disvolume = 10,
+ disseries = {International Series of Monographs on Computer Science},
+ year = 1994,
+ acknowledgement={brucker, 2007-04-23},
+ isbn = {0-19-853989-4},
+ bibkey = {hahnle:automated:1994}
+}
+
+@Book{ vigano:labelled:2000,
+ author = {Luca Vigan{\`o}},
+ title = {Labelled Non-Classical Logics},
+ year = 2000,
+ language = {USenglish},
+ publisher = pub-kluwer,
+ address = pub-kluwer:adr,
+ isbn = {0-7923-7749-4},
+ cover = {2000/lncl.png},
+ abstract = {The subject of the book is the development and
+ investigation of a framework for the modular and uniform
+ presentation and implementation of non-classical logics, in
+ particular modal and relevance logics. Logics are presented
+ as labelled deduction systems, which are proved to be sound
+ and complete with respect to the corresponding Kripke-style
+ semantics. We investigate the proof theory of our systems,
+ and show them to possess structural properties such as
+ normalization and the subformula property, which we exploit
+ not only to establish advantages and limitations of our
+ approach with respect to related ones, but also to give, by
+ means of a substructural analysis, a new proof-theoretic
+ method for investigating decidability and complexity of
+ (some of) the logics we consider. All of our deduction
+ systems have been implemented in the generic theorem prover
+ Isabelle, thus providing a simple and natural environment
+ for interactive proof development.},
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {vigano:labelled:2000}
+}
+
+@Book{ gabbay:labelled:1997,
+ author = {Dov M. Gabbay},
+ title = {Labelled Deductive Systems},
+ publisher = pub-oxford,
+ address = pub-oxford:adr,
+ series = {Oxford Logic Guides},
+ year = 1997,
+ isbn = {978-0-198-53833-2},
+ volume = 1,
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {gabbay:labelled:1997}
+}
+
+@Book{ warmer.ea:ocl2:2003,
+ bibkey = {warmer.ea:ocl2:2003},
+ author = {Jos Warmer and Anneke Kleppe},
+ abstract = {This book covers \acs{ocl} 2.0},
+ keywords = {OCL, \acs{uml}},
+ isbn = {0-321-17936-6},
+ edition = {2nd},
+ language = {USenglish},
+ public = {yes},
+ topic = {formalism},
+ publisher = pub-awl,
+ address = pub-awl:adr,
+ title = {The Object Constraint Language: Getting Your Models Ready
+ for \acs{mda}},
+ year = 2003,
+ month = aug,
+ num_pages = 240,
+ price = {39.99},
+ cover = {2003/ocl2.png},
+ currency = {USD},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Book{ smith:object:2000,
+ author = {Graeme Smith},
+ title = {The Object {Z} Specification Language},
+ publisher = pub-kluwer,
+ address = pub-kluwer:adr,
+ year = 2000,
+ isbn = {0-7923-8684-1},
+ pages = 160,
+ abstract = {bject-Z is an object-oriented extension of the formal
+ specification language Z. It adds, to Z, notions of classes
+ and objects, and inheritance and polymorphism. By extending
+ Z's semantic basis, it enables the specification of systems
+ as collections of independent objects in which self and
+ mutual referencing are possible.
+
+ The Object-Z Specification Language presents a
+ comprehensive description of Object-Z including discussions
+ of semantic issues, definitions of all language constructs,
+ type rules and other rules of usage, specification
+ guidelines, and a full concrete syntax. It will enable you
+ to confidently construct Object-Z specifications and is
+ intended as a reference manual to keep by your side as you
+ use and learn to use Object-Z.
+
+ The Object-Z Specification Language is suitable as a
+ textbook or as a secondary text for a graduate level
+ course, and as a reference for researchers and
+ practitioners in industry.},
+ series = {Advances in Formal Methods Series},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Book{ meyer:object-oriented:1988,
+ author = {Bertrand Meyer},
+ title = {Object-Oriented Software Construction},
+ acknowledgement={brucker, 2007-04-23},
+ publisher = pub-prentice,
+ address = pub-prentice:adr,
+ year = 1988,
+ isbn = {0-13-629031-0},
+ descriptor = {Eiffel, Objekt-orientiert, Software}
+}
+
+@Article{ meyer.ea:interactive:1999,
+ title = {Interactive Verification Environments for Object-Oriented
+ Languages },
+ author = {J{\"o}rg Meyer and Arnd Poetzsch-Heffter },
+ journal = j-ucs,
+ volume = 5,
+ url = {http://www.jucs.org/jucs_5_3/interactive_verification_environments_for}
+ ,
+ number = 3,
+ pages = {208--225 },
+ year = 1999,
+ doi = {10.1007/3-540-46419-0_6},
+ acknowledgement={brucker, 2007-04-23},
+ abstract = {Formal specification and verification techniques can
+ improve the quality of object-oriented software by enabling
+ semantic checks and certification of properties. To be
+ applicable to object-oriented programs, they have to cope
+ with subtyping, aliasing via object references, as well as
+ abstract and recursive methods. For mastering the resulting
+ complexity, mechanical aid is needed. The article outlines
+ the specific technical requirements for the specification
+ and verification of object-oriented programs. Based on
+ these requirements, it argues that verification of
+ OO-programs should be done interactively and develops an
+ modular architecture for this task. In particular, it shows
+ how to integrate interactive program verification with
+ existing universal interactive theorem provers, and
+ explains the new developed parts of the architecture. To
+ underline the general approach, we describe interesting
+ features of our prototype implementation.}
+}
+
+@Article{ church:types:1940,
+ author = {Church, Alonzo},
+ title = {A formulation of the simple theory of types},
+ journal = j-sl,
+ year = 1940,
+ volume = 5,
+ number = 2,
+ month = jun,
+ pages = {56--68},
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {church:types:1940}
+}
+
+@Article{ muller.ea:holcf:1999,
+ author = {Olaf M\"uller and Tobias Nipkow and David von Oheimb and
+ Oskar Slotosch},
+ title = {\acs{holcf} = \acs{hol} + \acs{lcf}},
+ journal = j-fp,
+ number = 2,
+ doi = {10.1017/S095679689900341X},
+ volume = 9,
+ pages = {191--223},
+ year = 1999,
+ abstract = {HOLCF is the definitional extension of Church's
+ Higher-Order Logic with Scott's Logic for Computable
+ Functions that has been implemented in the theorem prover
+ Isabelle. This results in a flexible setup for reasoning
+ about functional programs. HOLCF supports standard domain
+ theory (in particular fixedpoint reasoning and recursive
+ domain equations) but also coinductive arguments about lazy
+ datatypes. This paper describes in detail how domain theory
+ is embedded in HOL and presents applications from
+ functional programming, concurrency and denotational
+ semantics. },
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {muller.ea:holcf:1999}
+}
+
+@Article{ huet:programtransformations:1978,
+ author = {G{\'e}rard Huet and Bernard Lang},
+ title = {Proving and Applying Program Transformations Expressed
+ with Second Order Patterns},
+ journal = {Acta Informatica},
+ volume = 11,
+ year = 1978,
+ pages = {31--55},
+ number = 1,
+ doi = {10.1007/BF00264598},
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {huet:programtransformations:1978}
+}
+
+@PhDThesis{ kyas:verifying:2006,
+ author = {Marcel Kyas},
+ title = {Verifying {\acs{ocl}} Specifications of {\acs{uml}}
+ Models: Tool Support and Compositionality},
+ school = {University of Leiden},
+ year = 2006,
+ acknowledgement={brucker, 2007-04-23},
+ abstract = {The Unified Modelling Language (\acs{uml}) and the Object
+ Constraint Language (OCL) serve as specification languages
+ for embedded and real-time systems used in a
+ safety-critical environment. In this dissertation class
+ diagrams, object diagrams, and OCL constraints are
+ formalised. The formalisation serves as foundation for a
+ translation of class diagrams, state machines, and
+ constraints into the theorem prover PVS. This enables the
+ formal verification of models defined in a subset of
+ \acs{uml} using the interactive theorem prover. The type
+ system of OCL makes writing specifications difficult while
+ the model is still under development. To overcome this
+ difficulty a new type system is proposed, based on
+ intersection types, union types, and bounded operator
+ abstraction. To reduce the complexity of the model and to
+ increase the structure of the specification, compositional
+ reasoning is used. The introduction of history variables
+ allows compositional specifications. Proof rules support
+ compositional reasoning. The feasibility of the presented
+ approach is demonstrated by two case-studies. The first one
+ is the "Sieve of Eratosthenes" and the second one is a part
+ of the medium altitude reconnaissance system (MARS)
+ deployed in F-16 fighters of the Royal Dutch Air Force.},
+ isbn = {3-86541-142-8},
+ publisher = {Lehmanns Media},
+ address = {Berlin},
+ file = {papers/2006/kyas-verifying-2006.tgz}
+}
+
+@Article{ bertino.ea:object-oriented:1992,
+ author = {Elisa Bertino and Mauro Negri and Giuseppe Pelagatti and
+ Licia Sbattella},
+ title = {Object-Oriented Query Languages: The Notion and the
+ Issues},
+ journal = j-tkde,
+ volume = 4,
+ number = 3,
+ doi = {10.1109/69.142014},
+ library = {DINF-K},
+ year = 1992,
+ pages = {223--237},
+ abstract = {The authors describe how the characteristics of an
+ object-oriented data model, such as object identity,
+ complex object structure, methods, and class hierarchies,
+ have an impact on the design of a query language. They also
+ point out major differences with respect to relational
+ query languages. The discussion is supported through the
+ definition of OOPC, a formal object-oriented query language
+ based on predicate calculus, which incorporates in a
+ consistent formal notation most features of existing
+ object-oriented query languages.},
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {bertino.ea:object-oriented:1992}
+}
+
+@Article{ beckert.ea:leant-ap:1995,
+ author = {Bernhard Beckert and Joachim Posegga},
+ title = {{\leanTAP}: Lean Tableau-based Deduction},
+ journal = j-ar,
+ volume = 15,
+ number = 3,
+ pages = {339--358},
+ year = 1995,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ doi = {10.1007/BF00881804},
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {beckert.ea:leant-ap:1995}
+}
+
+@Article{ jackson:alloy:2002,
+ author = {Daniel Jackson},
+ title = {{Alloy}: a lightweight object modelling notation},
+ journal = j-tosem,
+ volume = 11,
+ number = 2,
+ year = 2002,
+ issn = {1049-331X},
+ pages = {256--290},
+ doi = {10.1145/505145.505149},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={brucker, 2007-04-23},
+ abstract = {Alloy is a little language for describing structural
+ properties. It offers a declaration syntax compatible with
+ graphical object models, and a set-based formula syntax
+ powerful enough to express complex constraints and yet
+ amenable to a fully automatic semantic analysis. Its
+ meaning is given by translation to an even smaller
+ (formally defined) kernel. This paper presents the language
+ in its entirety, and explains its motivation, contributions
+ and deficiencies. }
+}
+
+@Article{ kobryn:uml:1999,
+ author = {Cris Kobryn},
+ title = {{\acs{uml}} 2001: a standardization odyssey},
+ journal = j-cacm,
+ volume = 42,
+ number = 10,
+ year = 1999,
+ issn = {0001-0782},
+ pages = {29--37},
+ doi = {10.1145/317665.317673},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ language = {USEnglish},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@Article{ basin.ea:natural:1998,
+ author = {David A. Basin and Se{\'a}n Matthews and Luca Vigan{\`o}},
+ title = {Natural Deduction for Non-Classical Logics},
+ journal = {Studia Logica},
+ doi = {10.1023/A:1005003904639},
+ year = 1998,
+ volume = 60,
+ number = 1,
+ publisher = pub-springer,
+ address = pub-acm:adr,
+ issn = {0039-3215},
+ acknowledgement={brucker, 2007-04-23},
+ pages = {119--160},
+ language = {USenglish},
+ note = {Special issue on \emph{Natural Deduction} edited by Frank
+ Pfenning and Wilfried Sieg},
+ abstract = {We present a framework for machine implementation of
+ families of non-classical logics with Kripke-style
+ semantics. We decompose a logic into two interacting parts,
+ each a natural deduction system: a base logic of labelled
+ formulae, and a theory of labels characterizing the
+ properties of the Kripke models. By appropriate
+ combinations we capture both partial and complete fragments
+ of large families of non-classical logics such as modal,
+ relevance, and intuitionistic logics. Our approach is
+ modular and supports uniform proofs of correctness and
+ proof normalization. We have implemented our work in the
+ Isabelle Logical Framework. }
+}
+
+@InProceedings{ nipkow.ea:java-light:1998,
+ author = {Tobias Nipkow and David von Oheimb},
+ title = {{Java$_{{\ell}ight}$} is Type-Safe---Definitely},
+ booktitle = {\acs{acm} Symp.\ Principles of Programming Languages
+ (\acs{popl})},
+ publisher = pub-acm,
+ isbn = {0-89791-979-3},
+ address = pub-acm:adr,
+ year = 1998,
+ pages = {161--170},
+ doi = {10.1145/268946.268960},
+ location = {San Diego, California, United States},
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {nipkow.ea:java-light:1998}
+}
+
+@Article{ bierman.ea:mj:2003,
+ author = {Gavin M. Bierman and Matthew J. Parkinson},
+ title = {Effects and effect inference for a core {Java} calculus},
+ journal = j-entcs,
+ volume = 82,
+ number = 7,
+ year = 2003,
+ doi = {10.1016/S1571-0661(04)80803-X},
+ pages = {1--26},
+ booktitle = {WOOD2003, Workshop on Object Oriented Developments
+ (Satellite Event of ETAPS 2003)},
+ acknowledgement={brucker, 2007-04-23},
+ bibkey = {bierman.ea:mj:2003},
+ publisher = pub-elsevier,
+ address = pub-elsevier:adr
+}
+
+@Article{ chiorean.ea:ensuring:2004,
+ author = {Dan Chiorean and Mihai Pasca and Adrian C{\^a}rcu and
+ Cristian Botiza and Sorin Moldovan},
+ title = {Ensuring \acs{uml} Models Consistency Using the \acs{ocl}
+ Environment.},
+ journal = j-entcs,
+ volume = 102,
+ booktitle = PROC # { the Workshop, \acs{ocl} 2.0 -- Industry
+ Standard or Scientific Playground?},
+ year = 2004,
+ acknowledgement={brucker, 2007-04-24},
+ pages = {99--110},
+ doi = {10.1016/j.entcs.2003.09.005},
+ publisher = pub-elsevier,
+ address = pub-elsevier:adr
+}
+
+@Article{ rauch.ea:formalizing:2003,
+ abstract = {We present a formal model of the Java two's-complement
+ integral arithmetics. The model directly formalizes the
+ arithmetic operations as given in the Java Language
+ Specification (JLS). The algebraic properties of these
+ definitions are derived. Underspecifications and
+ ambiguities in the JLS are pointed out and clarified. The
+ theory is formally analyzed in Isabelle/HOL, that is,
+ machine-checked proofs for the ring properties and
+ divisor/remainder theorems etc. are provided. This work is
+ suited to build the framework for machine-supported
+ reasoning over arithmetic formulae in the context of Java
+ source-code verification.},
+ author = {Nicole Rauch and Burkhart Wolff},
+ journal = j-entcs,
+ doi = {10.1016/S1571-0661(04)80808-9},
+ acknowledgement={brucker, 2007-04-24},
+ publisher = pub-elsevier,
+ address = pub-elsevier:adr,
+ title = {Formalizing {Java}'s Two's-Com\-ple\-ment Integral Type in
+ {Isabelle}/\acs{hol}},
+ volume = 80,
+ year = 2003,
+ pages = {1--18},
+ booktitle = {International Workshop on Formal Methods for Industrial
+ Critical Systems (\ac{fmics})}
+}
+
+@Article{ kyas.ea:formalizing:2004,
+ journal = j-entcs,
+ author = {Kyas, Marcel and Fecher, Harald and de Boer, Frank S. and
+ van der Zwaag, Mark and Hooman, Jozef and Arons, Tamarah
+ and Kugler, Hillel},
+ title = {Formalizing {\acs{uml}} Models and {\acs{ocl}} Constraints
+ in {\acs{pvs}}},
+ booktitle = {Workshop on Semantic Foundations of Engineering Design
+ Languages (\acs{sfedl})},
+ year = 2004,
+ doi = {10.1016/j.entcs.2004.09.027 },
+ pages = {39--47},
+ acknowledgement={brucker, 2007-04-24},
+ publisher = pub-elsevier,
+ address = pub-elsevier:adr
+}
+
+@Proceedings{ grabowski.ea:formal:2005,
+ editor = {Jens Grabowski and Brian Nielsen},
+ title = {Formal Approaches to Software Testing (\textsc{fates})},
+ booktitle = {Formal Approaches to Software Testing (\textsc{fates})},
+ series = s-lncs,
+ volume = 3395,
+ year = 2005,
+ isbn = {3-540-25109-X},
+ doi = {10.1007/b106767},
+ acknowledgement={brucker, 2007-04-24},
+ publisher = pub-springer,
+ address = pub-springer:adr
+}
+
+@InCollection{ kerber.ea:tableau:1996,
+ author = {Manfred Kerber and Michael Kohlhase},
+ title = {A Tableau Calculus for Partial Functions},
+ pages = {21--49},
+ abstract = {Even though it is not very often admitted, partial
+ functions do play a significant role in many practical
+ applications of deduction systems. Kleene has already given
+ a semantic account of partial functions using a
+ three-valued logic decades ago, but there has not been a
+ satisfactory mechanization. Recent years have seen a
+ thorough investigation of the framework of many-valued
+ truth-functional logics. However, strong Kleene logic,
+ where quantification is restricted and therefore not
+ truth-functional, does not fit the framework directly. We
+ solve this problem by applying recent methods from sorted
+ logics. This paper presents a tableau calculus that
+ combines the proper treatment of partial functions with the
+ efficiency of sorted calculi.},
+ acknowledgement={brucker, 2007-04-24},
+ bibkey = {kerber.ea:tableau:1996},
+ booktitle = {Collegium Logicum---Annals of the Kurt-G{\"o}del-Society},
+ volume = 2,
+ publisher = pub-springer-ny,
+ address = pub-springer-ny:adr,
+ isbn = {3-211-82796-X},
+ year = 1996
+}
+
+@InCollection{ paulson:generic:1996,
+ author = {Lawrence C. Paulson},
+ title = {Generic automatic proof tools},
+ pages = {23--47},
+ abstract = {This paper explores a synthesis between two distinct
+ traditions in automated reasoning: resolution and
+ interaction. In particular it discusses Isabelle, an
+ interactive theorem prover based upon a form of resolution.
+ It aims to demonstrate the value of proof tools that,
+ compared with traditional resolution systems, seem absurdly
+ limited. Isabelle's classical reasoner searches for proofs
+ using a tableau approach. The reasoner is generic: it
+ accepts rules proved in applied theories, involving defined
+ connectives. New constants are not reduced to first-order
+ logic; the reasoner},
+ acknowledgement={brucker, 2007-04-24},
+ bibkey = {paulson:generic:1996},
+ booktitle = {Automated reasoning and its applications: essays in honor
+ of {Larry Wos}},
+ year = 1997,
+ editor = {Robert Veroff},
+ publisher = pub-mit,
+ address = pub-mit:adr,
+ isbn = {978-0-262-22055-2}
+}
+
+@InCollection{ nipkow:order-sorted:1993,
+ author = {Tobias Nipkow},
+ title = {Order-Sorted Polymorphism in {Isabelle}},
+ booktitle = {Workshop on Logical Environments},
+ editor = {G\'erard Huet and Gordon Plotkin},
+ publisher = pub-cup,
+ address = pub-cup:adr,
+ year = 1993,
+ location = {Edinburgh, Scotland},
+ pages = {164--188},
+ acknowledgement={brucker, 2007-04-24},
+ isbn = {0-521-43312-6},
+ bibkey = {nipkow:order-sorted:1993}
+}
+
+@InCollection{ hahnle:tableaux:1999,
+ author = {Reiner H\"ahnle},
+ booktitle = {Handbook of Tableau Methods},
+ editor = {Marcello D'Agostino and Dov Gabbay and Reiner H\"ahnle and
+ Joachim Posegga},
+ isbn = {978-0-792-35627-1},
+ publisher = pub-kluwer,
+ address = pub-kluwer:adr,
+ title = {Tableaux for Many-Valued Logics},
+ pages = {529--580},
+ year = 1999,
+ public = {no},
+ mynote = {Postscript-File nicht weitergeben!},
+ abstract = {This article reports on research done in the intersection
+ between many-valued logics and logical calculi related to
+ tableaux. A lot of important issues in many-valued logic,
+ such as algebras arising from many-valued logic,
+ many-valued function minimization, philosophical topics, or
+ applications are not discussed here; for these, we refer
+ the reader to general monographs and overviews such as
+ [Rosser and Turquette, 1952; Rescher, 1969; Urquhart, 1986;
+ Bolc and Borowik, 1992; Malinowski, 1993; Hahnle, 1994;
+ Panti, to appear] . More questionable, perhaps, than the
+ omissions is the need for a handbook chapter on tableaux
+ for many-valued logics in the first place.},
+ bibkey = {hahnle:tableaux:1999},
+ acknowledgement={brucker, 2007-04-24}
+}
+
+@InCollection{ leavens.ea:jml:1999,
+ author = {Gary T. Leavens and Albert L. Baker and Clyde Ruby},
+ title = {{JML}: A Notation for Detailed Design},
+ booktitle = {Behavioral Specifications of Businesses and Systems},
+ publisher = pub-kluwer,
+ address = pub-kluwer:adr,
+ editor = {Haim Kilov and Bernhard Rumpe and Ian Simmonds},
+ pages = {175--188},
+ year = 1999,
+ isbn = {978-0-7923-8629-2},
+ acknowledgement={brucker, 2007-04-24}
+}
+
+@InCollection{ paulson:fixedpoint:2000,
+ author = {Lawrence C. Paulson},
+ pages = {187--211},
+ title = {A fixedpoint approach to (co)inductive and (co)datatype
+ definitions},
+ acknowledgement={brucker, 2007-04-24},
+ abstract = {This paper presents a fixedpoint approach to inductive
+ definitions. In- stead of using a syntactic test such as
+ ``strictly positive,'' the approach lets definitions
+ involve any operators that have been proved monotone. It is
+ conceptually simple, which has allowed the easy
+ implementation of mutual recursion and iterated
+ definitions. It also handles coinductive definitions:
+ simply replace the least fixedpoint by a greatest
+ fixedpoint. The method has been implemented in two of
+ Isabelle's logics, zf set theory and higher-order logic. It
+ should be applicable to any logic in which the
+ Knaster-Tarski theorem can be proved. Examples include
+ lists of n elements, the accessible part of a relation and
+ the set of primitive recursive functions. One example of a
+ coinductive definition is bisimulations for lazy lists.
+ Recursive datatypes are examined in detail, as well as one
+ example of a codatatype: lazy lists. The Isabelle package
+ has been applied in several large case studies, including
+ two proofs of the Church-Rosser theorem and a coinductive
+ proof of semantic consistency. The package can be trusted
+ because it proves theorems from definitions, instead of
+ asserting desired properties as axioms. },
+ bibkey = {paulson:fixedpoint:2000},
+ crossref = {plotkin.ea:proof:2000}
+}
+
+@InCollection{ gordon:from:2000,
+ author = {Mike Gordon},
+ title = {From \acs{lcf} to {\acs{hol}}: a short history},
+ pages = {169--185},
+ acknowledgement={brucker, 2007-04-24},
+ abstract = {The original LCF system was a proof-checking program
+ developed at Stanford University by Robin Milner in 1972.
+ Descendents of LCF now form a thriving paradigm in computer
+ assisted reasoning. Many of the developments of the last 25
+ years have been due to Robin Milner, whose influence on the
+ field of automated reasoning has been diverse and profound.
+ One of the descendents of LCF is HOL, a proof assistant for
+ higher order logic originally developed for reasoning about
+ hardware. The multi-faceted contribution of Robin Milner to
+ the development of HOL is remarkable. Not only did he
+ invent the LCF-approach to theorem proving, but he also
+ designed the ML programming language underlying it and the
+ innovative polymorphic type system used both by ML and the
+ LCF and HOL logics. Code Milner wrote is still in use
+ today, and the design of the hardware verification system
+ LCF_LSM (a now obsolete stepping stone from LCF to HOL) was
+ inspired by Milner's Calculus of Communicating Systems
+ (CCS). },
+ crossref = {plotkin.ea:proof:2000}
+}
+
+@Book{ plotkin.ea:proof:2000,
+ booktitle = {Proof, Language, and Interaction: Essays in Honour of
+ {Robin Milner}},
+ title = {Proof, Language, and Interaction: Essays in Honour of
+ {Robin Milner}},
+ publisher = pub-mit,
+ address = pub-mit:adr,
+ year = 2000,
+ isbn = {978-0-262-16188-6},
+ acknowledgement={brucker, 2007-04-24},
+ editor = {Gordon Plotkin and Colin Stirling and Mads Tofte}
+}
+
+@InCollection{ pfenning:logical:2001,
+ author = {Frank Pfenning},
+ title = {Logical Frameworks},
+ booktitle = {Handbook of Automated Reasoning},
+ editor = {Alan Robinson and Andrei Voronkov},
+ chapter = 17,
+ volume = 2,
+ isbn = {0-444-50812-0},
+ pages = {1063--1147},
+ publisher = pub-elsevier,
+ address = pub-elsevier:adr,
+ year = 2001,
+ acknowledgement={brucker, 2007-04-24},
+ abstract = {The specification of a deductive system usually proceeds
+ in two stages: first we define the syntax of an object
+ language and then the axioms and rules of inference. In
+ order to concentrate on the meanings of expressions we
+ ignore issues of concrete syntax and parsing and
+ concentrate on specifying abstract syntax. Di#erent
+ framework implementations provide di#erent means for
+ customizing the parser in order to embed the desired
+ object-language syntax. As an example throughout this
+ chapter we consider formulations of intuitionistic and
+ classical first-order logic. In order to keep this chapter
+ to a manageable length, we restrict ourselves to the
+ fragment containing implication, negation, and universal
+ quantification. The reader is invited to test his or her
+ understanding by extending the development to include a
+ more complete set of connectives and quantifiers. }
+}
+
+@InProceedings{ pfenning:hoas:1988,
+ author = {Frank Pfenning and Conal Elliot},
+ title = {Higher-Order Abstract Syntax},
+ year = 1988,
+ isbn = {0-89791-269-1},
+ location = {Atlanta, Georgia, United States},
+ doi = {10.1145/53990.54010},
+ pages = {199--208},
+ acknowledgement={brucker, 2007-04-24},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ booktitle = {Conference on Programming Language Design and
+ Implementation (\acs{pldi})},
+ bibkey = {pfenning:hoas:1988}
+}
+
+@InProceedings{ boulton.ea:experience:1993,
+ crossref = {stavridou.ea:international:1993},
+ author = {Richard Boulton and Andrew Gordon and Michael J. C. Gordon
+ and John Harrison and John Herbert and John Van Tassel},
+ title = {Experience with embedding hardware description languages
+ in {\acs{hol}}},
+ bibkey = {boulton.ea:experience:1993},
+ abstract = {The semantics of hardware description languages can be
+ represented in higher order logic. This provides a formal
+ definition that is suitable for machine processing.
+ Experiments are in progress at Cambridge to see whether
+ this method can be the basis of practical tools based on
+ the HOL theorem-proving assistant. Three languages are
+ being investigated: ELLA, Silage and VHDL. The approaches
+ taken for these languages are compared and current progress
+ on building semantically-based theorem-proving tools is
+ discussed.},
+ acknowledgement={brucker, 2007-04-24},
+ pages = {129--156}
+}
+
+@Proceedings{ stavridou.ea:international:1993,
+ editor = {Victoria Stavridou and Thomas F. Melham and Raymond T.
+ Boute},
+ booktitle = PROC # { the International Conference on Theorem
+ Provers in Circuit Design: Theory, Practice and
+ Experience},
+ title = {International Conference on Theorem Provers in Circuit
+ Design: Theory, Practice and Experience (\acs{tpcd})},
+ series = {\acs{ifip} Transactions},
+ volume = {A-10},
+ isbn = {0-444-89686-4},
+ publisher = pub-north,
+ address = pub-north:adr,
+ date = {22--24 June 1993},
+ acknowledgement={brucker, 2007-04-24},
+ year = 1993
+}
+
+@InProceedings{ khoshafian.ea:object:1986,
+ author = {Setrag N. Khoshafian and George P. Copeland},
+ title = {Object identity},
+ booktitle = {Object-oriented programming systems, languages and
+ applications (\acs{oopsla})},
+ year = 1986,
+ isbn = {0-89791-204-7},
+ pages = {406--416},
+ location = {Portland, Oregon, United States},
+ doi = {10.1145/28697.28739},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={brucker, 2007-04-24}
+}
+
+@InProceedings{ melham:package:1992,
+ author = {Thomas F. Melham},
+ title = {A Package for Inductive Relation Definitions in {\HOL}},
+ pages = {350--357},
+ isbn = {0-8186-2460-4},
+ editor = {Myla Archer and Jennifer J. Joyce and Karl N. Levitt and
+ Phillip J. Windley},
+ booktitle = {International Workshop on the {\HOL} Theorem Proving
+ System and its Applications (\acs{tphols})},
+ month = aug,
+ publisher = pub-ieee,
+ address = pub-ieee:adr,
+ year = 1992,
+ acknowledgement={brucker, 2007-04-24},
+ location = {Davis, California, \acs{usa}},
+ bibkey = {melham:package:1992}
+}
+
+@InProceedings{ hahnle:efficient:1994,
+ doi = {10.1109/ismvl.1994.302195},
+ author = {Reiner H\"{a}hnle},
+ booktitle = {International Symposium on Multiple-Valued Logics
+ (\acs{ismvl})},
+ location = {Boston/MA, \acs{usa}},
+ pages = {240--249},
+ isbn = {0-8186-5650-6},
+ publisher = pub-ieee,
+ address = pub-ieee:adr,
+ title = {Efficient Deduction in Many-Valued Logics},
+ year = 1994,
+ abstract = {This paper tries to identify the basic problems
+ encountered in automated theorem proving in many-valued
+ logics and demonstrates to which extent they can be
+ currently solved. To this end a number of recently
+ developed techniques are reviewed. We list the avenues of
+ research in many-valued theorem proving that are in our
+ eyes the most promising.},
+ acknowledgement={brucker, 2007-04-24},
+ bibkey = {hahnle:efficient:1994}
+}
+
+@InProceedings{ nipkow.ea:java:2000,
+ author = {Tobias Nipkow and David von Oheimb and Cornelia Pusch},
+ title = {{$\mu$Java}: Embedding a Programming Language in a Theorem
+ Prover},
+ booktitle = {Foundations of Secure Computation},
+ series = {\acs{nato} Science Series F: Computer and Systems
+ Sciences},
+ volume = 175,
+ year = 2000,
+ publisher = pub-ios,
+ address = pub-ios:adr,
+ isbn = {978-1-58603-015-5},
+ editor = {Friedrich L. Bauer and Ralf Steinbr{\"u}ggen},
+ abstract = {This paper introduces the subset $micro$Java of Java,
+ essentially by omitting everything but classes. The type
+ system and semantics of this language (and a corresponding
+ abstract Machine $micro$JVM) are formalized in the theorem
+ prover Isabelle/\acs{hol}. Type safety both of $micro$Java
+ and the $micro$JVM are mechanically verified.
+
+ To make the paper self-contained, it starts with
+ introductions to Isabelle/\acs{hol} and the art of
+ embedding languages in theorem provers.},
+ pages = {117--144},
+ acknowledgement={brucker, 2007-04-24},
+ bibkey = {nipkow.ea:java:2000}
+}
+
+@InProceedings{ beckert.ea:translating:2002,
+ editor = {Serge Autexier and Heiko Mantel},
+ pages = {113--123},
+ booktitle = {Verification Workshop (\acs{verify})},
+ location = {Copenhagen, Denmark},
+ author = {Bernhard Beckert and Uwe Keller and Peter H. Schmitt},
+ title = {Translating the {O}bject {C}onstraint {L}anguage into
+ First-order Predicate Logic},
+ year = 2002,
+ abstract = {In this paper, we define a translation of \acs{uml} class
+ diagrams with OCL constraints into first-order predicate
+ logic. The goal is logical reasoning about \acs{uml} models.
+
+ We put an emphasis on usability of the formulas resulting
+ from the translation, and we have developed optimisations
+ and heuristics to enhance the efficiency of the theorem
+ proving process.
+
+ The translation has been implemented as part of the KeY
+ system, but our implementation can also be used
+ stand-alone. },
+ acknowledgement={brucker, 2007-04-24},
+ bibkey = {beckert.ea:translating:2002}
+}
+
+@InProceedings{ demuth.ea:generation:2005,
+ author = {Birgit Demuth and Heinrich Hussmann and Ansgar Konermann},
+ title = {Generation of an {\acs{ocl}} 2.0 Parser},
+ booktitle = {Workshop on Tool Support for \acs{ocl} and Related
+ Formalisms---Needs and Trends},
+ location = {Montego Bay, Jamaica, October 4, 2005},
+ pages = {38--52},
+ publisher = {\acs{epfl}},
+ year = 2005,
+ editor = {Thomas Baar},
+ series = {Technical Report LGL-REPORT-2005-001},
+ acknowledgement={brucker, 2007-04-24}
+}
+
+@InProceedings{ aredo:formalizing:1999,
+ author = {Demissie B. Aredo},
+ booktitle = {\acs{oopsla}'99 Workshop on Rigorous Modeling and Analysis
+ with the \acs{uml}: Challenges and Limitations, Denver,
+ Colorado},
+ title = {Formalizing {\acs{uml}} Class Diagrams in {\acs{pvs}}},
+ year = 1999,
+ month = nov,
+ address = {Denver, Colorado, \acs{usa}},
+ acknowledgement={brucker, 2007-04-24}
+}
+
+@InProceedings{ jackson.ea:alcoa:2000,
+ abstract = {Alcoa is a tool for analyzing object models. It has a
+ range of uses. At one end, it can act as a support tool for
+ object model diagrams, checking for consistency of
+ multiplicities and generating sample snapshots. At the
+ other end, it embodies a lightweight formal method in which
+ subtle properties of behaviour can be investigated. Alcoa's
+ input language, Alloy, is a new notation based on Z. Its
+ development was motivated by the need for a notation that
+ is more closely tailored to object models (in the style of
+ \acs{uml}), and more amenable to automatic analysis. Like
+ Z, Alloy supports the description of systems whose state
+ involves complex relational structure. State and
+ behavioural properties are described declaratively, by
+ conjoining constraints. This makes it possible to develop
+ and analyze a model incrementally, with Alcoa investigating
+ the consequences of whatever constraints are given. Alcoa
+ works by translating constraints to boolean formulas, and
+ then applying state-of-the-art SAT solvers. It can analyze
+ billions of states in seconds. },
+ author = {Daniel Jackson and Ian Schechter and Ilya Shlyakhter },
+ booktitle = {International Conference on Software Engineering
+ (\acs{icse})},
+ language = {USenglish},
+ month = jun,
+ public = {yes},
+ doi = {10.1109/ICSE.2000.870482},
+ location = {Limerick, Ireland},
+ isbn = {1-58113-206-9},
+ pages = {730--733},
+ topic = {formalism},
+ keywords = {Aloca, Alloy},
+ title = {{A}lcoa: the {A}lloy Constraint Analyzer },
+ year = 2000,
+ timestamp = 962701274,
+ acknowledgement={none},
+ publisher = pub-acm,
+ address = pub-acm:adr
+}
+
+@Article{ hahnle:many-valued:2005,
+ author = {Reiner H\"{a}hnle},
+ title = {Many-Valued Logic, Partiality, and Abstraction in Formal
+ Specification Languages},
+ journal = {Logic Journal of the \textsc{igpl}},
+ year = 2005,
+ volume = 13,
+ pages = {415--433},
+ month = jul,
+ doi = {10.1093/jigpal/jzi032},
+ number = 4,
+ acknowledgement={brucker, 2007-05-04}
+}
+
+@Booklet{ levens.ea:jml:2007,
+ bibkey = {levens.ea:jml:2007},
+ author = {Gary T. Leavens and Erik Poll and Curtis Clifton and
+ Yoonsik Cheon and Clyde Ruby and David R. Cok and Peter
+ M\"{u}ller and Joseph Kiniry and Patrice Chalin},
+ title = {{\acs{jml}} Reference Manual (Revision 1.2)},
+ month = feb,
+ year = 2007,
+ organization = {Department of Computer Science, Iowa State University.},
+ note = {Available from \url{http://www.jmlspecs.org}},
+ acknowledgement={brucker, 2007-04-23}
+}
+
+@InProceedings{ broy.ea:uml2:2006,
+ bibkey = {broy.ea:uml2:2006},
+ author = {Manfred Broy and Michelle L. Crane and J{\"u}rgen Dingel
+ and Alan Hartman and Bernhard Rumpe and Bran Selic},
+ title = {2nd \acs{uml} 2 Semantics Symposium: Formal Semantics for
+ {\acs{uml}}},
+ doi = {10.1007/978-3-540-69489-2_39},
+ pages = {318--323},
+ abstract = {The purpose of this symposium, held in conjunction with
+ \acs{models} 2006, was to present the current state of
+ research of the UML 2 Semantics Project. Equally important
+ to receiving feedback from an audience of experts was the
+ opportunity to invite researchers in the field to discuss
+ their own work related to a formal semantics for the
+ Unified Modeling Language. This symposium is a follow-on to
+ our first workshop, held in conjunction with ECMDA 2005.},
+ acknowledgement={brucker, 2007-04-23},
+ crossref = {kuhne:models:2006}
+}
+
+@InProceedings{ hafner.ea:towards:2006,
+ author = {Michael Hafner and Muhammad Alam and Ruth Breu},
+ title = {Towards a {MOF/QVT}-Based Domain Architecture for Model
+ Driven Security},
+ booktitle = {MoDELS},
+ year = 2006,
+ pages = {275--290},
+ ee = {10.1007/11880240_20},
+ crossref = {nierstrasz.ea:model:2006}
+}
+
+@Proceedings{ kuhne:models:2006,
+ doi = {10.1007/978-3-540-69489-2},
+ booktitle = {Models in Software Engineering---Workshops and Symposia at
+ \acs{models} 2006},
+ title = {Models in Software Engineering---Workshops and Symposia at
+ \acs{models} 2006},
+ isbn = {978-3-540-69488-5},
+ publisher = pub-springer,
+ paddress = pub-springer:adr,
+ address = {Genua, Italy},
+ volume = 4364,
+ series = s-lncs,
+ year = 2006,
+ acknowledgement={brucker, 2007-04-23},
+ editor = {Thomas K{\"u}hne}
+}
+
+@Book{ russell:introduction:1919,
+ author = {Bertrand Russell},
+ title = {Introduction to Mathematical Philosophy},
+ publisher = {George Allen \& Unwin},
+ year = 1919,
+ acknowledgement={brucker, 2007-04-23},
+ address = {London}
+}
+
+@Article{ bertino.ea:trbac:2001,
+ author = {Elisa Bertino and Piero Andrea Bonatti and Elena Ferrari},
+ title = {TRBAC: A temporal role-based access control model},
+ journal = {ACM Trans. Inf. Syst. Secur.},
+ volume = 4,
+ number = 3,
+ year = 2001,
+ issn = {1094-9224},
+ pages = {191--233},
+ doi = {10.1145/501978.501979},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ tags = {noTAG},
+ clearance = {unclassified},
+ timestap = {2008-05-29}
+}
+
+@Article{ moyer.ea:generalized:2001,
+ title = {Generalized role-based access control},
+ author = {Moyer, M.J. and Abamad, M.},
+ journal = {Distributed Computing Systems, 2001. 21st International
+ Conference on.},
+ year = 2001,
+ month = {Apr},
+ pages = {391--398},
+ keywords = {authorisation, distributed processing, transaction
+ processingGRBAC, JPEG, RBAC, access control, access control
+ decisions, access control models, environment roles,
+ environmental information, expressive power, generalized
+ role based access control, object roles, object type, rich
+ access control policies, security policy, security-relevant
+ characteristics, sensitivity level, subject roles},
+ doi = {10.1109/ICDSC.2001.918969},
+ abstract = {Generalized Role-Based Access Control (GRBAC) is a new
+ paradigm for creating and maintaining rich access control
+ policies. GRBAC leverages and extends the power of
+ traditional role based access control (RBAC) by
+ incorporating subject roles, object roles and environment
+ roles into access control decisions. Subject roles are like
+ traditional RBAC roles: they abstract the security-relevant
+ characteristics of subjects into categories that can be
+ used in defining a security policy. Similarly, object roles
+ abstract the various properties of objects, such as object
+ type (e.g., text, JPEG, executable) or sensitivity level
+ (e.g., classified, top secret) into categories. Environment
+ roles capture environmental information, such as time of
+ day or system load so it can be used to mediate access
+ control. Together, these three types of roles offer
+ flexibility and expressive power, as well as a degree of
+ usability not found in current access control models},
+ tags = {noTAG},
+ clearance = {unclassified},
+ timestap = {2008-05-29}
+}
+
+@InProceedings{ zhang.ea:role-based:2002,
+ author = {Longhua Zhang and Gail-Joon Ahn and Bei-Tseng Chu},
+ title = {A role-based delegation framework for healthcare
+ information systems},
+ booktitle = PROC # { the seventh \acs{acm} symposium on Access
+ control models and technologies (\acs{sacmat})},
+ year = 2002,
+ isbn = {1-58113-496-7},
+ pages = {125--134},
+ location = {Monterey, California, \acs{usa}},
+ doi = {10.1145/507711.507731},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {As organizations implement information strategies that
+ call for sharing access to resources in the networked
+ environment, mechanisms must be provided to protect the
+ resources from adversaries. The proposed delegation
+ framework addresses the issue of how to advocate selective
+ information sharing in role-based systems while minimizing
+ the risks of unauthorized access. We introduce a systematic
+ approach to specify delegation and revocation policies
+ using a set of rules. We demonstrate the feasibility of our
+ framework through policy specification, enforcement, and a
+ proof-of-concept implementation on specific domains, e.g.
+ the healthcare environment. We believe that our work can be
+ applied to organizations that rely heavily on collaborative
+ tasks.},
+ tags = {noTAG},
+ clearance = {unclassified},
+ timestap = {2008-05-29}
+}
+
+@InProceedings{ wilikens.ea:context-related:2002,
+ author = {Marc Wilikens and Simone Feriti and Alberto Sanna and
+ Marcelo Masera},
+ title = {A context-related authorization and access control method
+ based on \acs{rbac}: A case study from the health care
+ domain},
+ booktitle = PROC # { the seventh \acs{acm} symposium on Access
+ control models and technologies (\acs{sacmat})},
+ year = 2002,
+ isbn = {1-58113-496-7},
+ pages = {117--124},
+ location = {Monterey, California, USA},
+ doi = {10.1145/507711.507730},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {This paper describes an application of authorization and
+ access control based on the Role Based Access Control
+ (RBAC) method and integrated in a comprehensive trust
+ infrastructure of a health care application. The method is
+ applied to a health care business process that involves
+ multiple actors accessing data and resources needed for
+ performing clinical and logistics tasks in the application.
+ The notion of trust constituency is introduced as a concept
+ for describing the context of authorisation. In addition,
+ the applied RBAC covers time constraints, hierarchies and
+ multi-level authorization rules for coping with the
+ multi-actor nature and the complexity of the application
+ domain. The DRIVE RBAC model clearly distinguishes between
+ static role assignment to users and dynamic allocation of
+ roles at session time. The paper, while focusing on the
+ authorization and access control approach, also describes
+ how the RBAC functions have been integrated in a trust
+ infrastructure including smart cards.},
+ tags = {noTAG},
+ clearance = {unclassified},
+ timestap = {2008-05-29}
+}
+
+@InProceedings{ ahn.ea:towards:2007,
+ author = {Gail-Joon Ahn and Hongxin Hu},
+ title = {Towards realizing a formal \acs{rbac} model in real
+ systems},
+ booktitle = PROC # { the seventh \acs{acm} symposium on Access
+ control models and technologies (\acs{sacmat})},
+ year = 2007,
+ isbn = {978-1-59593-745-2},
+ pages = {215--224},
+ location = {Sophia Antipolis, France},
+ doi = {10.1145/1266840.1266875},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {There still exists an open question on how formal models
+ can be fully realized in the system development phase. The
+ Model Driven Development (MDD) approach has been recently
+ introduced to deal with such a critical issue for building
+ high assurance software systems.
+
+ There still exists an open question on how formal models
+ can be fully realized in the system development phase. The
+ Model Driven Development (MDD) approach has been recently
+ introduced to deal with such a critical issue for building
+ high assurance software systems.
+
+ The MDD approach focuses on the transformation of
+ high-level design models to system implementation modules.
+ However, this emerging development approach lacks an
+ adequate procedure to address security issues derived from
+ formal security models. In this paper, we propose an
+ empirical framework to integrate security model
+ representation, security policy specification, and
+ systematic validation of security model and policy, which
+ would be eventually used for accommodating security
+ concerns during the system development. We also describe
+ how our framework can minimize the gap between security
+ models and the development of secure systems. In addition,
+ we overview a proof-of-concept prototype of our tool that
+ facilitates existing software engineering mechanisms to
+ achieve the above-mentioned features of our framework.},
+ tags = {noTAG},
+ clearance = {unclassified},
+ timestap = {2008-05-29}
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%% un-checked entries
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@Book{ woodcock.ea:using:1996,
+ abstract = {This book contains enough material for three complete
+ courses of study. It provides an introduction to the world
+ of logic, sets and relations. It explains the use of the
+ Znotation in the specification of realistic systems. It
+ shows how Z specifications may be refined to produce
+ executable code; this is demonstrated in a selection of
+ casestudies.This book is both authoritative and
+ comprehensive. It strikes the right balance between the
+ formality of mathematics and the practical needs of
+ industrial softwaredevelopment. It is faithful to the draft
+ ISO standard for Z. It covers the essentials of
+ specification, refinement, and proof, revealing techniques
+ never previouslypublished.},
+ author = {Jim Woodcock and Jim Davies},
+ price = {\$37.95},
+ length = 391,
+ isbn = {0-13-948472-8},
+ language = {USenglish},
+ public = {yes},
+ publisher = {Prentice Hall},
+ title = {Using {Z}: {S}pecification, {R}efinement, and {P}roof},
+ series = {Prentice Hall International Series in Computer Science},
+ topic = {formalism},
+ keywords = {formal methods, Z},
+ library = {FAW (25/91): 91: CD/3.2/125},
+ url = {http://softeng.comlab.ox.ac.uk/usingz/},
+ year = 1996,
+ timestamp = 962966715,
+ acknowledgement={none},
+ bibkey = {woodcock.ea:using:1996}
+}
+
+@InProceedings{ dick.ea:testing:1993,
+ bibkey = {dick.ea:testing:1993},
+ author = {Jeremy Dick and Alain Faivre},
+ title = {Automating the Generation and Sequencing of Test Cases
+ from Model-Based Specications},
+ pages = {268--284},
+ booktitle = {Formal Methods Europe 93: Industrial-Strength Formal
+ Methods},
+ editor = {J.C.P. Woodcock and P.G. Larsen},
+ month = apr,
+ year = 1993,
+ volume = 670,
+ series = s-lncs,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ acknowledgement={none}
+}
+
+@Article{ grieskamp.ea:instrumenting:2004,
+ author = {Wolfgang Grieskamp and Nikolai Tillmann and Margus
+ Veanes},
+ booktitle = {Third International Conference on Quality Software: QSIC
+ 2003},
+ title = {Instrumenting scenarios in a model-driven development
+ environment},
+ journal = {Information and Software Technology},
+ year = 2004,
+ number = 15,
+ volume = 46,
+ pages = {1027--1036},
+ doi = {10.1016/j.infsof.2004.07.007},
+ abstract = {SpecExplorer is an integrated environment for model-driven
+ development of .NET software. In this paper we discuss how
+ scenarios can be described in SpecExplorer's modeling
+ language, Spec#, and how the SpecExplorer tool can be used
+ to validate those scenarios by various means.},
+ acknowledgement={none},
+ bibkey = {grieskamp.ea:instrumenting:2004}
+}
+
+@Book{ abrial:event-b:2009,
+ bibkey = {abrial:event-b:2009},
+ title = {Modeling in Event-B: System and Software Design},
+ publisher = {Cambridge University Press},
+ year = 2009,
+ author = {Jean-Raymond Abrial},
+ acknowledgement={none},
+ address = {New York, \acs{ny}, \acs{usa}}
+}
+
+@Book{ abrial:b-book:1996,
+ bibkey = {abrial:b-book:1996},
+ author = {Jean-Raymond Abrial},
+ title = {The {B-Book}: assigning programs to meanings},
+ year = 1996,
+ isbn = {0-521-49619-5},
+ publisher = {Cambridge University Press},
+ acknowledgement={none},
+ address = {New York, \acs{ny}, \acs{usa}}
+}
+
+@TechReport{ leino.ea:escjava:2000,
+ abstract = {The Compaq Extended Static Checker for Java (ESC/Java) is
+ a programming tool that attempts to find common run-time
+ errors in Java programs by static analysis of the program
+ text. Users can control the amount and kinds of checking
+ that ESC/Java performs by annotating their programs with
+ specially formatted comments called pragmas. This manual is
+ designed to serve both as an introduction to ESC/Java and
+ as a reference manual. It starts by providing an overview
+ of ESC/Java through an illustrative example of its use and
+ a summary of its features, and then goes on to document all
+ the pragmas supported by ESC/Java and all the kinds of
+ warnings that it generates. Appendices provide a brief
+ sketch of ESC/Java's implementation, information about
+ obtaining ESC/Java, and some discussion of its
+ limitations},
+ author = {K. Rustan M. Leino and Greg Nelson and James B. Saxe},
+ institution = {Compaq Systems Research Center},
+ language = {USenglish},
+ month = oct,
+ public = {yes},
+ title = {{\acs{esc}}/{Java} User's Manual},
+ url = {http://gatekeeper.dec.com/pub/DEC/SRC/technical-notes/abstracts/src-tn-2000-002.html}
+ ,
+ number = {SRC-2000-002},
+ year = 2000,
+ keywords = {Java},
+ topic = {tools},
+ acknowledgement={none},
+ bibkey = {leino.ea:escjava:2000}
+}
+
+@Book{ kleppe.ea:mda:2003,
+ bibkey = {kleppe.ea:mda:2003},
+ title = {\acs{mda} Explained. The Model Driven Architecture:
+ Practice and Promise},
+ acknowledgement={none},
+ publisher = {Addison-Wesley},
+ year = 2003,
+ author = {Anneke Kleppe and Jos Warmer and Wim Bast}
+}
+
+@Article{ schmidt:mde:2006,
+ author = {Douglas C. Schmidt},
+ title = {Guest Editor's Introduction: Model-Driven Engineering},
+ journal = {Computer},
+ volume = 39,
+ number = 2,
+ acknowledgement={none},
+ year = 2006,
+ issn = {0018-9162},
+ pages = {25--31},
+ doi = {10.1109/MC.2006.58},
+ publisher = {IEEE Computer Society},
+ address = {Los Alamitos, \acs{ca}, \acs{usa}}
+}
+
+@InCollection{ gaudel:testing:1995,
+ author = {Marie Claude Gaudel},
+ title = {Testing can be formal, too},
+ year = 1995,
+ booktitle = {\textsc{tapsoft}'95: Theory and Practice of Software
+ Development},
+ isbn = {3-540-59293-8},
+ address = pub-springer:adr,
+ paddress = {Heidelberg, Germany},
+ pages = {82--96},
+ publisher = pub-springer,
+ series = s-lncs,
+ number = 915,
+ editor = {Peter D. Mosses and Mogens Nielsen and Michael I.
+ Schwartzbach},
+ acknowledgement={none},
+ bibkey = {gaudel:testing:1995}
+}
+
+@InProceedings{ jurjens.ea:specification-based:2001,
+ author = {Jan J{\"u}rjens and Guido Wimmel},
+ title = {Specification-Based Testing of Firewalls},
+ booktitle = {Ershov Memorial Conference},
+ year = 2001,
+ pages = {308--316},
+ crossref = {bjorner.ea:perspectives:2001},
+ acknowledgement={none}
+}
+
+@Proceedings{ bjorner.ea:perspectives:2001,
+ editor = {Dines Bj{\o}rner and Manfred Broy and Alexandre V.
+ Zamulin},
+ title = {Perspectives of System Informatics, 4th International
+ Andrei Ershov Memorial Conference, PSI 2001, Akademgorodok,
+ Novosibirsk, Russia, July 2-6, 2001, Revised Papers},
+ booktitle = {Ershov Memorial Conference},
+ publisher = pub-springer,
+ adress = pub-springer:adr,
+ series = s-lncs,
+ volume = 2244,
+ year = 2001,
+ isbn = {3-540-43075-X},
+ acknowledgement={none}
+}
+
+@InProceedings{ bishop.ea:rigorous:2005,
+ author = {Steve Bishop and Matthew Fairbairn and Michael Norrish and
+ Peter Sewell and Michael Smith and Keith Wansbrough},
+ title = {Rigorous specification and conformance testing techniques
+ for network protocols, as applied to TCP, UDP, and
+ sockets},
+ booktitle = {SIGCOMM},
+ year = 2005,
+ pages = {265--276},
+ doi = {10.1145/1080091.1080123},
+ crossref = {guerin.ea:proceedings:2005},
+ acknowledgement={none}
+}
+
+@Proceedings{ guerin.ea:proceedings:2005,
+ editor = {Roch Gu{\'e}rin and Ramesh Govindan and Greg Minshall},
+ title = PROC # { the ACM SIGCOMM 2005 Conference on
+ Applications, Technologies, Architectures, and Protocols
+ for Computer Communications, Philadelphia, Pennsylvania,
+ \acs{usa}, August 22-26, 2005},
+ booktitle = {SIGCOMM},
+ publisher = pub-acm,
+ adress = pub-acm:adr,
+ year = 2005,
+ isbn = {1-59593-009-4},
+ acknowledgement={none}
+}
+
+@InProceedings{ senn.ea:firewall:2005,
+ abstract = {Firewalls are widely used to protect networks from
+ unauthorised access. To ensure that they implement an
+ organisation's security policy correctly, they need to be
+ tested. We present an approach that addresses this problem.
+ Namely, we show how an organisation's network security
+ policy can be formally specified in a high-level way, and
+ how this specification can be used to automatically
+ generate test cases to test a deployed system. In contrast
+ to other firewall testing methodologies, such as
+ penetration testing, our approach tests conformance to a
+ specified policy. Our test cases are organisation-specific
+ --- i.e.~they depend on the security requirements and on
+ the network topology ofan organisation --- and can uncover
+ errors both in the firewall products themselves and in
+ their configuration.},
+ author = {Diana Senn and David A. Basin and Germano Caronni},
+ booktitle = {TestCom 2005},
+ editor = {Ferhat Khendek and Rachida Dssouli},
+ isbn = {3-540-26054-4},
+ language = {UKenglish},
+ month = {May},
+ pages = {226--241},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ title = {Firewall Conformance Testing},
+ volume = 3502,
+ year = 2005,
+ acknowledgement={none}
+}
+
+@PhDThesis{ bidder:specification:2007,
+ author = {Diana von Bidder},
+ title = {Specification-based Firewall Testing},
+ school = {ETH Zurich},
+ year = 2007,
+ public = {yes},
+ type = {Ph.D. Thesis},
+ acknowledgement={none},
+ classification= {thesis},
+ note = {\acs{eth} Dissertation No. 17172. Diana von Bidder's
+ maiden name is Diana Senn.}
+}
+
+@InCollection{ wenzel.ea:building:2007,
+ abstract = {We present the generic system framework of
+ Isabelle/Isarunderlying recent versions of Isabelle. Among
+ other things, Isar provides an infrastructure for Isabelle
+ plug-ins, comprising extensible state components and
+ extensible syntax that can be bound to tactical ML
+ programs. Thus the Isabelle/Isar architecture may be
+ understood as an extension and refinement of the
+ traditional LCF approach, with explicit infrastructure for
+ building derivative systems. To demonstrate the technical
+ potential of the framework, we apply it to a concrete
+ formalmethods tool: the HOL-Z 3.0 environment, which is
+ geared towards the analysis of Z specifications and formal
+ proof of forward-refinements.},
+ author = {Makarius Wenzel and Burkhart Wolff},
+ booktitle = {\acs{tphols} 2007},
+ editor = {Klaus Schneider and Jens Brandt},
+ language = {USenglish},
+ acknowledgement={none},
+ pages = {352--367},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ number = 4732,
+ series = s-lncs,
+ title = {Building Formal Method Tools in the {Isabelle}/{Isar}
+ Framework},
+ doi = {10.1007/978-3-540-74591-4_26},
+ year = 2007
+}
+
+@Article{ igarashi.ea:featherweight:2001,
+ author = {Atsushi Igarashi and Benjamin C. Pierce and Philip
+ Wadler},
+ title = {{Featherweight Java}: a minimal core calculus for {Java}
+ and {\acs{gj}}},
+ journal = j-toplas,
+ volume = 23,
+ number = 3,
+ year = 2001,
+ issn = {0164-0925},
+ pages = {396--450},
+ doi = {10.1145/503502.503505},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none},
+ abstract = {Several recent studies have introduced lightweight
+ versions of Java: reduced languages in which complex
+ features like threads and reflection are dropped to enable
+ rigorous arguments about key properties such as type
+ safety. We carry this process a step further, omitting
+ almost all features of the full language (including
+ interfaces and even assignment) to obtain a small calculus,
+ Featherweight Java, for which rigorous proofs are not only
+ possible but easy. Featherweight Java bears a similar
+ relation to Java as the lambda-calculus does to languages
+ such as ML and Haskell. It offers a similar computational
+ "feel," providing classes, methods, fields, inheritance,
+ and dynamic typecasts with a semantics closely following
+ Java's. A proof of type safety for Featherweight Java thus
+ illustrates many of the interesting features of a safety
+ proof for the full language, while remaining pleasingly
+ compact. The minimal syntax, typing rules, and operational
+ semantics of Featherweight Java make it a handy tool for
+ studying the consequences of extensions and variations. As
+ an illustration of its utility in this regard, we extend
+ Featherweight Java with generic classes in the style of GJ
+ (Bracha, Odersky, Stoutamire, and Wadler) and give a
+ detailed proof of type safety. The extended system
+ formalizes for the first time some of the key features of
+ GJ. },
+ bibkey = {igarashi.ea:featherweight:2001}
+}
+
+@Article{ zhu.ea:software:29-4,
+ title = {Software Unit Test Coverage and Adequacy},
+ author = {Hong Zhu and Patrick A.V. Hall and John H. R. May},
+ journal = {ACM Computing Surveys},
+ issn = {0360-0300},
+ volume = 29,
+ url = {http://www.cs.bris.ac.uk/Tools/Reports/Abstracts/1997-zhu.html}
+ ,
+ number = 4,
+ language = {USenglish},
+ pages = {366--427},
+ month = dec,
+ keywords = {Safety_Critical_Systems},
+ year = 1997,
+ abstract = {Objective measurement of test quality is one of the key
+ issues in software testing. It has been a major research
+ focus for the last two decades. Many test criteria have
+ been proposed and studied for this purpose. Various kinds
+ of rationale have been presented in support of one
+ criterion or another. This paper surveys the research work
+ in this area. The notion of adequacy criteria is examined
+ together with its role in software dynamic testing. A
+ review of criteria classification is followed by a summary
+ of the methods for comparison and assessment of criteria.},
+ acknowledgement={none},
+ bibkey = {zhu.ea:software:29-4}
+}
+
+@PhDThesis{ wenzel:isabelleisar:2002,
+ author = {Markus M. Wenzel},
+ title = {Isabelle/Isar --- a versatile environment for
+ human-readable formal proof documents},
+ school = {TU M{\"u}nchen},
+ year = 2002,
+ url = {http://tumb1.biblio.tu-muenchen.de/publ/diss/in/2002/wenzel.html}
+ ,
+ abstract = {The basic motivation of this work is to make formal theory
+ developments with machine-checked proofs accessible to a
+ broader audience. Our particular approach is centered
+ around the Isar formal proof language that is intended to
+ support adequate composition of proof documents that are
+ suitable for human consumption. Such primary proofs written
+ in Isar may be both checked by the machine and read by
+ human-beings; final presentation merely involves trivial
+ pretty printing of the sources. Sound logical foundations
+ of Isar are achieved by interpretation within the generic
+ Natural Deduction framework of Isabelle, reducing all
+ high-level reasoning steps to primitive inferences.
+
+ The resulting Isabelle/Isar system is generic with respect
+ to object-logics and proof tools, just as pure Isabelle
+ itself. The full Isar language emerges from a small core by
+ means of several derived elements, which may be combined
+ freely with existing ones. This results in a very rich
+ space of expressions of formal reasoning, supporting many
+ viable proof techniques. The general paradigms of Natural
+ Deduction and Calculational Reasoning are both covered
+ particularly well. Concrete examples from logic,
+ mathematics, and computer-science demonstrate that the Isar
+ concepts are indeed sufficiently versatile to cover a broad
+ range of applications.},
+ address = {M{\"u}nchen},
+ month = feb,
+ acknowledgement={none},
+ bibkey = {wenzel:isabelleisar:2002}
+}
+
+@InProceedings{ frantzen.ea:test:2004,
+ author = {L. Frantzen and J. Tretmans and T.A.C. Willemse},
+ title = {Test Generation Based on Symbolic Specifications},
+ booktitle = {FATES 2004},
+ year = 2004,
+ month = sep,
+ abstract = {Classical state-oriented testing approaches are based on
+ sim- ple machine models such as Labelled Transition Systems
+ (LTSs), in which data is represented by concrete values. To
+ implement these theories, data types which have infinite
+ universes have to be cut down to infinite vari- ants, which
+ are subsequently enumerated to fit in the model. This leads
+ to an explosion of the state space. Moreover, exploiting
+ the syntactical and/or semantical information of the
+ involved data types is non-trivial after enumeration. To
+ overcome these problems, we lift the family of test- ing
+ relations iocoF to the level of Symbolic Transition Systems
+ (STSs). We present an algorithm based on STSs, which
+ generates and executes tests on-the-fly on a given system.
+ It is sound and complete for the ioco F testing
+ relations.},
+ acknowledgement={none},
+ bibkey = {frantzen.ea:test:2004}
+}
+
+@Book{ dagostino.ea:handbook:1996,
+ title = {Handbook of Tableau Methods},
+ editor = {Marcello D'Agostino and Dov Gabbay and Reiner H\"ahnle and
+ Joachim Posegga},
+ publisher = {Kluwer, Dordrecht},
+ year = 1996,
+ isbn = {0-7923-5627-6},
+ acknowledgement={none},
+ bibkey = {dagostino.ea:handbook:1996}
+}
+
+@Article{ visser.ea:test:2004,
+ author = {Willem Visser and Corina S. P\u{a}s\u{a}reanu and Sarfraz
+ Khurshid},
+ title = {Test input generation with {Java} {PathFinder}},
+ journal = {SIGSOFT Softw. Eng. Notes},
+ volume = 29,
+ number = 4,
+ year = 2004,
+ issn = {0163-5948},
+ pages = {97--107},
+ doi = {10.1145/1013886.1007526},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none},
+ bibkey = {visser.ea:test:2004}
+}
+
+@InProceedings{ pons.ea:practical:2006,
+ author = {Claudia Pons and Diego Garcia},
+ title = {Practical Verification Strategy for Refinement Conditions
+ in \acs{uml} Models},
+ booktitle = {IFIP Workshop on Advanced Software Engineering},
+ year = 2006,
+ pages = {47--61},
+ doi = {10.1007/978-0-387-34831-5_4},
+ crossref = {ochoa.ea:ifip:2006}
+}
+
+@Proceedings{ ochoa.ea:ifip:2006,
+ editor = {Sergio F. Ochoa and Gruia-Catalin Roman},
+ title = {IFIP 19th World Computer Congress, First International
+ Workshop on Advanced Software Engineering, Expanding the
+ Frontiers of Software Technology, August 25, 2006,
+ Santiago, Chile},
+ booktitle = {IFIP Workshop on Advanced Software Engineering},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = {IFIP},
+ volume = 219,
+ year = 2006,
+ isbn = {978-0-387-34828-5}
+}
+
+@Misc{ clearsy:atelier-b:2008,
+ author = {{Clearsy Inc.}},
+ title = {{Atelier B}},
+ year = 2008,
+ note = {\url{http://www.atelierb.eu/}}
+}
+
+@Book{ beckert.ea:key:2007,
+ editor = {Bernhard Beckert and Reiner H\"ahnle and Peter H. Schmitt},
+ title = {Verification of Object-Oriented Software: The {\KeY}
+ Approach},
+ volume = 4334,
+ series = s-lncs,
+ doi = {10.1007/978-3-540-69061-0},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ year = 2007
+}
+
+@InProceedings{ rudich.ea:checking:2008,
+ author = {Arsenii Rudich and {\'A}d{\'a}m Darvas and Peter M{\"u}ller},
+ title = {Checking Well-Formedness of Pure-Method Specifications},
+ booktitle = {FM},
+ year = 2008,
+ pages = {68--83},
+ ee = {http://dx.doi.org/10.1007/978-3-540-68237-0_7},
+ crossref = {cuellar.ea:fm:2008}
+}
+
+@Proceedings{ cuellar.ea:fm:2008,
+ editor = {Jorge Cu{\'e}llar and T. S. E. Maibaum and Kaisa Sere},
+ title = {FM 2008: Formal Methods, 15th International Symposium on
+ Formal Methods, Turku, Finland, May 26-30, 2008,
+ Proceedings},
+ booktitle = {FM},
+ series = s-lncs,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ volume = 5014,
+ year = 2008,
+ isbn = {978-3-540-68235-6}
+}
+
+@InProceedings{ ledang:b-based:2004,
+ author = {Hung Ledang},
+ title = {B-based Conistency Checking of UML Diagrams},
+ booktitle = PROC # { ICT/RDA2004 : the 2nd National Symposium on
+ Research, Development and Application of Information and
+ Communication TechnologyAIR'2005},
+ year = 2004,
+ publisher = {Science and Techniques Publisher}
+}
+
+@InProceedings{ krieger.ea:executing,
+ author = {Matthias P. Krieger and Alexander Knapp.},
+ title = {Executing Underspecified OCL Operation Contracts with a
+ SAT Solver},
+ booktitle = PROC # { the OCL 2008 Workshop},
+ editor = {to appear},
+ note = {\url{http://www.fots.ua.ac.be/events/ocl2008/}}
+}
+
+@InProceedings{ tretmans.ea:cote:2002,
+ author = {Jan Tretmans and Edsgar Brinksma},
+ title = {C\^ote de Resyste --- Automated Model Based Testing},
+ booktitle = {Progress 2002 --- 3rd Workshop on Embedded Systems},
+ pages = {246--255},
+ year = 2002
+}
+
+@Article{ tretmans:test:1996,
+ author = {Jan Tretmans},
+ title = {Test Generation with Inputs, Outputs and Repetitive
+ Quiescence},
+ journal = {Software --- Concepts and Tools},
+ year = 1996,
+ volume = 17,
+ number = 3,
+ pages = {103--120}
+}
+
+@Article{ jard.ea:tgv:2005,
+ author = {C. Jard and T. J\'eron},
+ title = {TGV: Theory, Principles and Algorithms},
+ journal = {Software Tools for Technology Transfer},
+ year = 2005,
+ volume = 7,
+ number = 4,
+ pages = {297--315}
+}
+
+@InProceedings{ clarke.ea:stg:2002,
+ author = {D. Clarke and T. J\'eron and V. Rusu and E. Zinovieva},
+ title = {STG: A Symbolic Test Generation Tool},
+ pages = {470--475},
+ year = 2002,
+ series = s-lncs,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ volume = {2280}
+}
+
+@InProceedings{ koch.ea:autolink:1998,
+ author = {B. Koch and J. Grabowski and D. Hogrefe and M. Schmitt},
+ title = {AutoLink --- a Tool for Automatic Test Generation from SDL
+ Specifications},
+ booktitle = {Proc. IEEE Intl. Workshop on Industrial Strength Formal
+ Specification Techniques (WIFT 1998)},
+ pages = {114--127},
+ year = 1998
+}
+
+@InProceedings{ bouquet.ea:mastering:2004,
+ author = {F. Bouquet and B. Legeard and F. Peureux and E.
+ Torreborre},
+ title = {Mastering Test Generation from Smart Card Software Formal
+ Models},
+ booktitle = {Proc. Intl. Workshop on Construction and Analysis of Safe,
+ Secure and Interoperable Smart devices},
+ pages = {70--85},
+ year = 2004,
+ series = s-lncs,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ volume = {3362}
+}
+
+@InProceedings{ prowell:tool:2003,
+ author = {S. Prowell},
+ title = {A Tool for Model-based Statistical Testing},
+ booktitle = {Proc. HICSS'03, IEEE},
+ pages = {337.3},
+ year = 2003
+}
+
+@Article{ walton.ea:generating:2000,
+ author = {G. Walton and J. Poore},
+ title = {Generating transition probabilities to support model-based
+ software testing},
+ journal = {Software: Practice and Experience},
+ year = 2000,
+ volume = 30,
+ number = 10,
+ pages = {1095--1106}
+}
+
+@Article{ cohen.ea:aetg:1997,
+ author = {D. Cohen and S. Dalal and M. Fredman and G. Patton},
+ title = {The AETG System: An approach to testing Based on
+ Combinatorial Design},
+ journal = {IEEE Transactions on Software Engineering},
+ year = 1997,
+ volume = 23,
+ number = 7
+}
+
+@InProceedings{ bohme.ea:hol-boogie:2008,
+ author = {Sascha B{\"o}hme and K. Rustan M. Leino and Burkhart
+ Wolff},
+ title = {{\acs{hol}-Boogie}---An Interactive Prover for the
+ {Boogie} Program-Verifier},
+ booktitle = {Theorem Proving in Higher Order Logics},
+ year = 2008,
+ pages = {150--166},
+ doi = {10.1007/978-3-540-71067-7_15},
+ crossref = {otmane.ea:tphols:2008}
+}
+
+@Proceedings{ otmane.ea:tphols:2008,
+ editor = {Otmane A\"{\i}t Mohamed and C{\'e}sar Mu{\~n}oz and
+ Sofi{\`e}ne Tahar},
+ title = {Theorem Proving in Higher Order Logics (\acs{tphols})},
+ booktitle = {Theorem Proving in Higher Order Logics (\acs{tphols})},
+ location = {Montreal, Canada},
+ month = aug,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 5170,
+ year = 2008,
+ isbn = {978-3-540-71065-3}
+}
+
+@InProceedings{ huisman.ea:inheritance:2000,
+ author = {Marieke Huisman and Bart Jacobs},
+ title = {Inheritance in Higher Order Logic: Modeling and
+ Reasoning},
+ doi = {10.1007/3-540-44659-1_19},
+ year = 2000,
+ pages = {301--319},
+ crossref = {aagaard.ea:tphols:2000}
+}
+
+@Proceedings{ aagaard.ea:tphols:2000,
+ editor = {Mark Aagaard and John Harrison},
+ location = {Portland, Oregon, USA},
+ month = aug,
+ title = {Theorem Proving in Higher Order Logics (\acs{tphols})},
+ booktitle = {Theorem Proving in Higher Order Logics (\acs{tphols})},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 1869,
+ year = 2000,
+ isbn = {3-540-67863-8}
+}
+
+@Book{ roscoe:csp:1998,
+ author = {A.W. Roscoe},
+ title = {Theory and Practice of Concurrency},
+ publisher = {Prentice Hall},
+ year = 1998,
+ isbn = {0-13-674409-5}
+}
+
+@Article{ foster:error:1980,
+ title = {Error Sensitive Test Cases Analysis (ESTCA)},
+ author = {Foster, K.A.},
+ journal = {Software Engineering, IEEE Transactions on},
+ year = 1980,
+ month = {May},
+ volume = {SE-6},
+ number = 3,
+ pages = {258--264},
+ abstract = {A hardware failure analysis technique adapted to software
+ yielded three rules for generating test cases sensitive to
+ code errors. These rules, and a procedure for generating
+ these cases, are given with examples. Areas for further
+ study are recommended.},
+ keywords = {null Program correctness, progran testing, software
+ errors, software reliability, test data generation},
+ issn = {0098-5589}
+}
+
+@Book{ myers.ea:art:2004,
+ author = {Glenford J. Myers and Corey Sandler},
+ title = {The Art of Software Testing},
+ year = 2004,
+ isbn = 0471469122,
+ publisher = {John Wiley \& Sons}
+}
+
+@InProceedings{ tillmann.ea:pex:2008,
+ author = {Nikolai Tillmann and Jonathan de Halleux},
+ title = {{Pex}---White Box Test Generation for {.NET}},
+ booktitle = {TAP},
+ year = 2008,
+ pages = {134-153},
+ doi = {10.1007/978-3-540-79124-9_10},
+ crossref = {beckert.ea:tests:2008},
+ abstract = {Pex automatically produces a small test suite with high
+ code coverage for a .NET program. To this end, Pex performs
+ a systematic program analysis (using dynamic symbolic
+ execution, similar to path-bounded model-checking) to
+ determine test inputs for Parameterized Unit Tests. Pex
+ learns the program behavior by monitoring execution traces.
+ Pex uses a constraint solver to produce new test inputs
+ which exercise different program behavior. The result is an
+ automatically generated small test suite which often
+ achieves high code coverage. In one case study, we applied
+ Pex to a core component of the .NET runtime which had
+ already been extensively tested over several years. Pex
+ found errors, including a serious issue.}
+}
+
+@InProceedings{ halleux.ea:parameterized:2008,
+ author = {Jonathan de Halleux and Nikolai Tillmann},
+ title = {Parameterized Unit Testing with {Pex}},
+ booktitle = {TAP},
+ year = 2008,
+ pages = {171--181},
+ doi = {10.1007/978-3-540-79124-9_12},
+ crossref = {beckert.ea:tests:2008},
+ abstract = {This hands-on tutorial will teach the principles of
+ Parameterized Unit Testing [5,4] with Pex [2], an automatic
+ test input generator for .NET which performs a systematic
+ program analysis, similar to path bounded model-checking. A
+ parameterized unit test is simply a method that takes
+ parameters, calls the code under test, and states
+ assertions.}
+}
+
+@Proceedings{ beckert.ea:tests:2008,
+ editor = {Bernhard Beckert and Reiner H{\"a}hnle},
+ title = {Tests and Proofs, Second International Conference, TAP
+ 2008, Prato, Italy, April 9-11, 2008. Proceedings},
+ booktitle = {TAP},
+ series = s-lncs,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ volume = 4966,
+ year = 2008,
+ isbn = {978-3-540-79123-2}
+}
+
+%%%%%%
+@InProceedings{ povey:enforcing:1999,
+ author = {Dean Povey},
+ title = {Enforcing well-formed and partially-formed transactions
+ for {Unix}},
+ booktitle = PROC # { the 8th conference on \acs{usenix} Security
+ Symposium},
+ volume = 8,
+ year = 1999,
+ publisher = {\acs{usenix} Association},
+ location = {Berkeley, \acs{ca}},
+ pages = {5--5}
+}
+
+@InProceedings{ longstaff.ea:model:2000,
+ author = {J.J. Longstaff and M.A. Lockyer and M.G. Thick},
+ title = {A Model of Accountability, Confidentiality and Override
+ for Healthcare and other Applications},
+ booktitle = PROC # { the fifth \acs{acm} workshop on Role-based
+ access control},
+ year = 2000,
+ isbn = {1-58113-259-X},
+ pages = {71--76},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ doi = {10.1145/344287.344304}
+}
+
+@InProceedings{ rissanen.ea:towards:2004,
+ author = {Erik Rissanen},
+ title = {Towards a Mechanism for Discretionary Overriding of Access
+ Control (Transcript of Discussion)},
+ booktitle = PROC # { the 12th International Workshop on Security
+ Protocols},
+ year = 2004,
+ pages = {320--323},
+ month = mar,
+ doi = {10.1007/11861386_39},
+ abstract = {Last year, the Swedish Prime Minister was stabbed to death
+ in a shopping mall in Stockholm, and of course the police
+ thoroughly investigated it. They had some privacy problems
+ during the investigation: many policemen just looked at the
+ case, because there was no access control on the police
+ system. They didn{\^a}€™t have a whole system on-line,
+ because they cannot really predict the needs of individual
+ policemen, and they cannot really audit the whole thing
+ either because there were so many accesses. In the case of
+ the prime minister we suspect that something was going on
+ because he was a famous person, and they know from
+ experience that this tends to happen with famous people,
+ but in the case of a policemen accessing his
+ neighbour{\^a}€™s data, or something like that, then there
+ is little reason to notice that something is going on.},
+ crossref = {bruce.ea:security:2006}
+}
+
+@Proceedings{ bruce.ea:security:2006,
+ series = s-lncs,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ editor = {Bruce Christianson and Bruno Crispo and James A. Malcolm
+ and Michael Roe},
+ title = {Security Protocols, 12th International Workshop,
+ Cambridge, UK, April 26-28, 2004. Revised Selected Papers},
+ booktitle = {Security Protocols Workshop},
+ volume = 3957,
+ year = 2006,
+ isbn = {3-540-40925-4}
+}
+
+@InProceedings{ rissanen.ea:discretionary:2004,
+ author = {Erik Rissanen and Babak Sadighi Firozabadi and Marek J.
+ Sergot},
+ title = {Discretionary Overriding of Access Control in the
+ Privilege Calculus},
+ booktitle = PROC # { the Workshop on Formal Aspects Security and
+ Trust (\acs{fast})},
+ year = 2004,
+ pages = {219--232},
+ doi = {10.1007/0-387-24098-5_16},
+ crossref = {dimitrakos.ea:formal:2005},
+ abstract = {We extend a particular access control framework, the
+ Privilege Calculus, with a possibility to override denied
+ access for increased flexibility in hard to define or
+ unanticipated situations. We require the overrides to be
+ audited and approved by appropriate managers. In order to
+ automatically find the authorities who are able to approve
+ an override, we present an algorithm for authority
+ resolution. We are able to calculate from the access
+ control policy who can approve an override without the need
+ for any additional information.}
+}
+
+@Proceedings{ dimitrakos.ea:formal:2005,
+ editor = {Theodosis Dimitrakos and Fabio Martinelli},
+ title = {Formal Aspects in Security and Trust: Second IFIP TC1
+ WG1.7 Workshop on Formal Aspects in Security and Trust
+ (FAST), an event of the 18th IFIP World Computer Congress,
+ August 22-27, 2004, Toulouse, France},
+ booktitle = {Formal Aspects in Security and Trust},
+ publisher = pub-springer,
+ volume = 173,
+ address = pub-springer:adr,
+ year = 2005,
+ isbn = {0-387-24050-0}
+}
+
+@InProceedings{ alqatawna.ea:overriding:2007,
+ author = {Ja'far Alqatawna and Erik Rissanen and Babak Sadighi},
+ title = {Overriding of Access Control in \textsc{XACML}},
+ booktitle = PROC # { the Eighth \acs{ieee} International
+ Workshop on Policies for Distributed Systems and Networks
+ (\acs{policy})},
+ year = 2007,
+ isbn = {0-7695-2767-1},
+ pages = {87--95},
+ doi = {10.1109/POLICY.2007.31},
+ address = pub-ieee:adr,
+ publisher = pub-ieee
+}
+
+@InProceedings{ stevens.ea:new:2002,
+ author = {Gunnar Stevens and Volker Wulf},
+ title = {A new dimension in access control: studying maintenance
+ engineering across organizational boundaries},
+ booktitle = PROC # { the \acs{acm} conference on Computer
+ supported cooperative work (\acs{cscw})},
+ year = 2002,
+ isbn = {1-58113-560-2},
+ pages = {196--205},
+ location = {New Orleans, Louisiana, USA},
+ doi = {10.1145/587078.587106},
+ publisher = pub-acm,
+ address = pub-acm:adr
+}
+
+@InProceedings{ jaeger.ea:managing:2002,
+ author = {Trent Jaeger and Antony Edwards and Xiaolan Zhang},
+ title = {Managing access control policies using access control
+ spaces},
+ booktitle = PROC # { the seventh \acs{acm} symposium on Access
+ control models and technologies (\acs{sacmat})},
+ year = 2002,
+ isbn = {1-58113-496-7},
+ pages = {3--12},
+ location = {Monterey, California, USA},
+ doi = {10.1145/507711.507713},
+ publisher = pub-acm,
+ address = pub-acm:adr
+}
+
+@Article{ joshi.ea:generalized:2005,
+ author = {James B.D. Joshi and Elisa Bertino and Usman Latif and
+ Arif Ghafoor},
+ title = {A Generalized Temporal Role-Based Access Control Model},
+ journal = j-tkde,
+ volume = 17,
+ number = 1,
+ issn = {1041-4347},
+ year = 2005,
+ pages = {4--23},
+ doi = {10.1109/TKDE.2005.1},
+ publisher = pub-ieee,
+ address = pub-ieee:adr
+}
+
+@InProceedings{ bell.ea:secure:1996,
+ author = {D. Elliott Bell and Leonard J. LaPadula},
+ title = {Secure Computer Systems: A Mathematical Model, Volume
+ {II}},
+ booktitle = {Journal of Computer Security 4},
+ year = 1996,
+ pages = {229--263},
+ note = {An electronic reconstruction of \emph{Secure Computer
+ Systems: Mathematical Foundations}, 1973}
+}
+
+@InProceedings{ bell:looking:2005,
+ title = {Looking Back at the Bell-La Padula Model},
+ author = {D. Elliott Bell},
+ journal = PROC # { the 21st Annual Computer Security
+ Applications Conference},
+ year = 2005,
+ isbn = {1063-9527},
+ doi = {10.1109/CSAC.2005.37},
+ publisher = {pub-ieee},
+ address = pub-ieee:adr,
+ pages = {337--351}
+}
+
+@Booklet{ oasis:xacml:2005,
+ title = {{eXtensible Access Control Markup Language (XACML)},
+ Version 2.0},
+ year = 2005,
+ url = {http://docs.oasis-open.org/xacml/2.0/XACML-2.0-OS-NORMATIVE.zip}
+ ,
+ bibkey = {oasis:xacml:2005},
+ publisher = {\acs{oases}},
+ key = {OASIS},
+ language = {USenglish},
+ public = {yes}
+}
+
+@InProceedings{ barka.ea:framework:2000,
+ author = {Ezedin Barka and Ravi Sandhu},
+ title = {Framework for Role-based Delegation Models},
+ year = 2000,
+ booktitle = PROC # { the 16th Annual Computer Security
+ Applications Conference},
+ doi = {10.1109/ACSAC.2000.898870},
+ isbn = {0-7695-0859-6},
+ pages = {168--176},
+ publisher = pub-ieee,
+ address = pub-ieee:adr
+}
+
+@InProceedings{ cheng.ea:fuzzy:2007,
+ author = {Pau-Chen Cheng and Pankaj Rohatgi and Claudia Keser and
+ Paul A. Karger and Grant M. Wagner and Angela Schuett
+ Reninger},
+ title = {Fuzzy Multi-Level Security: An Experiment on Quantified
+ Risk-Adaptive Access Control},
+ booktitle = {IEEE Symposium on Security and Privacy},
+ year = 2007,
+ pages = {222--230},
+ ee = {http://dx.doi.org/10.1109/SP.2007.21},
+ crossref = {ieee:security-privacy:2007}
+}
+
+@Proceedings{ ieee:security-privacy:2007,
+ title = {2007 IEEE Symposium on Security and Privacy (S{\&}P 2007),
+ 20-23 May 2007, Oakland, California, USA},
+ booktitle = {IEEE Symposium on Security and Privacy},
+ publisher = {IEEE Computer Society},
+ year = 2007
+}
+
+@InProceedings{ zhang.ea:toward:2006,
+ author = {Lei Zhang and Alexander Brodsky and Sushil Jajodia},
+ title = {Toward Information Sharing: Benefit And Risk Access
+ Control (BARAC)},
+ booktitle = {POLICY},
+ year = 2006,
+ pages = {45--53},
+ doi = {10.1109/POLICY.2006.36},
+ crossref = {ieee:policy:2006}
+}
+
+@Proceedings{ ieee:policy:2006,
+ title = {7th IEEE International Workshop on Policies for
+ Distributed Systems and Networks (POLICY 2006), 5-7 June
+ 2006, London, Ontario, Canada},
+ booktitle = {POLICY},
+ publisher = {IEEE Computer Society},
+ year = 2006,
+ isbn = {0-7695-2598-9}
+}
+
+@InProceedings{ nissanke.ea:risk:2004,
+ author = {Nimal Nissanke and Etienne J. Khayat},
+ title = {Risk Based Security Analysis of Permissions in RBAC},
+ booktitle = {WOSIS},
+ year = 2004,
+ pages = {332--341},
+ crossref = {fernandez-medina.ea:security:2004}
+}
+
+@Proceedings{ fernandez-medina.ea:security:2004,
+ editor = {Eduardo Fern{\'a}ndez-Medina and Julio C{\'e}sar
+ Hern{\'a}ndez Castro and L. Javier Garc\'{\i}a-Villalba},
+ title = {Security In Information Systems, Proceedings of the 2nd
+ International Workshop on Security In Information Systems,
+ WOSIS 2004, In conjunction with ICEIS 2004, Porto,
+ Portugal, April 2004},
+ booktitle = {WOSIS},
+ publisher = {INSTICC Press},
+ year = 2004,
+ isbn = {972-8865-07-4}
+}
+
+@InProceedings{ fisler.ea:verification:2005,
+ author = {Kathi Fisler and Shriram Krishnamurthi and Leo A.
+ Meyerovich and Michael Carl Tschantz},
+ title = {Verification and change-impact analysis of access-control
+ policies},
+ booktitle = {ICSE},
+ year = 2005,
+ pages = {196--205},
+ doi = {10.1145/1062455.1062502},
+ crossref = {roman.ea:27th:2005}
+}
+
+@Proceedings{ roman.ea:27th:2005,
+ editor = {Gruia-Catalin Roman and William G. Griswold and Bashar
+ Nuseibeh},
+ title = {27th International Conference on Software Engineering
+ (ICSE 2005), 15-21 May 2005, St. Louis, Missouri, USA},
+ booktitle = {ICSE},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ year = 2005
+}
+
+@InProceedings{ lin.ea:approach:2007,
+ author = {Dan Lin and Prathima Rao and Elisa Bertino and Jorge
+ Lobo},
+ title = {An approach to evaluate policy similarity},
+ booktitle = {SACMAT},
+ year = 2007,
+ pages = {1--10},
+ doi = {10.1145/1266840.1266842},
+ crossref = {lotz.ea:sacmat:2007}
+}
+
+@InProceedings{ backes.ea:efficient:2004,
+ author = {Michael Backes and G{\"u}nter Karjoth and Walid Bagga and
+ Matthias Schunter},
+ title = {Efficient comparison of enterprise privacy policies},
+ booktitle = {SAC},
+ year = 2004,
+ pages = {375--382},
+ doi = {10.1145/967900.967983},
+ crossref = {haddad.ea:proceedings:2004}
+}
+
+@Proceedings{ haddad.ea:proceedings:2004,
+ editor = {Hisham Haddad and Andrea Omicini and Roger L. Wainwright
+ and Lorie M. Liebrock},
+ title = PROC # { the 2004 ACM Symposium on Applied Computing
+ (SAC), Nicosia, Cyprus, March 14-17, 2004},
+ booktitle = {SAC},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ year = 2004,
+ isbn = {1-58113-812-1}
+}
+
+@InProceedings{ warner.ea:using:2007,
+ author = {Janice Warner and Vijayalakshmi Atluri and Ravi Mukkamala
+ and Jaideep Vaidya},
+ title = {Using semantics for automatic enforcement of access
+ control policies among dynamic coalitions},
+ booktitle = {SACMAT},
+ year = 2007,
+ pages = {235--244},
+ doi = {10.1145/1266840.1266877},
+ crossref = {lotz.ea:sacmat:2007}
+}
+
+@Proceedings{ lotz.ea:sacmat:2007,
+ editor = {Volkmar Lotz and Bhavani M. Thuraisingham},
+ title = {SACMAT 2007, 12th ACM Symposium on Access Control Models
+ and Technologies, Sophia Antipolis, France, June 20-22,
+ 2007, Proceedings},
+ booktitle = {SACMAT},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ year = 2007,
+ isbn = {978-1-59593-745-2}
+}
+
+@InProceedings{ povey:optimistic:1999,
+ author = {Dean Povey},
+ title = {Optimistic Security: A New Access Control Paradigm},
+ booktitle = PROC # { the 1999 workshop on New security
+ paradigms},
+ year = 1999,
+ isbn = {1-58113-149-6},
+ pages = {40--45},
+ doi = {10.1145/335169.335188},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {Despite the best efforts of security researchers,
+ sometimes the static nature of authorisation can cause
+ unexpected risks for users work- ing in a dynamically
+ changing environment. Disasters, medical emergencies or
+ time-critical events can all lead to situations where the
+ ability to relax normal access rules can become critically
+ impor- tant.
+
+ This paper presents an optimistic access control scheme
+ where en- forcement of rules is retrospective. The system
+ administrator is re- lied on to ensure that the system is
+ not misused, and compensating transactions are used to
+ ensure that the system integrity can be re- covered in the
+ case of a breach. It is argued that providing an opti-
+ mistic scheme alongside a traditional access control
+ mechanism can provide a useful means for users to exceed
+ their normal privileges on the rare occasion that the
+ situation warrants it.
+
+ The idea of a partially-formed transaction is introduced to
+ show how accesses in an optimistic system might be
+ constrained. This model is formally described and related
+ to the Clark-Wilson in- tegrity model.}
+}
+
+@Article{ sandhu.ea:role-based:1996,
+ author = {Ravi S. Sandhu and Edward J. Coyne and Hal L. Feinstein
+ and Charles E. Youman},
+ title = {Role-Based Access Control Models},
+ journal = j-computer,
+ year = 1996,
+ volume = 29,
+ number = 2,
+ address = pub-ieee:adr,
+ publisher = pub-ieee,
+ pages = {38--47},
+ url = {http://ite.gmu.edu/list/journals/computer/pdf_ver/i94rbac(org).pdf}
+ ,
+ abstract = {Abstract This article introduces a family of reference
+ models for rolebased acce ss control (RBAC) in which
+ permissions are associated with roles, and users are made
+ members of appropriate roles. This greatly simplifies
+ management of permiss ions. Roles are closely related to
+ the concept of user groups in access control. However, a
+ role brings together a set of users on one side and a set
+ of permiss ions on the other, whereas user groups are
+ typically defined as a set of users o nly.
+
+ The basic concepts of RBAC originated with early multi-user
+ computer systems. Th e resurgence of interest in RBAC has
+ been driven by the need for general-purpose customizable
+ facilities for RBAC and the need to manage the
+ administration of R BAC itself. As a consequence RBAC
+ facilities range from simple to complex. This article
+ describes a novel framework of reference models to
+ systematically addres s the diverse components of RBAC, and
+ their interactions.},
+ issn = {0018-9162},
+ keywords = {Computational linguistics; Computer control systems;
+ Computer simulation; Computer software; Data abstraction;
+ Database systems; Discretionary access control; Encoding
+ (symbols); Integration; Mandator access control; Role based
+ access control; Semantics; Software encoding; User
+ interfaces},
+ acknowledgement={none},
+ bibkey = {sandhu.ea:role-based:1996}
+}
+
+@Booklet{ sarbanes.ea:sox:2002,
+ title = {{Sarbanes-Oxley} {Act} of 2002},
+ author = {P. Sarbanes and G. Oxley and others},
+ howpublished = {107th Congress Report, House of Representatives, 2nd
+ Session, 107--610},
+ year = 2002
+}
+
+@TechReport{ bcbs:baselii:2004,
+ author = {{Basel Committee on Banking Supervision}},
+ title = {{Basel II}: International Convergence of Capital
+ Measurement and Capital Standards},
+ year = 2004,
+ url = {http://www.bis.org/publ/bcbsca.htm},
+ address = {Basel, Switzerland},
+ institution = {Bank for International Settlements}
+}
+
+@Book{ dahl.ea:structured:1972,
+ author = {O.-J. Dahl and E. W. Dijkstra and C. A. R. Hoare},
+ title = {Structured Programming},
+ publisher = {Academic Press},
+ year = 1972,
+ edition = {3rd},
+ volume = 8,
+ series = {A.P.I.C. Studies in Data Processing},
+ address = {London},
+ isbn = {0-12-200550-3}
+}
+
+@InProceedings{ bryans:reasoning:2005,
+ author = {Jery Bryans},
+ title = {Reasoning about {XACML} policies using {CSP}},
+ booktitle = {SWS '05: Proceedings of the 2005 workshop on Secure web
+ services},
+ year = 2005,
+ isbn = {1-59593-234-8},
+ pages = {28--35},
+ location = {Fairfax, VA, USA},
+ doi = {10.1145/1103022.1103028},
+ address = pub-acm:adr,
+ publisher = pub-acm
+}
+
+@InProceedings{ chadwick.ea:permis:2002,
+ author = {David W. Chadwick and Alexander Otenko},
+ title = {The \acs{permis} {X.509} role based privilege management
+ infrastructure},
+ booktitle = PROC # { the seventh \acs{acm} symposium on Access
+ control models and technologies (\acs{sacmat})},
+ year = 2002,
+ isbn = {1-58113-496-7},
+ pages = {135--140},
+ location = {Monterey, California, USA},
+ doi = {10.1145/507711.507732},
+ address = pub-acm:adr,
+ publisher = pub-acm
+}
+
+@InProceedings{ ye.ea:using:2005,
+ author = {Chunxiao Ye and Zhongfu Wu},
+ title = {Using \acs{xml} and \acs{xacml} to Support Attribute Based
+ Delegation},
+ booktitle = {CIT '05: Proceedings of the The Fifth International
+ Conference on Computer and Information Technology},
+ year = 2005,
+ isbn = {0-7695-2432-X},
+ pages = {751--756},
+ doi = {10.1109/CIT.2005.196},
+ publisher = {IEEE Computer Society},
+ address = {Washington, DC, USA}
+}
+
+@Book{ fox.ea:it-sox:2006,
+ author = {Christopher Fox and Paul Zonneveld},
+ abstract = {This publication provides CIOs, IT managers, and control
+ and assurance professionals with scoping and assessment
+ ideas, approaches and guidance in support of the IT-related
+ Committee of Sponsoring Organizations of the Treadway
+ Commission (COSO) internal control objectives for financial
+ reporting.
+
+ A streamlined road map is provided to help turn compliance
+ into a competitive challenge. Lessons learned and
+ sustaining ideas are also included.
+
+ The second edition is updated for recent US Securities and
+ Exchange Commission (SEC) and Public Company Accounting and
+ Oversight Board (PCAOB) guidance related to entity-level
+ controls, a risk-based/top-down approach, application
+ controls and the evaluation of deficiencies.},
+ title = {\acs{it} Control Objectives for Sarbanes-Oxley: The Role
+ of \acs{it} in the Design and Implementation of Internal
+ Control Over Financial Reporting},
+ year = 2006,
+ month = sep,
+ bibkey = {fox.ea:it-sox:2006},
+ num_pages = 128,
+ edition = {2nd},
+ publisher = {IT Governance Institute},
+ isbn = {1-933284-76-5},
+ address = {Rolling Meadows, IL, USA}
+}
+
+@Article{ basin.ea:automated:2009,
+ title = {Automated analysis of security-design models},
+ journal = j-ist,
+ volume = 51,
+ number = 5,
+ issn = {0950-5849},
+ year = 2009,
+ pages = {815--831},
+ doi = {10.1016/j.infsof.2008.05.011},
+ author = {David Basin and Manuel Clavel and J{\"u}rgen Doser and
+ Marina Egea},
+ keywords = {Metamodels},
+ abstract = {We have previously proposed SecureUML, an expressive
+ UML-based language for constructing security-design models,
+ which are models that combine design specifications for
+ distributed systems with specifications of their security
+ policies. Here, we show how to automate the analysis of
+ such models in a semantically precise and meaningful way.
+ In our approach, models are formalized together with
+ scenarios that represent possible run-time instances.
+ Queries about properties of the security policy modeled are
+ expressed as formulas in UML's Object Constraint Language.
+ The policy may include both declarative aspects, i.e.,
+ static access-control information such as the assignment of
+ users and permissions to roles, and programmatic aspects,
+ which depend on dynamic information, namely the
+ satisfaction of authorization constraints in a given
+ scenario. We show how such properties can be evaluated,
+ completely automatically, in the context of the metamodel
+ of the security-design language. We demonstrate, through
+ examples, that this approach can be used to formalize and
+ check non-trivial security properties. The approach has
+ been implemented in the SecureMOVA tool and all of the
+ examples presented have been checked using this tool.},
+ note = {Special Issue on Model-Driven Development for Secure
+ Information Systems},
+ publisher = pub-elsevier,
+ address = pub-elsevier:adr
+}
+
+@InProceedings{ dong.ea:flexible:2008,
+ author = {Changyu Dong and Giovanni Russello and Naranker Dulay},
+ title = {Flexible Resolution of Authorisation Conflicts in
+ Distributed Systems},
+ booktitle = {DSOM},
+ year = 2008,
+ pages = {95--108},
+ doi = {10.1007/978-3-540-87353-2_8},
+ crossref = {turck.ea:managing:2008},
+ abstract = {Managing security in distributed systems requires flexible
+ and expressive authorisation models with support for
+ conflict resolution. Models need to be hierarchical but
+ also non-monotonic supporting both positive and negative
+ authorisations. In this paper, we present an approach to
+ resolve the authorisation conflicts that inevitably occur
+ in such models, with administrator specified conflict
+ resolution strategies (rules). Strategies can be global or
+ applied to specific parts of a system and dynamically
+ loaded for different applications. We use Courteous Logic
+ Programs (CLP) for the specification and enforcement of
+ strategies. Authorisation policies are translated into
+ labelled rules in CLP and prioritised. The prioritisation
+ is regulated by simple override rules specified or selected
+ by administrators. We demonstrate the capabilities of the
+ approach by expressing the conflict resolution strategy for
+ a moderately complex authorisation model that organises
+ subjects and objects hierarchically.}
+}
+
+@Proceedings{ turck.ea:managing:2008,
+ editor = {Filip De Turck and Wolfgang Kellerer and George
+ Kormentzas},
+ title = {Managing Large-Scale Service Deployment, 19th IFIP/IEEE
+ International Workshop on Distributed Systems: Operations
+ and Management, DSOM 2008, Samos Island, Greece, September
+ 22-26, 2008. Proceedings},
+ booktitle = {DSOM},
+ series = s-lncs,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ volume = 5273,
+ year = 2008,
+ isbn = {978-3-540-85999-4}
+}
+
+@InProceedings{ russello.ea:consent-based:2008,
+ author = {Giovanni Russello and Changyu Dong and Naranker Dulay},
+ title = {Consent-Based Workflows for Healthcare Management},
+ booktitle = {9th IEEE International Workshop on Policies for
+ Distributed Systems and Networks (POLICY 2008), 2-4 June
+ 2008, Palisades, New York, USA},
+ year = 2008,
+ publisher = {IEEE Computer Society},
+ pages = {153--161},
+ isbn = {978-0-7695-3133-5},
+ doi = {10.1109/POLICY.2008.22},
+ abstract = {n this paper, we describe a new framework for healthcare
+ systems where patients are able to control the disclosure
+ of their medical data. In our framework, the patient's
+ consent has a pivotal role in granting or removing access
+ rights to subjects accessing patient's medical data.
+ Depending on the context in which the access is being
+ executed, different consent policies can be applied.
+ Context is expressed in terms of workflows. The execution
+ of a task in a given workflow carries the necessary
+ information to infer whether the consent can be implicitly
+ retrieved or should be explicitly requested from a patient.
+ However, patients are always able to enforce their own
+ decisions and withdraw consent if necessary. Additionally,
+ the use of workflows enables us to apply the need-to-know
+ principle. Even when the patient's consent is obtained, a
+ subject should access medical data only if it is required
+ by the actual situation. For example, if the subject is
+ assigned to the execution of a medical diagnosis workflow
+ requiring access to the patient's medical record. We also
+ provide a complex medical case study to highlight the
+ design principles behind our framework. Finally, the
+ implementation of the framework is outlined.}
+}
+
+@InProceedings{ mitchell-wong.ea:social:2008,
+ author = {Juliana Mitchell-Wong and Ryszard Kowalczyk and Bao Quoc
+ Vo},
+ title = {Social Network Profile and Policy},
+ booktitle = {9th IEEE International Workshop on Policies for
+ Distributed Systems and Networks (POLICY 2008), 2-4 June
+ 2008, Palisades, New York, USA},
+ year = 2008,
+ publisher = {IEEE Computer Society},
+ isbn = {978-0-7695-3133-5},
+ pages = {207--210},
+ doi = {10.1109/POLICY.2008.41},
+ abstract = {n this paper, we describe a new framework for healthcare
+ systems where patients are able to control the disclosure
+ of their medical data. In our framework, the patient's
+ consent has a pivotal role in granting or removing access
+ rights to subjects accessing patient's medical data.
+ Depending on the context in which the access is being
+ executed, different consent policies can be applied.
+ Context is expressed in terms of workflows. The execution
+ of a task in a given workflow carries the necessary
+ information to infer whether the consent can be implicitly
+ retrieved or should be explicitly requested from a patient.
+ However, patients are always able to enforce their own
+ decisions and withdraw consent if necessary. Additionally,
+ the use of workflows enables us to apply the need-to-know
+ principle. Even when the patient's consent is obtained, a
+ subject should access medical data only if it is required
+ by the actual situation. For example, if the subject is
+ assigned to the execution of a medical diagnosis workflow
+ requiring access to the patient's medical record. We also
+ provide a complex medical case study to highlight the
+ design principles behind our framework. Finally, the
+ implementation of the framework is outlined.}
+}
+
+@Book{ paulson:ml:1996,
+ author = {Lawrence C. Paulson},
+ title = {\acs{ml} for the Working Programmer},
+ publisher = {Cambridge Press},
+ year = 1996,
+ acknowledgement={none}
+}
+
+@InProceedings{ kohler.ea:proactive:2008,
+ title = {Pro Active Access Control for Business Process-driven
+ Environments},
+ author = {Mathias Kohler and Andreas Schaad},
+ booktitle = {Annual Computer Security Applications Conference},
+ year = 2008
+}
+
+@InProceedings{ dewin:importance:2002,
+ author = {Bart De Win and Frank Piessens and Wouter Joosen and Tine
+ Verhanneman},
+ title = {On the importance of the separation-of-concerns principle
+ in secure software engineering},
+ booktitle = {ACSA Workshop on the Application of Engineering Principles
+ to System Security Design - Final Report (Serban, C.,
+ ed.)},
+ year = 2003,
+ pages = {1--10}
+}
+
+@InProceedings{ priebe:towards:2000,
+ author = {Torsten Priebe and G\"{u}nther Pernul},
+ title = {Towards \textsc{olap} security design --- survey and
+ research issues},
+ booktitle = {DOLAP '00: Proceedings of the 3rd ACM international
+ workshop on Data warehousing and OLAP},
+ year = 2000,
+ isbn = {1-58113-323-5},
+ pages = {33--40},
+ location = {McLean, Virginia, United States},
+ doi = {10.1145/355068.355313},
+ publisher = {ACM},
+ address = {New York, NY, USA}
+}
+
+@InProceedings{ atluri:supporting:2005,
+ author = {Vijayalakshmi Atluri and Janice Warner},
+ title = {Supporting conditional delegation in secure workflow
+ management systems},
+ booktitle = PROC # { the tenth \acs{acm} symposium on Access
+ control models and technologies (\acs{sacmat})},
+ year = 2005,
+ isbn = {1-59593-045-0},
+ pages = {49--58},
+ location = {Stockholm, Sweden},
+ doi = {10.1145/1063979.1063990},
+ publisher = pub-acm,
+ address = pub-acm:adr
+}
+
+@InProceedings{ dimmock:using:2004,
+ author = {Nathan Dimmock and Andr{\'a} Belokosztolszki and David
+ Eyers and Jean Bacon and Ken Moody},
+ title = {Using trust and risk in role-based access control
+ policies},
+ booktitle = PROC # { the ninth ACM symposium on Access control
+ models and technologies (\acs{sacmat})},
+ year = 2004,
+ isbn = {1-58113-872-5},
+ pages = {156--162},
+ location = {Yorktown Heights, New York, USA},
+ doi = {10.1145/990036.990062},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {Emerging trust and risk management systems provide a
+ framework for principals to determine whether they will
+ exchange resources, without requiring a complete definition
+ of their credentials and intentions. Most distributed
+ access control architectures have far more rigid policy
+ rules, yet in many respects aim to solve a similar problem.
+ This paper elucidates the similarities between trust
+ management and distributed access control systems by
+ demonstrating how the OASIS access control system and its
+ role-based policy language can be extended to make
+ decisions on the basis of trust and risk analyses rather
+ than on the basis of credentials alone. We apply our new
+ model to the prototypical example of a file storage and
+ publication service for the Grid, and test it using our
+ Prolog-based OASIS implementation.}
+}
+
+@Article{ barnett.ea:verification:2004,
+ author = {Michael Barnett and Robert DeLine and Manuel F{\"a}hndrich
+ and K. Rustan M. Leino and Wolfram Schulte},
+ title = {Verification of Object-Oriented Programs with Invariants},
+ journal = {Journal of Object Technology},
+ volume = 3,
+ number = 6,
+ year = 2004,
+ pages = {27--56},
+ abstract = {An object invariant defines what it means for an object's
+ data to be in a consistent state. Object invariants are
+ central to the design and correctness of object-oriented
+ programs. This paper defines a programming methodology for
+ using object invariants. The methodology, which enriches a
+ program's state space to express when each object invariant
+ holds, deals with owned object components, ownership
+ transfer, and subclassing, and is expressive enough to
+ allow many interesting object-oriented programs to be
+ specified and verified. Lending itself to sound modular
+ verification, the methodology also provides a solution to
+ the problem of determining what state a method is allowed
+ to modify. },
+ url = {http://www.jot.fm/issues/issue_2004_06/article2/article2.pdf}
+
+}
+
+@Article{ harms.ea:copying:1991,
+ author = {Douglas E. Harms and Bruce W. Weide},
+ title = {Copying and Swapping: Influences on the Design of Reusable
+ Software Components},
+ journal = j-tse,
+ volume = 17,
+ number = 5,
+ year = 1991,
+ pages = {424--435},
+ doi = {10.1109/32.90445 },
+ abstract = {The authors argue that a simple alternative to copying as
+ a data movement primitive-swapping (exchanging) the values
+ of two variables-has potentially significant advantages in
+ the context of the design of generic reusable software
+ components. Specifically, the authors claim that generic
+ module designs based on a swapping style are superior to
+ designs based on copying, both in terms of execution-time
+ efficiency and with respect to the likelihood of
+ correctness of client programs and module implementations.
+ Furthermore, designs based on swapping are more reusable
+ than traditional designs. Specific arguments and examples
+ to support these positions are presented},
+ publisher = pub-ieee,
+ address = pub-ieee:adr
+}
+
+@InProceedings{ albano.ea:relationship:1991,
+ author = {Antonio Albano and Giorgio Ghelli and Renzo Orsini},
+ title = {A Relationship Mechanism for a Strongly Typed
+ Object-Oriented Database Programming Language},
+ booktitle = {VLDB},
+ year = 1991,
+ pages = {565--575},
+ crossref = {lohman.ea:17th:1991}
+}
+
+@Proceedings{ lohman.ea:17th:1991,
+ editor = {Guy M. Lohman and Am\'{\i}lcar Sernadas and Rafael Camps},
+ title = {17th International Conference on Very Large Data Bases,
+ September 3-6, 1991, Barcelona, Catalonia, Spain,
+ Proceedings},
+ publisher = {Morgan Kaufmann},
+ year = 1991,
+ isbn = {1-55860-150-3}
+}
+
+@InProceedings{ ernst.ea:predicate:1998,
+ author = {Michael D. Ernst and Craig S. Kaplan and Craig Chambers},
+ title = {Predicate Dispatching: A Unified Theory of Dispatch},
+ booktitle = {ECOOP},
+ year = 1998,
+ pages = {186--211},
+ doi = {10.1007/BFb0054092},
+ abstract = {Predicate dispatching generalizes previous method dispatch
+ mechanisms by permitting arbitrary predicates to control
+ method applicability and by using logical implication
+ between predicates as the overriding relationship. The
+ method selected to handle a message send can depend not
+ just on the classes of the arguments, as in ordinary
+ object-oriented dispatch, but also on the classes of
+ subcomponents, on an argument's state, and on relationships
+ between objects. This simple mechanism subsumes and extends
+ object-oriented single and multiple dispatch, ML-style
+ pattern matching, predicate classes, and classifiers, which
+ can all be regarded as syntactic sugar for predicate
+ dispatching. This paper introduces predicate dispatching,
+ gives motivating examples, and presents its static and
+ dynamic semantics. An implementation of predicate
+ dispatching is available.},
+ crossref = {jul:eccop98:1998}
+}
+
+@Proceedings{ jul:eccop98:1998,
+ editor = {Eric Jul},
+ title = {ECCOP'98 - Object-Oriented Programming, 12th European
+ Conference, Brussels, Belgium, July 20-24, 1998,
+ Proceedings},
+ booktitle = {ECOOP},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 1445,
+ year = 1998,
+ isbn = {3-540-64737-6}
+}
+
+@Misc{ garbani:future:2009,
+ author = {Jean-Pierre Garbani},
+ title = {Future Trends In The Enterprise Software Market},
+ howpublished = {http://www.forrester.com/Research/Document/Excerpt/0,7211,53493,00.html}
+ ,
+ month = mar # {~9},
+ year = 2009,
+ publisher = {Forrester Research, Inc.},
+ address = {Cambridge, USA},
+ abstract = {Hardware, software, and people are the three basic
+ ingredients of enterprise business technology. They provide
+ the enterprise with an economic advantage through automated
+ and improved business processes, increased employee
+ productivity, and more accurate and precise information.
+ The relationship between these three components has evolved
+ over time: Initially, hardware reigned supreme; software
+ was a mere adjunct and free to the mainframe buyer.
+ Decreasing hardware costs then led to software
+ "unbundling." In the present era of information technology,
+ hardware's ever-decreasing costs make it an enabler of
+ software functions. In the business technology (BT) era, we
+ predict that managing the third part of the equation --
+ people -- will emerge as the dominant focus. As software
+ applications become business services, the cost of human
+ resources producing, operating, and managing software will
+ soon be prohibitive and the new focal point. In this
+ regard, the current economic downturn, if it persists, may
+ prove to be a driver that accelerates the shift toward the
+ BT era.}
+}
+
+@Article{ klein:operating:2009,
+ author = {Gerwin Klein},
+ title = {Operating System Verification --- An Overview},
+ journal = {S\={a}dhan\={a}},
+ publisher = pub-springer,
+ year = 2009,
+ volume = 34,
+ number = 1,
+ month = feb,
+ pages = {27--69},
+ abstract = {This paper gives a high-level introduction to the topic of
+ formal, interactive, machine-checked software verification
+ in general, and the verification of operating systems code
+ in particular. We survey the state of the art, the
+ advantages and limitations of machine-checked code proofs,
+ and describe two specific ongoing larger-scale verification
+ projects in more detail.}
+}
+
+@Article{ edwards.ea:resolve:1994,
+ bibkey = {edwards.ea:resolve:1994},
+ author = {Stephen H. Edwards and Wayne D. Heym and Timothy J. Long
+ and Murali Sitaramanand Bruce W. Weide},
+ title = {Part II: specifying components in {RESOLVE}},
+ journal = {SIGSOFT Softw. Eng. Notes},
+ volume = 19,
+ number = 4,
+ year = 1994,
+ issn = {0163-5948},
+ pages = {29--39},
+ doi = {10.1145/190679.190682},
+ publisher = pub-acm,
+ address = pub-acm:adr
+}
+
+@PhDThesis{ kassios:theory:2006,
+ author = {Ioannis T. Kassios},
+ title = {A Theory of Object Oriented Refinement},
+ school = {University of Toronto},
+ abstract = {This thesis introduces a formal theory of object oriented
+ refinement. The formal design of the theory is based on the
+ design principles of unification and decoupling, which we
+ believe have not been adequately used in other object
+ oriented refinement theories.
+
+ Thanks to the use of these principles, the semantics of the
+ theory is mathematically simpler than other approaches: the
+ formalization of most features uses very primitive
+ mathematical entities. Furthermore, the constructs of the
+ theory are more general than other approaches. There are
+ specification constructs more general than classes.
+ Features that are typically coupled with classes, like
+ reuse and polymorphism, now apply to these more general
+ specifications. Finally, our solution to the frame problem
+ is the only modular approach that we know of that does not
+ impose any aliasing control policy.
+
+ To demonstrate that the extra generality offers real
+ advantages to the specifier, we use the theory in some
+ specification examples that would be impossible with other
+ approaches. These examples, mainly inspired by Design
+ Patterns, represent realistic and common software design
+ situations.},
+ year = 2006
+}
+
+@TechReport{ dewar:setl:1979,
+ author = {Robert B. K. Dewar},
+ title = {The {SETL} Programming Language},
+ year = 1979
+}
+
+@InBook{ chun.ea:risk-based:2008,
+ author = {Soon Ae Chun and Vijay Atluri},
+ editor = {Bhargab B. Bhattacharya and Susmita Sur-Kolay and Subhas
+ C. Nandy and Aditya Bagchi},
+ booktitle = {Algorithms, Architecture and Information Systems
+ Security},
+ title = {Risk-based Access Control for Personal Data Services},
+ publisher = {World Scientific Press},
+ year = 2008,
+ volume = 3,
+ series = {Statistical Science and Interdisciplinary Research},
+ isbn = 9789812836236
+}
+
+@Unpublished{ clark.ea:survey:1997,
+ author = {John Clark and Jeremy Jacob},
+ title = {A Survey of Authentication Protocol: Literature: Version
+ 1.0},
+ year = 1997
+}
+
+@Unpublished{ dierks.ea:tls:1999,
+ author = {T. Dierks and C. Allen},
+ title = {The TLS Protocol Version 1.0},
+ year = 1999,
+ publisher = {RFC Editor},
+ address = {United States},
+ note = {RFC 2246}
+}
+
+@InProceedings{ fontaine.ea:expressiveness:2006,
+ author = {Pascal Fontaine and Jean-Yves Marion and Stephan Merz and
+ Leonor Prensa Nieto and Alwen Fernanto Tiu},
+ title = {Expressiveness + Automation + Soundness: Towards Combining
+ SMT Solvers and Interactive Proof Assistants},
+ booktitle = {TACAS},
+ year = 2006,
+ pages = {167--181},
+ doi = {10.1007/11691372_11},
+ crossref = {hermanns.ea:tools:2006}
+}
+
+@Proceedings{ hermanns.ea:tools:2006,
+ editor = {Holger Hermanns and Jens Palsberg},
+ title = {Tools and Algorithms for the Construction and Analysis of
+ Systems, 12th International Conference, TACAS 2006 Held as
+ Part of the Joint European Conferences on Theory and
+ Practice of Software, ETAPS 2006, Vienna, Austria, March 25
+ - April 2, 2006, Proceedings},
+ booktitle = {TACAS},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 3920,
+ year = 2006,
+ isbn = {3-540-33056-9}
+}
+
+@InProceedings{ amjad:lcf-style:2008,
+ author = {Hasan Amjad},
+ title = {LCF-Style Propositional Simplification with BDDs and SAT
+ Solvers},
+ booktitle = {TPHOLs},
+ year = 2008,
+ pages = {55--70},
+ doi = {10.1007/978-3-540-71067-7_9},
+ crossref = {mohamed.ea:theorem:2008}
+}
+
+@Proceedings{ mohamed.ea:theorem:2008,
+ editor = {Otmane A\"{\i}t Mohamed and C{\'e}sar Mu{\~n}oz and
+ Sofi{\`e}ne Tahar},
+ title = {Theorem Proving in Higher Order Logics, 21st International
+ Conference, TPHOLs 2008, Montreal, Canada, August 18-21,
+ 2008. Proceedings},
+ booktitle = {TPHOLs},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ volume = 5170,
+ series = s-lncs,
+ year = 2008,
+ isbn = {978-3-540-71065-3}
+}
+
+@Article{ weber:integrating:2006,
+ author = {Tjark Weber},
+ title = {Integrating a {SAT} Solver with an {LCF}-style Theorem
+ Prover},
+ editor = {Alessandro Armando and Alessandro Cimatti},
+ journal = j-entcs,
+ month = jan,
+ year = 2006,
+ publisher = pub-elsevier,
+ address = pub-elsevier:adr,
+ pages = {67--78},
+ doi = {10.1016/j.entcs.2005.12.007},
+ issn = {1571-0661},
+ volume = 144,
+ number = 2,
+ note = PROC # { the Third Workshop on Pragmatics of
+ Decision Procedures in Automated Reasoning (PDPAR 2005)},
+ clearance = {unclassified},
+ abstract = {This paper describes the integration of a leading SAT
+ solver with Isabelle/HOL, a popular interactive theorem
+ prover. The SAT solver generates resolution-style proofs
+ for (instances of) propositional tautologies. These proofs
+ are verified by the theorem prover. The presented approach
+ significantly improves Isabelle's performance on
+ propositional problems, and furthermore exhibits
+ counterexamples for unprovable conjectures.}
+}
+
+@Article{ weber.ea:efficiently:2009,
+ title = {Efficiently checking propositional refutations in HOL
+ theorem provers},
+ journal = {Journal of Applied Logic},
+ volume = 7,
+ number = 1,
+ pages = {26 -- 40},
+ year = 2009,
+ note = {Special Issue: Empirically Successful Computerized
+ Reasoning},
+ issn = {1570-8683},
+ doi = {10.1016/j.jal.2007.07.003},
+ author = {Tjark Weber and Hasan Amjad},
+ abstract = {This paper describes the integration of zChaff and
+ MiniSat, currently two leading SAT solvers, with Higher
+ Order Logic (HOL) theorem provers. Both SAT solvers
+ generate resolution-style proofs for (instances of)
+ propositional tautologies. These proofs are verified by the
+ theorem provers. The presented approach significantly
+ improves the provers' performance on propositional
+ problems, and exhibits counterexamples for unprovable
+ conjectures. It is also shown that LCF-style theorem
+ provers can serve as viable proof checkers even for large
+ SAT problems. An efficient representation of the
+ propositional problem in the theorem prover turns out to be
+ crucial; several possible solutions are discussed.}
+}
+
+@Article{ wendling:german:2009,
+ title = {The German {eHealth} programme},
+ journal = {Card Technology Today},
+ volume = 21,
+ number = 1,
+ pages = {10--11},
+ year = 2009,
+ issn = {0965-2590},
+ doi = {10.1016/S0965-2590(09)70018-0},
+ author = {Dietmar Wendling},
+ abstract = {Germany was one of the first countries in the world to use
+ smart cards for healthcare. Now it is at the starting gate
+ to roll out a new generation of cards. Dietmar Wendling,
+ vice president of the eGovernment market sector at SCM
+ Microsystems reports.}
+}
+
+@Article{ meng.ea:translating:2008,
+ author = {Jia Meng and Lawrence C. Paulson},
+ title = {Translating Higher-Order Clauses to First-Order Clauses},
+ journal = j-jar,
+ volume = 40,
+ number = 1,
+ year = 2008,
+ pages = {35--60},
+ doi = {10.1007/s10817-007-9085-y}
+}
+
+@InProceedings{ paulson.ea:source-level:2007,
+ author = {Lawrence C. Paulson and Kong Woei Susanto},
+ title = {Source-Level Proof Reconstruction for Interactive Theorem
+ Proving},
+ booktitle = {TPHOLs},
+ year = 2007,
+ pages = {232--245},
+ doi = {10.1007/978-3-540-74591-4_18},
+ crossref = {schneider.ea:theorem:2007}
+}
+
+@Proceedings{ schneider.ea:theorem:2007,
+ editor = {Klaus Schneider and Jens Brandt},
+ title = {Theorem Proving in Higher Order Logics, 20th International
+ Conference, TPHOLs 2007, Kaiserslautern, Germany, September
+ 10-13, 2007, Proceedings},
+ booktitle = {TPHOLs},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 4732,
+ year = 2007,
+ isbn = {978-3-540-74590-7}
+}
+
+@Article{ meng.ea:automation:2006,
+ author = {Jia Meng and Claire Quigley and Lawrence C. Paulson},
+ title = {Automation for interactive proof: First prototype},
+ journal = {Inf. Comput.},
+ volume = 204,
+ number = 10,
+ year = 2006,
+ pages = {1575--1596},
+ doi = {10.1016/j.ic.2005.05.010}
+}
+
+@InProceedings{ erkok.ea:using:2008,
+ location = {Princeton, New Jersey, USA},
+ author = {Levent Erk{\"o}k and John Matthews},
+ booktitle = {Automated Formal Methods (AFM'08)},
+ title = {Using Yices as an Automated Solver in Isabelle/{HOL}},
+ year = 2008
+}
+
+@Article{ jurjens.ea:model-based:2008,
+ author = {Jan J{\"u}rjens and Rumm, R.},
+ title = {Model-based security analysis of the German health card
+ architecture.},
+ journal = {Methods Inf Med},
+ year = 2008,
+ volume = 47,
+ number = 5,
+ pages = {409--416},
+ keywords = {Patient Identification Systems},
+ abstract = {OBJECTIVES: Health-care information systems are
+ particularly security-critical. In order to make these
+ applications secure, the security analysis has to be an
+ integral part of the system design and IT management
+ process for such systems. METHODS: This work presents the
+ experiences and results from the security analysis of the
+ system architecture of the German Health Card, by making
+ use of an approach to model-based security engineering that
+ is based on the UML extension UMLsec. The focus lies on the
+ security mechanisms and security policies of the
+ smart-card-based architecture which were analyzed using the
+ UMLsec method and tools. RESULTS: Main results of the paper
+ include a report on the employment of the UMLsec method in
+ an industrial health information systems context as well as
+ indications of its benefits and limitations. In particular,
+ two potential security weaknesses were detected and
+ countermeasures discussed. CONCLUSIONS: The results
+ indicate that it can be feasible to apply a model-based
+ security analysis using UMLsec to an industrial health
+ information system like the German Health Card
+ architecture, and that doing so can have concrete benefits
+ (such as discovering potential weaknesses, and an increased
+ confidence that no further vulnerabilities of the kind that
+ were considered are present).},
+ issn = {0026-1270}
+}
+
+@InProceedings{ miseldine:automated:2008,
+ author = {Philip Miseldine},
+ title = {Automated {XACML} policy reconfiguration for evaluation
+ optimisation},
+ booktitle = {SESS},
+ year = 2008,
+ pages = {1--8},
+ doi = {10.1145/1370905.1370906},
+ crossref = {win.ea:proceedings:2008},
+ abstract = {We present a programmatic approach to the optimisation of
+ XACML policies that specifies how a set of access control
+ rules should be best represented for optimised evaluation.
+ The work assumes no changes to the current XACML
+ specification and methods of interpretation shall be made,
+ so that those who consume XACML are unaffected
+ structurally, and those that generate XACML can provide
+ optimised output. Discussion regarding the flexibility of
+ the XACML specification to describe the same access rules
+ with different policy configurations is presented, and is
+ used to formulate a comprehensive analysis of the
+ evaluation costs the possible policy configurations will
+ produce. This leads to the specification of methods that
+ can be employed to produce optimal forms of policy
+ description. These are implemented and evaluated to show
+ the benefits of the approach proposed.}
+}
+
+@Proceedings{ win.ea:proceedings:2008,
+ editor = {Bart De Win and Seok-Won Lee and Mattia Monga},
+ title = PROC # { the Fourth International Workshop on
+ Software Engineering for Secure Systems, SESS 2008,
+ Leipzig, Germany, May 17-18, 2008},
+ booktitle = {SESS},
+ publisher = {ACM},
+ year = 2008,
+ isbn = {978-1-60558-042-5}
+}
+
+@InProceedings{ liu.ea:firewall:2008,
+ author = {Alex X. Liu and Eric Torng and Chad Meiners},
+ title = {Firewall Compressor: An Algorithm for Minimizing Firewall
+ Policies},
+ booktitle = PROC # { the 27th Annual IEEE Conference on Computer
+ Communications (Infocom)},
+ year = 2008,
+ address = {Phoenix, Arizona},
+ month = {April}
+}
+
+@InProceedings{ liu.ea:xengine:2008,
+ author = {Alex X. Liu and Fei Chen and JeeHyun Hwang and Tao Xie},
+ title = {{XEngine}: A Fast and Scalable {XACML} Policy Evaluation
+ Engine},
+ booktitle = PROC # { the International Conference on Measurement
+ and Modeling of Computer Systems (Sigmetrics)},
+ year = 2008,
+ address = {Annapolis, Maryland},
+ month = {June}
+}
+
+@InProceedings{ goubault-larrecq:towards:2008,
+ address = {Pittsburgh, PA, USA},
+ author = {Goubault{-}Larrecq, Jean},
+ booktitle = {{P}roceedings of the 21st {IEEE} {C}omputer {S}ecurity
+ {F}oundations {S}ymposium ({CSF}'08)},
+ doi = {10.1109/CSF.2008.21},
+ month = jun,
+ pages = {224--238},
+ publisher = {{IEEE} Computer Society Press},
+ title = {Towards Producing Formally Checkable Security Proofs,
+ Automatically},
+ year = 2008
+}
+
+@InProceedings{ weidenbach.ea:spass:2007,
+ author = {Christoph Weidenbach and Renate A. Schmidt and Thomas
+ Hillenbrand and Rostislav Rusev and Dalibor Topic},
+ title = {System Description: Spass Version 3.0},
+ booktitle = {CADE},
+ year = 2007,
+ pages = {514--520},
+ doi = {10.1007/978-3-540-73595-3_38},
+ crossref = {pfenning:automated:2007}
+}
+
+@Proceedings{ pfenning:automated:2007,
+ editor = {Frank Pfenning},
+ title = {Automated Deduction - CADE-21, 21st International
+ Conference on Automated Deduction, Bremen, Germany, July
+ 17-20, 2007, Proceedings},
+ booktitle = {CADE},
+ series = s-lncs,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ volume = 4603,
+ year = 2007,
+ isbn = {978-3-540-73594-6}
+}
+
+@Article{ paulson:tls:1999,
+ author = {Lawrence C. Paulson},
+ title = {Inductive Analysis of the Internet Protocol {TLS}},
+ journal = {ACM Trans. Inf. Syst. Secur.},
+ volume = 2,
+ number = 3,
+ year = 1999,
+ pages = {332--351},
+ doi = {10.1145/322510.322530}
+}
+
+@Article{ harman.ea:testability:2004,
+ author = {Mark Harman and Lin Hu and Rob Hierons and Joachim Wegener
+ and Harmen Sthamer and Andr{\'e} Baresel and Marc Roper},
+ title = {Testability Transformation},
+ journal = {IEEE Trans. Softw. Eng.},
+ volume = 30,
+ number = 1,
+ year = 2004,
+ issn = {0098-5589},
+ pages = {3--16},
+ doi = {10.1109/TSE.2004.1265732},
+ publisher = {IEEE Press},
+ address = {Piscataway, NJ, USA}
+}
+
+@Article{ dssouli.ea:communications:1999,
+ title = {Communications software design for testability:
+ specification transformations and testability measures},
+ journal = {Information and Software Technology},
+ volume = 41,
+ number = {11-12},
+ pages = {729--743},
+ year = 1999,
+ issn = {0950-5849},
+ doi = {10.1016/S0950-5849(99)00033-6},
+ url = {http://www.sciencedirect.com/science/article/B6V0B-3X3TD3J-4/2/0efca94003ffe88571f8aa2d346a1289}
+ ,
+ author = {R. Dssouli and K. Karoui and K. Saleh and O. Cherkaoui},
+ keywords = {Testing}
+}
+
+@Article{ baker:equal:1993,
+ author = {Henry G. Baker},
+ title = {Equal rights for functional objects or, the more things
+ change, the more they are the same},
+ journal = {OOPS Messenger},
+ volume = 4,
+ number = 4,
+ year = 1993,
+ pages = {2--27},
+ abstract = {We argue that intensional object identity in
+ object-oriented programming languages and databases is best
+ defined operationally by side-effect semantics. A corollary
+ is that "functional" objects have extensional semantics.
+ This model of object identity, which is analogous to the
+ normal forms of relational algebra, provides cleaner
+ semantics for the value-transmission operations and
+ built-in primitive equality predicate of a programming
+ language, and eliminates the confusion surrounding
+ "call-by-value" and "call-by-reference" as well as the
+ confusion of multiple equality predicates.Implementation
+ issues are discussed, and this model is shown to have
+ significant performance advantages in persistent, parallel,
+ distributed and multilingual processing environments. This
+ model also provides insight into the "type equivalence"
+ problem of Algol-68, Pascal and Ada.}
+}
+
+@Article{ hierons.ea:branch-coverage:2005,
+ author = {Robert M. Hierons and Mark Harman and Chris Fox},
+ title = {Branch-Coverage Testability Transformation for
+ Unstructured Programs},
+ journal = {Comput. J.},
+ volume = 48,
+ number = 4,
+ year = 2005,
+ pages = {421--436},
+ doi = {10.1093/comjnl/bxh093},
+ abstract = {Test data generation by hand is a tedious, expensive and
+ error-prone activity, yet testing is a vital part of the
+ development process. Several techniques have been proposed
+ to automate the generation of test data, but all of these
+ are hindered by the presence of unstructured control flow.
+ This paper addresses the problem using testability
+ transformation. Testability transformation does not
+ preserve the traditional meaning of the program, rather it
+ deals with preserving test-adequate sets of input data.
+ This requires new equivalence relations which, in turn,
+ entail novel proof obligations. The paper illustrates this
+ using the branch coverage adequacy criterion and develops a
+ branch adequacy equivalence relation and a testability
+ transformation for restructuring. It then presents a proof
+ that the transformation preserves branch adequacy.}
+}
+
+@InProceedings{ harman:open:2008,
+ title = {Open Problems in Testability Transformation},
+ author = {Harman, M.},
+ booktitle = {Software Testing Verification and Validation Workshop,
+ 2008. ICSTW '08. IEEE International Conference on},
+ year = 2008,
+ month = {April},
+ pages = {196--209},
+ keywords = {data analysis, program testingsearch-based test data
+ generation, test adequacy criterion, testability
+ transformation},
+ doi = {10.1109/ICSTW.2008.30},
+ issn = {978-0-7695-3388-9},
+ abstract = {Testability transformation (tetra) seeks to transform a
+ program in order to make it easier to generate test data.
+ The test data is generated from the transformed version of
+ the program, but it is applied to the original version for
+ testing purposes. A transformation is a testability
+ transformation with respect to a test adequacy criterion if
+ all test data that is adequate for the transformed program
+ is also adequate for the untransformed program. Testability
+ transformation has been shown to be effective at improving
+ coverage for search based test data generation. However,
+ there are many interesting open problems. This paper
+ presents some of these open problems. The aim is to show
+ how testability transformation can be applied to a wide
+ range of testing scenarios.}
+}
+
+@InProceedings{ harman.ea:testability:2008,
+ author = {Mark Harman and Andr{\'e} Baresel and David Binkley and
+ Robert M. Hierons and Lin Hu and Bogdan Korel and Phil
+ McMinn and Marc Roper},
+ title = {Testability Transformation - Program Transformation to
+ Improve Testability},
+ booktitle = {Formal Methods and Testing},
+ year = 2008,
+ pages = {320--344},
+ doi = {10.1007/978-3-540-78917-8_11},
+ crossref = {hierons.ea:formal:2008}
+}
+
+@InProceedings{ veanes.ea:model-based:2008,
+ author = {Margus Veanes and Colin Campbell and Wolfgang Grieskamp
+ and Wolfram Schulte and Nikolai Tillmann and Lev
+ Nachmanson},
+ title = {Model-Based Testing of Object-Oriented Reactive Systems
+ with Spec Explorer},
+ booktitle = {Formal Methods and Testing},
+ year = 2008,
+ pages = {39--76},
+ doi = {10.1007/978-3-540-78917-8_2},
+ abstract = {},
+ crossref = {hierons.ea:formal:2008}
+}
+
+@Proceedings{ hierons.ea:formal:2008,
+ editor = {Robert M. Hierons and Jonathan P. Bowen and Mark Harman},
+ title = {Formal Methods and Testing, An Outcome of the FORTEST
+ Network, Revised Selected Papers},
+ booktitle = {Formal Methods and Testing},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 4949,
+ year = 2008,
+ isbn = {978-3-540-78916-1}
+}
+
+@Booklet{ omg:uml-infrastructure:2009,
+ bibkey = {omg:uml-infrastructure:2009},
+ key = omg,
+ publisher = omg,
+ language = {USenglish},
+ note = {Available as \acs{omg} document
+ \href{http://www.omg.org/cgi-bin/doc?formal/2009-02-04}
+ {formal/2009-02-04}},
+ keywords = {\acs{uml}},
+ topic = {formalism},
+ public = {yes},
+ title = {\acs{uml} 2.2 Infrastructure Specification},
+ year = 2009
+}
+
+@InProceedings{ pirretti.ea:secure:2006,
+ author = {Matthew Pirretti and Patrick Traynor and Patrick McDaniel
+ and Brent Waters},
+ title = {Secure attribute-based systems},
+ booktitle = PROC # {ACM conference on
+ Computer and communications security (CCS)},
+ year = 2006,
+ isbn = {1-59593-518-5},
+ pages = {99--112},
+ location = {Alexandria, Virginia, USA},
+ doi = {10.1145/1180405.1180419},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ abstract = {Attributes define, classify, or annotate the datum to
+ which they are assigned. However, traditional attribute
+ architectures and cryptosystems are ill-equipped to provide
+ security in the face of diverse access requirements and
+ environments. In this paper, we introduce a novel secure
+ information management architecture based on emerging
+ attribute-based encryption (ABE) primitives. A policy
+ system that meets the needs of complex policies is defined
+ and illustrated. Based on the needs of those policies, we
+ propose cryptographic optimizations that vastly improve
+ enforcement efficiency. We further explore the use of such
+ policies in two example applications: a HIPAA compliant
+ distributed file system and a social network. A performance
+ analysis of our ABE system and example applications
+ demonstrates the ability to reduce cryptographic costs by
+ as much as 98\% over previously proposed constructions.
+ Through this, we demonstrate that our attribute system is
+ an efficient solution for securely managing information in
+ large, loosely-coupled, distributed systems.}
+}
+
+@Article{ milicev:semantics:2007,
+ bibkey = {milicev:semantics:2007},
+ title = {On the Semantics of Associations and Association Ends in
+ UML},
+ author = {Dragan Milicev},
+ journal = {IEEE Transactions on Software Engineering},
+ year = 2007,
+ month = apr,
+ volume = 33,
+ number = 4,
+ pages = {238--251},
+ keywords = {Unified Modeling Language, entity-relationship modelling,
+ formal specification, object-oriented programming,
+ programming language semanticsUML, Unified Modeling
+ Language, association end, conceptual modeling, formal
+ semantics, formal specification, intentional
+ interpretation, object-oriented modeling},
+ doi = {10.1109/TSE.2007.37},
+ issn = {0098-5589}
+}
+
+@InProceedings{ bierman.ea:first-class:2005,
+ author = {Gavin M. Bierman and Alisdair Wren},
+ title = {First-Class Relationships in an Object-Oriented Language},
+ booktitle = {ECOOP},
+ year = 2005,
+ pages = {262--286},
+ doi = {10.1007/11531142_12},
+ crossref = {black:ecoop:2005}
+}
+
+@Proceedings{ black:ecoop:2005,
+ editor = {Andrew P. Black},
+ title = {ECOOP 2005 - Object-Oriented Programming, 19th European
+ Conference, Glasgow, UK, July 25-29, 2005, Proceedings},
+ booktitle = {ECOOP},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 3586,
+ year = 2005,
+ isbn = {3-540-27992-X}
+}
+
+@Article{ shafiq.ea:secure:2005,
+ title = {Secure interoperation in a multidomain environment
+ employing RBAC policies},
+ author = {Basit Shafiq and James B.D. Joshi and Elisa Bertino and
+ Arif Ghafoor},
+ journal = j-tkde,
+ year = 2005,
+ month = nov,
+ volume = 17,
+ number = 11,
+ pages = {1557--1577},
+ keywords = {Internet, authorisation, integer programming, open systems
+ Internet-based enterprise, heterogeneous role-based access
+ control, integer programming, multidomain application
+ environment, optimality criterion, policy integration
+ framework, secure interoperation},
+ doi = {10.1109/TKDE.2005.185},
+ issn = {1041-4347}
+}
+
+@Article{ aedo.ea:rbac:2006,
+ volume = 11,
+ number = 4,
+ month = dec,
+ year = 2006,
+ title = {An {RBAC} Model-Based Approach to Specify the Access
+ Policies of Web-Based Emergency Information Systems},
+ author = {Ignacio Aedo and Paloma D{\'i}az and Daniel Sanz},
+ journal = {The International Journal of Intelligent Control and
+ Systems},
+ page = {272--283},
+ abstract = {One of the main design challenges of any Web-based
+ Emergency Management Information System (WEMIS) is the
+ diversity of users and responsibilities to be considered.
+ Modelling the access capabilities of different communities
+ of users is a most relevant concern for which the RBAC
+ (Role-Based Access Control) paradigm provides flexible and
+ powerful constructs. In this paper we describe how we used
+ an RBAC model-based approach to specify at different levels
+ of abstraction the access policy of a specific WEMIS called
+ ARCE (Aplicaci{\`o}n en Red para Casos de Emergencia). This
+ approach made possible to face access modelling at earlier
+ development stages, so that stakeholders got involved in
+ analytical and empirical evaluations to test the
+ correctness and completeness of the access policy.
+ Moreover, since the RBAC meta-model is embedded into a web
+ engineering method, we put in practice a holistic process
+ addressing different design perspectives in an integrated
+ way. }
+}
+
+@InProceedings{ phillips.ea:information:2002,
+ author = {Charles E. Phillips, Jr. and T.C. Ting and Steven A.
+ Demurjian},
+ title = {Information sharing and security in dynamic coalitions},
+ booktitle = {SACMAT '02: Proceedings of the seventh ACM symposium on
+ Access control models and technologies},
+ year = 2002,
+ isbn = {1-58113-496-7},
+ pages = {87--96},
+ location = {Monterey, California, USA},
+ doi = {10.1145/507711.507726},
+ address = pub-acm:adr,
+ publisher = pub-acm
+}
+
+@InProceedings{ martino.ea:multi-domain:2008,
+ title = {Multi-domain and privacy-aware role based access control
+ in eHealth},
+ author = {Lorenzo D. Martino and Qun Ni and Dan Lin and Elisa
+ Bertino},
+ booktitle = {Second International Conference on Pervasive Computing
+ Technologies for Healthcare (PervasiveHealth 2008)},
+ year = 2008,
+ month = {30 2008-Feb. 1},
+ pages = {131--134},
+ keywords = {authorisation, data privacy, health care, medical
+ information systemseHealth, electronic medical/health
+ records, healthcare professionals, multidomain
+ privacy-aware role based access control, patient safety,
+ privacy preserving,},
+ doi = {10.1109/PCTHEALTH.2008.4571050}
+}
+
+@InProceedings{ kamath.ea:user-credential:2006,
+ author = {Ajith Kamath and Ramiro Liscano and Abdulmotaleb El
+ Saddik},
+ title = {User-credential based role mapping in multi-domain
+ environment},
+ booktitle = {PST '06: Proceedings of the 2006 International Conference
+ on Privacy, Security and Trust},
+ year = 2006,
+ isbn = {1-59593-604-1},
+ pages = {1--1},
+ location = {Markham, Ontario, Canada},
+ doi = {10.1145/1501434.1501507},
+ address = pub-acm:adr,
+ publisher = pub-acm
+}
+
+@Article{ geethakumari.ea:cross:2009,
+ journal = {International Journal of Computer Science \& Applications},
+ title = {A Cross -- Domain Role Mapping and Authorization Framework
+ for {RBAC} in Grid Systems.},
+ year = 2009,
+ volume = {VI},
+ issue = {I},
+ author = {G. Geethakumari and Atul Negi and V. N. Sastry},
+ issn = {0972-9038}
+}
+
+@InProceedings{ gogolla.ea:benchmark:2008,
+ author = {Martin Gogolla and Mirco Kuhlmann and Fabian B{\"u}ttner},
+ title = {A Benchmark for \acs{ocl} Engine Accuracy,
+ Determinateness, and Efficiency},
+ booktitle = {MoDELS},
+ year = 2008,
+ pages = {446--459},
+ doi = {10.1007/978-3-540-87875-9_32},
+ crossref = {czarnecki.ea:models:2008},
+ abstract = {The Object Constraint Language (OCL) is a central element
+ in modeling and transformation languages like UML, MOF, and
+ QVT. Consequently approaches for MDE (Model-Driven
+ Engineering) depend on OCL. However, OCL is present not
+ only in these areas influenced by the OMG but also in the
+ Eclipse Modeling Framework (EMF). Thus the quality of OCL
+ and its realization in tools seems to be crucial for the
+ success of model-driven development. Surprisingly, up to
+ now a benchmark for OCL to measure quality properties has
+ not been proposed. This paper puts forward in the first
+ part the concepts of a comprehensive OCL benchmark. Our
+ benchmark covers (A) OCL engine accuracy (e.g., for the
+ undefined value and the use of variables), (B) OCL engine
+ determinateness properties (e.g., for the collection
+ operations any and flatten), and (C) OCL engine efficiency
+ (for data type and user-defined operations). In the second
+ part, this paper empirically evaluates the proposed
+ benchmark concepts by examining a number of OCL tools. The
+ paper discusses several differences in handling particular
+ OCL language features and underspecifications in the OCL
+ standard.}
+}
+
+@InProceedings{ gessenharter:mapping:2008,
+ author = {Dominik Gessenharter},
+ title = {Mapping the {UML2} Semantics of Associations to a {Java}
+ Code Generation Model},
+ booktitle = {MoDELS},
+ year = 2008,
+ pages = {813--827},
+ doi = {10.1007/978-3-540-87875-9_56},
+ crossref = {czarnecki.ea:models:2008}
+}
+
+@Proceedings{ czarnecki.ea:models:2008,
+ editor = {Krzysztof Czarnecki and Ileana Ober and Jean-Michel Bruel
+ and Axel Uhl and Markus V{\"o}lter},
+ title = {Model Driven Engineering Languages and Systems, 11th
+ International Conference, MoDELS 2008, Toulouse, France,
+ September 28 - October 3, 2008. Proceedings},
+ booktitle = {MoDELS},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 5301,
+ year = 2008,
+ isbn = {978-3-540-87874-2}
+}
+
+@Article{ aalst.ea:workflow:2003,
+ author = {Wil M. P. van der Aalst and Arthur H. M. ter Hofstede and
+ Bartek Kiepuszewski and Alistair P. Barros},
+ title = {Workflow Patterns},
+ journal = {Distributed and Parallel Databases},
+ volume = 14,
+ number = 1,
+ year = 2003,
+ pages = {5--51},
+ doi = {10.1023/A:1022883727209},
+ abstract = {Differences in features supported by the various
+ contemporary commercial workflow management systems point
+ to different insights of suitability and different levels
+ of expressive power. The challenge, which we undertake in
+ this paper, is to systematically address workflow
+ requirements, from basic to complex. Many of the more
+ complex requirements identified, recur quite frequently in
+ the analysis phases of workflow projects, however their
+ implementation is uncertain in current products.
+ Requirements for workflow languages are indicated through
+ workflow patterns. In this context, patterns address
+ business requirements in an imperative workflow style
+ expression, but are removed from specific workflow
+ languages. The paper describes a number of workflow
+ patterns addressing what we believe identify comprehensive
+ workflow functionality. These patterns provide the basis
+ for an in-depth comparison of a number of commercially
+ availablework flow management systems. As such, this paper
+ can be seen as the academic response to evaluations made by
+ prestigious consulting companies. Typically, these
+ evaluations hardly consider the workflow modeling language
+ and routing capabilities, and focus more on the purely
+ technical and commercial aspects.}
+}
+
+@InProceedings{ chalin.ea:non-null:2005,
+ author = {Patrice Chalin and Fr\'{e}d\'{e}ric Rioux},
+ title = {Non-null references by default in the {Java} modeling
+ language},
+ booktitle = {SAVCBS '05: Proceedings of the 2005 conference on
+ Specification and verification of component-based systems},
+ year = 2005,
+ isbn = {1-59593-371-9},
+ pages = 9,
+ location = {Lisbon, Portugal},
+ doi = {10.1145/1123058.1123068},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ abstract = {Based on our experiences and those of our peers, we
+ hypothesized that in Java code, the majority of
+ declarations that are of reference types are meant to be
+ non-null. Unfortunately, the Java Modeling Language (JML),
+ like most interface specification and object-oriented
+ programming languages, assumes that such declarations are
+ possibly-null by default. As a consequence, developers need
+ to write specifications that are more verbose than
+ necessary in order to accurately document their module
+ interfaces. In practice, this results in module interfaces
+ being left incompletely and inaccurately specified. In this
+ paper we present the results of a study that confirms our
+ hypothesis. Hence, we propose an adaptation to JML that
+ preserves its language design goals and that allows
+ developers to specify that declarations of reference types
+ are to be interpreted as non-null by default. We explain
+ how this default is safer and results in less writing on
+ the part of specifiers than null-by-default. The paper also
+ reports on an implementation of the proposal in some of the
+ JML tools.}
+}
+
+@Article{ ekman.ea:pluggable:2007,
+ author = {Torbj{\"o}rn Ekman and G{\"o}rel Hedin},
+ title = {Pluggable checking and inferencing of nonnull types for
+ {Java}},
+ journal = {Journal of Object Technology},
+ volume = 6,
+ number = 9,
+ year = 2007,
+ pages = {455--475},
+ ee = {http://www.jot.fm/issues/issue_2007_10/paper23/index.html}
+
+}
+
+@InProceedings{ fahndrich.ea:declaring:2003,
+ author = {Manuel F{\"a}hndrich and K. Rustan M. Leino},
+ title = {Declaring and checking non-null types in an
+ object-oriented language},
+ booktitle = {OOPSLA},
+ year = 2003,
+ pages = {302--312},
+ doi = {10.1145/949305.949332},
+ crossref = {crocker.ea:proceedings:2003}
+}
+
+@Proceedings{ crocker.ea:proceedings:2003,
+ editor = {Ron Crocker and Guy L. Steele Jr.},
+ title = PROC # { the 2003 ACM SIGPLAN Conference on
+ Object-Oriented Programming Systems, Languages and
+ Applications, OOPSLA 2003, October 26-30, 2003, Anaheim,
+ CA, USA},
+ booktitle = {OOPSLA},
+ year = 2003,
+ isbn = {1-58113-712-5},
+ address = pub-acm:adr,
+ publisher = pub-acm
+}
+
+@InProceedings{ lee.ea:lightweight:2007,
+ author = {Hannah K. Lee and Heiko and Luedemann},
+ title = {lightweight decentralized authorization model for
+ inter-domain collaborations},
+ booktitle = {SWS '07: Proceedings of the 2007 ACM workshop on Secure
+ web services},
+ year = 2007,
+ isbn = {978-1-59593-892-3},
+ pages = {83--89},
+ location = {Fairfax, Virginia, USA},
+ doi = {10.1145/1314418.1314431},
+ address = pub-acm:adr,
+ publisher = pub-acm
+}
+
+@InProceedings{ freudenthal.ea:drbac:2002,
+ title = {{dRBAC}: distributed role-based access control for dynamic
+ coalition environments},
+ author = {Freudenthal, E. and Pesin, T. and Port, L. and Keenan, E.
+ and Karamcheti, V.},
+ journal = {Distributed Computing Systems, 2002. Proceedings. 22nd
+ International Conference on},
+ year = 2002,
+ pages = {411--420},
+ keywords = {authorisation, distributed processing PKI identities,
+ continuous monitoring, controlled activities, credential
+ discovery, credential validation, dRBAC, distributed
+ role-based access control, dynamic coalition environments,
+ graph approach, long-lived interactions, multiple
+ administrative domains, namespaces, policy roots, role
+ delegation, scalable decentralized access control
+ mechanism, scalable decentralized trust-management
+ mechanism, scalar valued attributes, third-party
+ delegation, transferred permissions, trust domains, trust
+ relationships},
+ doi = {10.1109/ICDCS.2002.1022279},
+ issn = {1063-6927 },
+ abstract = {distributed role-based access control (dRBAC) is a
+ scalable, decentralized trust-management and access-control
+ mechanism for systems that span multiple administrative
+ domains. dRBAC utilizes PKI identities to define trust
+ domains, roles to define controlled activities, and role
+ delegation across domains to represent permissions to these
+ activities. The mapping of controlled actions to roles
+ enables their namespaces to serve as policy roots. dRBAC
+ distinguishes itself from previous approaches by providing
+ three features: (1) third-party delegation of roles from
+ outside a domain's namespace, relying upon an explicit
+ delegation of assignment; (2) modulation of transferred
+ permissions using scalar valued attributes associated with
+ roles; and (3) continuous monitoring of trust relationships
+ over long-lived interactions. The paper describes the dRBAC
+ model and its scalable implementation using a graph
+ approach to credential discovery and validation.}
+}
+
+@Article{ liu.ea:role-based:2004,
+ author = {Duen-Ren Liu and Mei-Yu Wu and Shu-Teng Lee},
+ title = {Role-based authorizations for workflow systems in support
+ of task-based separation of duty},
+ journal = {Journal of Systems and Software},
+ volume = 73,
+ number = 3,
+ year = 2004,
+ pages = {375--387},
+ doi = {10.1016/S0164-1212(03)00175-4},
+ abstract = {Role-based authorizations for assigning tasks of workflows
+ to roles/users are crucial to security management in
+ workflow management systems. The authorizations must
+ enforce separation of duty (SoD) constraints to prevent
+ fraud and errors. This work analyzes and defines several
+ duty-conflict relationships among tasks, and designs
+ authorization rules to enforce SoD constraints based on the
+ analysis. A novel authorization model that incorporates
+ authorization rules is then proposed to support the
+ planning of assigning tasks to roles/users, and the
+ run-time activation of tasks. Different from existing work,
+ the proposed authorization model considers the AND/XOR
+ split structures of workflows and execution dependency
+ among tasks to enforce separation of duties in assigning
+ tasks to roles/users. A prototype system is developed to
+ realize the effectiveness of the proposed authorization
+ model.}
+}
+
+@Booklet{ nipkow.ea:isabelle-hol:2009,
+ title = {{Isabelle's} Logic: {HOL}},
+ author = {Tobias Nipkow and Lawrence C. Paulson and Markus Wenzel},
+ year = 2009,
+ misc = {\url{http://isabelle.in.tum.de/library/HOL/}}
+}
+
+@InProceedings{ garson.ea:security:2008,
+ author = {Garson, Kathryn and Adams, Carlisle},
+ title = {Security and privacy system architecture for an e-hospital
+ environment},
+ booktitle = {IDtrust '08: Proceedings of the 7th symposium on Identity
+ and trust on the Internet},
+ year = 2008,
+ isbn = {978-1-60558-066-1},
+ pages = {122--130},
+ location = {Gaithersburg, Maryland},
+ doi = {10.1145/1373290.1373306},
+ address = pub-acm:adr,
+ publisher = pub-acm
+}
+
+@Article{ kambourakis.ea:pki-based:2005,
+ author = {G. Kambourakis and I. Maglogiannis and A. Rouskas},
+ title = {PKI-based secure mobile access to electronic health
+ services and data},
+ journal = {Technology and Health Care Journal},
+ volume = 13,
+ number = 6,
+ year = 2005,
+ issn = {0928-7329},
+ pages = {511--526},
+ publisher = pub-ios,
+ address = pub-ios:adr,
+ abstract = {Recent research works examine the potential employment of
+ public-key cryptography schemes in e-health environments.
+ In such systems, where a Public Key Infrastructure (PKI) is
+ established beforehand, Attribute Certificates (ACs) and
+ public key enabled protocols like TLS, can provide the
+ appropriate mechanisms to effectively support
+ authentication, authorization and confidentiality services.
+ In other words, mutual trust and secure communications
+ between all the stakeholders, namely physicians, patients
+ and e-health service providers, can be successfully
+ established and maintained. Furthermore, as the recently
+ introduced mobile devices with access to computer-based
+ patient record systems are expanding, the need of
+ physicians and nurses to interact increasingly with such
+ systems arises. Considering public key infrastructure
+ requirements for mobile online health networks, this paper
+ discusses the potential use of Attribute Certificates (ACs)
+ in an anticipated trust model. Typical trust interactions
+ among doctors, patients and e-health providers are
+ presented, indicating that resourceful security mechanisms
+ and trust control can be obtained and implemented. The
+ application of attribute certificates to support medical
+ mobile service provision along with the utilization of the
+ de-facto TLS protocol to offer competent confidentiality
+ and authorization services is also presented and evaluated
+ through experimentation, using both the 802.11 WLAN and
+ General Packet Radio Service (GPRS) networks.}
+}
+
+@InProceedings{ sahai.ea:fuzzy:2005,
+ author = {Amit Sahai and Brent Waters},
+ title = {Fuzzy Identity-Based Encryption},
+ year = 2005,
+ pages = {457--473},
+ doi = {10.1007/11426639_27},
+ crossref = {cramer:advances:2005},
+ abstract = {We introduce a new type of Identity-Based Encryption (IBE)
+ scheme that we call Fuzzy Identity-Based Encryption. In
+ Fuzzy IBE we view an identity as set of descriptive
+ attributes. A Fuzzy IBE scheme allows for a private key for
+ an identity, ohgr, to decrypt a ciphertext encrypted with
+ an identity, ohgr prime, if and only if the identities ohgr
+ and ohgr prime are close to each other as measured by the
+ ldquoset overlaprdquo distance metric. A Fuzzy IBE scheme
+ can be applied to enable encryption using biometric inputs
+ as identities; the error-tolerance property of a Fuzzy IBE
+ scheme is precisely what allows for the use of biometric
+ identities, which inherently will have some noise each time
+ they are sampled. Additionally, we show that Fuzzy-IBE can
+ be used for a type of application that we term
+ ldquoattribute-based encryptionrdquo. In this paper we
+ present two constructions of Fuzzy IBE schemes. Our
+ constructions can be viewed as an Identity-Based Encryption
+ of a message under several attributes that compose a
+ (fuzzy) identity. Our IBE schemes are both error-tolerant
+ and secure against collusion attacks. Additionally, our
+ basic construction does not use random oracles. We prove
+ the security of our schemes under the Selective-ID security
+ model. }
+}
+
+@Proceedings{ cramer:advances:2005,
+ editor = {Ronald Cramer},
+ booktitle = PROC # {International Conference on the Theory and Applications of
+ Cryptographic Techniques (EUROCRYPT)},
+ location = {Advances in Cryptology - EUROCRYPT 2005, 24th Annual
+ International Conference on the Theory and Applications of
+ Cryptographic Techniques, Aarhus, Denmark, May 22-26, 2005,
+ Proceedings},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 3494,
+ year = 2005,
+ isbn = {3-540-25910-4}
+}
+
+@InProceedings{ goyal.ea:attribute-based:2006,
+ author = {Vipul Goyal and Omkant Pandey and Amit Sahai and Brent
+ Waters},
+ title = {Attribute-based encryption for fine-grained access control
+ of encrypted data},
+ booktitle = {CCS '06: Proceedings of the 13th ACM conference on
+ Computer and communications security},
+ year = 2006,
+ isbn = {1-59593-518-5},
+ pages = {89--98},
+ location = {Alexandria, Virginia, USA},
+ doi = {10.1145/1180405.1180418},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ abstract = {As more sensitive data is shared and stored by third-party
+ sites on the Internet, there will be a need to encrypt data
+ stored at these sites. One drawback of encrypting data, is
+ that it can be selectively shared only at a coarse-grained
+ level (i.e., giving another party your private key). We
+ develop a new cryptosystem for fine-grained sharing of
+ encrypted data that we call Key-Policy Attribute-Based
+ Encryption (KP-ABE). In our cryptosystem, ciphertexts are
+ labeled with sets of attributes and private keys are
+ associated with access structures that control which
+ ciphertexts a user is able to decrypt. We demonstrate the
+ applicability of our construction to sharing of audit-log
+ information and broadcast encryption. Our construction
+ supports delegation of private keys which
+ subsumesHierarchical Identity-Based Encryption (HIBE).}
+}
+
+@InProceedings{ li.ea:privacy-aware:2009,
+ author = {Jin Li and Kui Ren and Bo Zhu and Zhiguo Wan},
+ title = {Privacy-aware Attribute-based Encryption with User
+ Accountability},
+ booktitle = {The 12th Information Security Conference (ISC'09)},
+ location = {September 7-9, 2009, Pisa},
+ year = 2009,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ abstract = {As a new public key primitive, attribute-based encryption
+ (ABE) is envisioned to be a promising tool for implementing
+ fine-grained access control. To further address the concern
+ of user access privacy, privacy-aware ABE schemes are being
+ developed to achieve hidden access policy recently. For the
+ purpose of secure access control, there is, how- ever,
+ still one critical functionality missing in the existing
+ ABE schemes, which is user accountability. Currently, no
+ ABE scheme can completely prevent the problem of illegal
+ key sharing among users. In this paper, we tackle this
+ problem by firstly proposing the notion of accountable,
+ anonymous, and ciphertext-policy ABE (CP-A3 BE, in short)
+ and then giving out a concrete construction. We start by
+ improving the state-of-the-art of anonymous CP-ABE to
+ obtain shorter public parameters and ciphertext length. In
+ the proposed CP-A3 BE construction, user accountability can
+ be achieved in black-box model by embedding additional
+ user-specific information into the attribute private key
+ issued to that user, while still maintaining hidden access
+ policy. The proposed constructions are provably secure.}
+}
+
+@InProceedings{ bobba.ea:pbes:2009,
+ author = {Rakesh Bobba and and Himanshu Khurana and Musab AlTurki
+ and Farhana Ashraf},
+ title = {PBES: a policy based encryption system with application to
+ data sharing in the power grid},
+ booktitle = {ASIACCS '09: Proceedings of the 4th International
+ Symposium on Information, Computer, and Communications
+ Security},
+ year = 2009,
+ isbn = {978-1-60558-394-5},
+ pages = {262--275},
+ location = {Sydney, Australia},
+ doi = {10.1145/1533057.1533093},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ abstract = {In distributed systems users need the ability to share
+ sensitive content with multiple other recipients based on
+ their ability to satisfy arbitrary policies. One such
+ system is electricity grids where finegrained sensor data
+ sharing holds the potential for increased reliability and
+ efficiency. However, effective data sharing requires
+ technical solutions that support flexible access policies,
+ for example, sharing more data when the grid is unstable.
+ In such systems, both the messages and policies are
+ sensitive and, therefore, they need to kept be secret.
+ Furthermore, to allow for such a system to be secure and
+ usable in the presence of untrusted object stores and
+ relays it must be resilient in the presence of active
+ adversaries and provide efficient key management. While
+ several of these properties have been studied in the past
+ we address a new problem in the area of policy based
+ encryption in that we develop a solution with all of these
+ capabilities. We develop a Policy and Key Encapsulation
+ Mechanism -- Data Encapsulation Mechanism (PKEM-DEM)
+ encryption scheme that is a generic construction secure
+ against adaptive chosen ciphertext attacks and develop a
+ Policy Based Encryption System (PBES) using this scheme
+ that provides these capabilities. We provide an
+ implementation of PBES and measure its performance.}
+}
+
+@InProceedings{ shanqing.ea:attribute-based:2008,
+ author = {Guo Shanqing and Zeng Yingpei},
+ title = {Attribute-based Signature Scheme},
+ doi = {10.1109/ISA.2008.111},
+ booktitle = {International Conference on Information Security and
+ Assurance, 2008 (ISA 2008)},
+ year = 2008,
+ pages = {509--511},
+ month = apr,
+ address = pub-ieee:adr,
+ publisher = pub-ieee,
+ abstract = {In real life, one requires signatures from people who
+ satisfy certain criteria like that they should possess some
+ specific attributes. For example, Alice wants a document to
+ be signed by some employee in Bob's company. This employee
+ must have certain attributes such as being part of the IT
+ staff and at least a junior manager in the cryptography
+ team or a senior manager in the biometrics team. In order
+ to satisfy these kinds of needs, we defined a common
+ Attribute-based signature scheme where the signing member
+ has to have certain attributes or belong to a certain
+ group, and we also proved our scheme to be secure.}
+}
+
+@Article{ huang.ea:aspe:2009,
+ title = {ASPE: attribute-based secure policy enforcement in
+ vehicular ad hoc networks},
+ journal = {Ad Hoc Networks},
+ volume = 7,
+ number = 8,
+ pages = {1526--1535},
+ year = 2009,
+ mynote = {Privacy and Security in Wireless Sensor and Ad Hoc
+ Networks},
+ issn = {1570-8705},
+ doi = {10.1016/j.adhoc.2009.04.011},
+ author = {Dijiang Huang and Mayank Verma},
+ keywords = {Security, Vehicular networks, Secure group communications,
+ Key management, Attribute based encryption},
+ publisher = pub-elsevier,
+ address = pub-elsevier:adr,
+ abstract = {Vehicular ad hoc networks (VANETs) are usually operated
+ among vehicles moving at high speeds, and thus their
+ communication relations can be changed frequently. In such
+ a highly dynamic environment, establishing trust among
+ vehicles is difficult. To solve this problem, we propose a
+ flexible, secure and decentralized attribute based secure
+ key management framework for VANETs. Our solution is based
+ on attribute based encryption (ABE) to construct an
+ attribute based security policy enforcement (ASPE)
+ framework. ASPE considers various road situations as
+ attributes. These attributes are used as encryption keys to
+ secure the transmitted data. ASPE is flexible in that it
+ can dynamically change encryption keys depending on the
+ VANET situations. At the same time, ASPE naturally
+ incorporates data access control policies on the
+ transmitted data. ASPE provides an integrated solution to
+ involve data access control, key management, security
+ policy enforcement, and secure group formation in highly
+ dynamic vehicular communication environments. Our
+ performance evaluations show that ASPE is efficient and it
+ can handle large amount of data encryption/decryption flows
+ in VANETs.}
+}
+
+@InProceedings{ weber:securing:2009,
+ author = {Stefan G. Weber},
+ title = {Securing First Response Coordination With Dynamic
+ Attribute-Based Encryption},
+ booktitle = {World Congress on Privacy, Security, Trust and the
+ Management of e-Business (CONGRESS)},
+ year = 2009,
+ pages = {58--69},
+ isbn = {978-0-7695-3805-1},
+ address = pub-ieee:adr,
+ publisher = pub-ieee,
+ abstract = {Every minute saved in emergency management processes can
+ save additional lives of affected victims. Therefore, an
+ effective coordination of the incident reactions of mobile
+ first responders is very important, especially in the face
+ of rapidly changing situations of large scale disasters.
+ However, tactical communication and messaging between the
+ headquarter and mobile first responders, initiated for
+ coordination purposes, has to meet a strong security
+ requirements: it must preserve confidentiality in order to
+ prevent malicious third parties from disrupting the
+ reactions. This paper presents concepts to support the
+ secure coordination of mobile first responders by providing
+ means for secure ubiquitous tactical communication. Our
+ concept harnesses ciphertext-policy attribute-based
+ encryption (CP-ABE) techniques. We extend current CP-ABE
+ proposals by additionally taking into account dynamic
+ factors: our proposed system is able to handle dynamic
+ attributes, like current status of duty and location of
+ mobile first responders, in a secure fashion, in order to
+ support flexible specification of receiver groups of
+ tactical messages, while end-to-end encryption in the
+ messaging process is still satisfied.}
+}
+
+@InProceedings{ cardoso:approaches:2006,
+ author = {Jorge Cardoso},
+ title = {Approaches to Compute Workflow Complexity},
+ booktitle = {The Role of Business Processes in Service Oriented
+ Architectures},
+ year = 2006,
+ ee = {http://drops.dagstuhl.de/opus/volltexte/2006/821},
+ crossref = {leymann.ea:role:2006},
+ abstract = {During the last 20 years, complexity has been an
+ interesting topic that has been investigated in many fields
+ of science, such as biology, neurology, software
+ engineering, chemistry, psychology, and economy. A survey
+ of the various approaches to understand complexity has lead
+ sometimes to a measurable quantity with a rigorous but
+ narrow definition and other times as merely an ad hoc
+ label. In this paper we investigate the complexity concept
+ to avoid a vague use of the term `complexity' in workflow
+ designs. We present several complexity metrics that have
+ been used for a number of years in adjacent fields of
+ science and explain how they can be adapted and use to
+ evaluate the complexity of workflows. }
+}
+
+@Proceedings{ leymann.ea:role:2006,
+ editor = {Frank Leymann and Wolfgang Reisig and Satish R. Thatte and
+ Wil M. P. van der Aalst},
+ title = {The Role of Business Processes in Service Oriented
+ Architectures, 16.07. - 21.07.2006},
+ booktitle = {The Role of Business Processes in Service Oriented
+ Architectures},
+ publisher = {Internationales Begegnungs- und Forschungszentrum fuer
+ Informatik (IBFI), S chloss Dagstuhl, Germany},
+ series = {Dagstuhl Seminar Proceedings},
+ volume = 06291,
+ year = 2006
+}
+
+@Article{ parnas:stop:2007,
+ author = {David Lorge Parnas},
+ title = {Stop the numbers game},
+ journal = j-cacm,
+ volume = 50,
+ number = 11,
+ year = 2007,
+ issn = {0001-0782},
+ pages = {19--21},
+ doi = {10.1145/1297797.1297815},
+ address = pub-acm:adr,
+ publisher = pub-acm
+}
+
+
+
+
+@InBook{ gentry:ibe:2006,
+ author = {Craig Gentry},
+ chapter = {IBE (Identity-Based Encryption)},
+ title = {Handbook of Information Security},
+ editor = {Hossein Bidgoli},
+ volume = 2,
+ isbn = {0-471-64833-7},
+ publisher = {John Wiley \& Sons},
+ pages = {575--592},
+ month = jan,
+ year = 2006
+}
+
+@InProceedings{ bethencourt.ea:ciphertext-policy:2007,
+ author = {John Bethencourt and Amit Sahai and Brent Waters},
+ title = {Ciphertext-Policy Attribute-Based Encryption},
+ booktitle = {IEEE Symposium on Security and Privacy},
+ pages = {321--334},
+ year = 2007,
+ doi = {10.1109/SP.2007.11},
+ abstract = {In several distributed systems a user should only be able
+ to access data if a user posses a certain set of
+ credentials or attributes. Currently, the only method for
+ enforcing such policies is to employ a trusted server to
+ store the data and mediate access control. However, if any
+ server storing the data is compromised, then the
+ confidentiality of the data will be compromised. In this
+ paper we present a system for realizing complex access
+ control on encrypted data that we call ciphertext-policy
+ attribute-based encryption. By using our techniques
+ encrypted data can be kept confidential even if the storage
+ server is untrusted; moreover, our methods are secure
+ against collusion attacks. Previous attribute-based
+ encryption systems used attributes to describe the
+ encrypted data and built policies into user's keys; while
+ in our system attributes are used to describe a user's
+ credentials, and a party encrypting data determines a
+ policy for who can decrypt. Thus, our methods are
+ conceptually closer to traditional access control methods
+ such as role-based access control (RBAC). In addition, we
+ provide an implementation of our system and give
+ performance measurements.},
+ publisher = pub-ieee,
+ address = pub-ieee:adr
+}
+
+@Article{ karedla.ea:caching:1994,
+ author = {Ramakrishna Karedla and J. Spencer Love and Bradley G.
+ Wherry},
+ title = {Caching strategies to improve disk system performance},
+ journal = j-computer,
+ volume = 27,
+ number = 3,
+ issn = {0018-9162},
+ year = 1994,
+ pages = {38--46},
+ doi = {10.1109/2.268884},
+ publisher = pub-ieee,
+ address = pub-ieee:adr,
+ abstract = {I/O subsystem manufacturers attempt to reduce latency by
+ increasing disk rotation speeds, incorporating more
+ intelligent disk scheduling algorithms, increasing I/O bus
+ speed, using solid-state disks, and implementing caches at
+ various places in the I/O stream. In this article, we
+ examine the use of caching as a means to increase system
+ response time and improve the data throughput of the disk
+ subsystem. Caching can help to alleviate I/O subsystem
+ bottlenecks caused by mechanical latencies. This article
+ describes a caching strategy that offers the performance of
+ caches twice its size. After explaining some basic caching
+ issues, we examine some popular caching strategies and
+ cache replacement algorithms, as well as the advantages and
+ disadvantages of caching at different levels of the
+ computer system hierarchy. Finally, we investigate the
+ performance of three cache replacement algorithms: random
+ replacement (RR), least recently used (LRU), and a
+ frequency-based variation of LRU known as segmented LRU
+ (SLRU). }
+}
+
+@InProceedings{ megiddo.ea:arc:2003,
+ author = {Nimrod Megiddo and Dharmendra S. Modha},
+ title = {{ARC}: A Self-Tuning, Low Overhead Replacement Cache},
+ booktitle = {FAST '03: Proceedings of the 2nd USENIX Conference on File
+ and Storage Technologies},
+ year = 2003,
+ pages = {115--130},
+ location = {San Francisco, CA},
+ publisher = {\acs{usenix} Association},
+ address = {Berkeley, CA, USA}
+}
+
+@InProceedings{ chou.ea:evaluation:1985,
+ author = {Hong-Tai Chou and David J. DeWitt},
+ title = {An evaluation of buffer management strategies for
+ relational database systems},
+ booktitle = {VLDB '1985: Proceedings of the 11th international
+ conference on Very Large Data Bases},
+ year = 1985,
+ pages = {127--141},
+ location = {Stockholm, Sweden},
+ publisher = {VLDB Endowment}
+}
+
+@InProceedings{ yu.ea:fdac:2009,
+ author = {Shucheng Yu and Kui Ren and Wenjing Lou},
+ title = {{FDAC}: Toward fine-grained distributed data access
+ control in wireless sensor networks},
+ booktitle = PROC # { \acs{ieee} Conference on Computer
+ Communications (INFOCOM)},
+ year = 2009,
+ address = pub-ieee:adr,
+ publisher = pub-ieee,
+ abstract = {Distributed sensor data storage and retrieval has gained
+ increasing popularity in recent years for supporting
+ various applications. While distributed architecture enjoys
+ a more robust and fault-tolerant wireless sensor network
+ (WSN), such architecture also poses a number of security
+ challenges especially when applied in mission-critical
+ applications such as battle field and e-healthcare. First,
+ as sensor data are stored and maintained by individual
+ sensors and unattended sensors are easily subject to strong
+ attacks such as physical compromise, it is significantly
+ harder to ensure data security. Second, in many
+ mission-critical applications, fine-grained data access
+ control is a must as illegal access to the sensitive data
+ may cause disastrous result and/or prohibited by the law.
+ Last but not least, sensors usually are resource-scarce,
+ which limits the direct adoption of expensive cryptographic
+ primitives. To address the above challenges, we propose in
+ this paper a distributed data access control scheme that is
+ able to fulfill fine-grained access control over sensor
+ data and is resilient against strong attacks such as sensor
+ compromise and user colluding. The proposed scheme exploits
+ a novel cryptographic primitive called attribute-based
+ encryption (ABE), tailors, and adapts it for WSNs with
+ respect to both performance and security requirements. The
+ feasibility of the scheme is demonstrated by experiments on
+ real sensor platforms. To our best knowledge, this paper is
+ the first to realize distributed fine-grained data access
+ control for WSNs.}
+}
+
+@InProceedings{ traynor.ea:massive-scale:2008,
+ author = {Patrick Traynor and Kevin R. B. Butler and William Enck
+ and Patrick McDaniel},
+ title = {Realizing Massive-Scale Conditional Access Systems Through
+ Attribute-Based Cryptosystems},
+ booktitle = PROC # { 15th Annual Network and Distributed System
+ Security Symposium (NDSS 2008)},
+ year = 2008,
+ abstract = {The enormous growth in the diversity of content services
+ such as IPtv has highlighted the inadequacy of the
+ accompanying content security: existing security mechanisms
+ scale poorly, require complex and often costly dedicated
+ hardware, or fail to meet basic security requirements. New
+ security methods are needed. In this paper, we explore the
+ ability of attribute-based encryption (ABE) to meet the
+ unique performance and security requirements of conditional
+ access systems such as subscription radio and payper- view
+ television. We show through empirical study that costs of
+ ABE make its direct application inappropriate, but present
+ constructions that mitigate its incumbent costs. We develop
+ an extensive simulation that allows us to explore the
+ performance of a number of virtual hardware configurations
+ and construction parameters over workloads developed from
+ real subscription and television audiences. These
+ simulations show that we can securely deliver high quality
+ content to viewerships of the highest rated shows being
+ broadcast today, some in excess of 26,000,000 viewers. It
+ is through these experiments that we expose the viability
+ of not only ABE-based content delivery, but applicability
+ of ABE systems to large-scale distributed systems.},
+ url = {http://www.isoc.org/isoc/conferences/ndss/08/papers/06_realizing_massive-scale_conditional.pdf}
+ ,
+ location = {San Diego, California, USA},
+ month = feb,
+ publisher = {The Internet Society}
+}
+
+@Article{ alpern.ea:defining:1985,
+ author = {Bowen Alpern and Fred B. Schneider},
+ title = {Defining Liveness},
+ journal = j-ipl,
+ volume = 21,
+ number = 4,
+ year = 1985,
+ pages = {181--185}
+}
+
+@Article{ lamport:proving:1977,
+ title = {Proving the Correctness of Multiprocess Programs},
+ author = {Leslie Lamport},
+ journal = j-tse,
+ year = 1977,
+ month = {March},
+ volume = {SE-3},
+ number = 2,
+ pages = {125--143},
+ abstract = {The inductive assertion method is generalized to permit
+ formal, machine-verifiable proofs of correctness for
+ multiprocess programs. Individual processes are represented
+ by ordinary flowcharts, and no special synchronization
+ mechanisms are assumed, so the method can be applied to a
+ large class of multiprocess programs. A correctness proof
+ can be designed together with the program by a hierarchical
+ process of stepwise refinement, making the method practical
+ for larger programs. The resulting proofs tend to be
+ natural formalizations of the informal proofs that are now
+ used.},
+ keywords = {null Assertions, concufrent programming, correctness,
+ multiprocessing, synchronization},
+ doi = {10.1109/TSE.1977.229904},
+ issn = {0098-5589}
+}
+
+@InProceedings{ goodenough.ea:toward:1975,
+ author = {John B. Goodenough and Susan L. Gerhart},
+ title = {Toward a theory of test data selection},
+ booktitle = PROC # { the international conference on Reliable
+ software},
+ year = 1975,
+ pages = {493--510},
+ url = {http://portal.acm.org/citation.cfm?id=808473&dl=ACM&coll=GUIDE#}
+ ,
+ location = {Los Angeles, California},
+ abstract = {This paper examines the theoretical and practical role of
+ testing in software development. We prove a fundamental
+ theorem showing that properly structured tests are capable
+ of demonstrating the absence of errors in a program. The
+ theorem's proof hinges on our definition of test
+ reliability and validity, but its practical utility hinges
+ on being able to show when a test is actually reliable. We
+ explain what makes tests unreliable (for example, we show
+ by example why testing all program statements, predicates,
+ or paths is not usually sufficient to insure test
+ reliability), and we outline a possible approach to
+ developing reliable tests. We also show how the analysis
+ required to define reliable tests can help in checking a
+ program's design and specifications as well as in
+ preventing and detecting implementation errors. },
+ acknowledgement={none}
+}
+
+@InCollection{ aczel:introduction:1977,
+ author = {Peter Aczel},
+ title = {An Introduction to Inductive Definitions},
+ booktitle = {Handbook of Mathematical Logic},
+ editor = {Jon Barwise},
+ series = {Studies in Logic and the Foundations of Mathematics},
+ volume = 90,
+ chapter = {C.7},
+ pages = {739--782},
+ publisher = {North-Holland},
+ address = {Amsterdam},
+ year = 1977
+}
+
+@InProceedings{ cousot.ea:abstract:1977,
+ author = {Patrick Cousot and Radhia Cousot},
+ title = {Abstract interpretation: a unified lattice model for
+ static analysis of programs by construction or
+ approximation of fixpoints},
+ booktitle = PROC # { the 4th ACM SIGACT-SIGPLAN symposium on
+ Principles of programming languages},
+ year = 1977,
+ pages = {238--252},
+ location = {Los Angeles, California},
+ doi = {10.1145/512950.512973},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none}
+}
+
+@Article{ cardelli.ea:understanding:1985,
+ author = {Luca Cardelli and Peter Wegner},
+ title = {On understanding types, data abstraction, and
+ polymorphism},
+ journal = {ACM Computing Surveys},
+ volume = 17,
+ number = 4,
+ year = 1985,
+ issn = {0360-0300},
+ acknowledgement={none},
+ pages = {471--523},
+ doi = {10.1145/6041.6042},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {Our objective is to understand the notion of type in
+ programming languages, present a model of typed,
+ polymorphic programming languages that reflects recent
+ research in type theory, and examine the relevance of
+ recent research to the design of practical programming
+ languages. Object-oriented languages provide both a
+ framework and a motivation for exploring the interaction
+ among the concepts of type, data abstraction, and
+ polymorphism, since they extend the notion of type to data
+ abstraction and since type inheritance is an important form
+ of polymorphism. We develop a &lgr;-calculus-based model
+ for type systems that allows us to explore these
+ interactions in a simple setting, unencumbered by
+ complexities of production programming languages. The
+ evolution of languages from untyped universes to
+ monomorphic and then polymorphic type systems is reviewed.
+ Mechanisms for polymorphism such as overloading, coercion,
+ subtyping, and parameterization are examined. A unifying
+ framework for polymorphic type systems is developed in
+ terms of the typed &lgr;-calculus augmented to include
+ binding of types by quantification as well as binding of
+ values by abstraction. The typed &lgr;-calculus is
+ augmented by universal quantification to model generic
+ functions with type parameters, existential quantification
+ and packaging (information hiding) to model abstract data
+ types, and bounded quantification to model subtypes and
+ type inheritance. In this way we obtain a simple and
+ precise characterization of a powerful type system that
+ includes abstract data types, parametric polymorphism, and
+ multiple inheritance in a single consistent framework. The
+ mechanisms for type checking for the augmented
+ &lgr;-calculus are discussed. The augmented typed
+ &lgr;-calculus is used as a programming language for a
+ variety of illustrative examples. We christen this language
+ Fun because fun instead of &lgr; is the functional
+ abstraction keyword and because it is pleasant to deal
+ with. Fun is mathematically simple and can serve as a basis
+ for the design and implementation of real programming
+ languages with type facilities that are more powerful and
+ expressive than those of existing programming languages. In
+ afsyped object-oriented languages. }
+}
+
+@InProceedings{ wadler:listlessness:1985,
+ author = {Philip Wadler},
+ title = {Listlessness is better than laziness II: composing
+ listless functions},
+ booktitle = {on Programs as data objects},
+ year = 1985,
+ isbn = {0-387-16446-4},
+ pages = {282--305},
+ location = {Copenhagen, Denmark},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ acknowledgement={none}
+}
+
+@InProceedings{ clement.ea:simple:1986,
+ author = {Dominique Cl\'ement and Thierry Despeyroux and Gilles Kahn
+ and Jo\"elle Despeyroux},
+ title = {A simple applicative language: {mini-ML}},
+ booktitle = {LFP '86: Proceedings of the 1986 ACM conference on LISP
+ and functional programming},
+ year = 1986,
+ isbn = {0-89791-200-4},
+ pages = {13--27},
+ location = {Cambridge, Massachusetts, United States},
+ doi = {10.1145/319838.319847},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none}
+}
+
+@InProceedings{ hamlet:theoretical:1989,
+ author = {R. Hamlet},
+ title = {Theoretical comparison of testing methods},
+ booktitle = PROC # { the ACM SIGSOFT '89 third symposium on
+ Software testing, analysis, and verification},
+ year = 1989,
+ isbn = {0-89791-342-6},
+ pages = {28--37},
+ location = {Key West, Florida, United States},
+ doi = {10.1145/75308.75313},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none}
+}
+
+@Article{ frankl.ea:applicable:1988,
+ author = {P. G. Frankl and E. J. Weyuker},
+ title = {An Applicable Family of Data Flow Testing Criteria},
+ journal = j-ieee-tse,
+ volume = 14,
+ number = 10,
+ year = 1988,
+ month = oct,
+ issn = {0098-5589},
+ pages = {1483--1498},
+ doi = {http://dx.doi.org/10.1109/32.6194},
+ publisher = pub-ieee,
+ abstract = {he authors extend the definitions of the previously
+ introduced family of data flow testing criteria to apply to
+ programs written in a large subset of Pascal. They then
+ define a family of adequacy criteria called feasible data
+ flow testing criteria, which are derived from the data-flow
+ testing criteria. The feasible data flow testing criteria
+ circumvent the problem of nonapplicability of the data flow
+ testing criteria by requiring the test data to exercise
+ only those definition-use associations which are
+ executable. It is shown that there are significant
+ differences between the relationships among the data flow
+ testing criteria and the relationships among the feasible
+ data flow testing criteria. The authors discuss a
+ generalized notion of the executability of a path through a
+ program unit. A script of a testing session using their
+ data flow testing tool, ASSET, is included.},
+ acknowledgement={none}
+}
+
+@InProceedings{ teo.ea:use:1988,
+ author = {Ghee S. Teo and M\'{\i}che{\'a}l Mac an Airchinnigh},
+ title = {The Use of VDM in the Specification of Chinese
+ Characters.},
+ booktitle = {VDM Europe},
+ year = 1988,
+ pages = {476--499},
+ crossref = {bloomfield.ea:vdm:1988},
+ acknowledgement={none}
+}
+
+@Proceedings{ bloomfield.ea:vdm:1988,
+ editor = {Robin E. Bloomfield and Lynn S. Marshall and Roger B.
+ Jones},
+ title = {VDM '88, VDM - The Way Ahead, 2nd VDM-Europe Symposium,
+ Dublin, Ireland, September 11-16, 1988, Proceedings},
+ booktitle = {VDM Europe},
+ publisher = pub-springer,
+ series = lncs,
+ volume = 328,
+ year = 1988,
+ isbn = {3-540-50214-9},
+ acknowledgement={none},
+ bibkey = {bloomfield.ea:vdm:1988}
+}
+
+@InProceedings{ cook.ea:inheritance:1990,
+ author = {William R. Cook and Walter Hill and Peter S. Canning},
+ title = {Inheritance is not subtyping},
+ booktitle = {POPL '90: Proceedings of the 17th ACM SIGPLAN-SIGACT
+ symposium on Principles of programming languages},
+ year = 1990,
+ isbn = {0-89791-343-4},
+ pages = {125--135},
+ location = {San Francisco, California, United States},
+ doi = {10.1145/96709.96721},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none},
+ abstract = {In typed object-oriented languages the subtype relation is
+ typically based on the inheritance hierarchy. This
+ approach, however, leads either to insecure type-systems or
+ to restrictions on inheritance that make it less flexible
+ than untyped Smalltalk inheritance. We present a new typed
+ model of inheritance that allows more of the flexibility of
+ Smalltalk inheritance within a statically-typed system.
+ Significant features of our analysis are the introduction
+ of polymorphism into the typing of inheritance and the
+ uniform application of inheritance to objects, classes and
+ types. The resulting notion of type inheritance allows us
+ to show that the type of an inherited object is an
+ inherited type but not always a subtype. },
+ bibkey = {cook.ea:inheritance:1990}
+}
+
+@Article{ lynch.ea:forward:1996,
+ author = {Nancy Lynch and Frits Vaandrager},
+ title = {Forward and backward simulations II.: timing-based
+ systems},
+ journal = {Inf. Comput.},
+ volume = 128,
+ number = 1,
+ year = 1996,
+ issn = {0890-5401},
+ pages = {1--25},
+ doi = {10.1006/inco.1996.0060},
+ publisher = {Academic Press, Inc.},
+ acknowledgement={none},
+ bibkey = {lynch.ea:forward:1996}
+}
+
+@Article{ lamport.ea:should:1999,
+ author = {Leslie Lamport and Lawrence C. Paulson},
+ title = {Should your specification language be typed.},
+ journal = {ACM Trans. Program. Lang. Syst.},
+ volume = 21,
+ number = 3,
+ year = 1999,
+ acknowledgement={none},
+ pages = {502--526},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ issn = {0164-0925},
+ doi = {10.1145/319301.319317}
+}
+
+@InProceedings{ muller.ea:formal:1997,
+ title = {Formal Specification Techniques for Object-Oriented
+ Programs },
+ author = {Peter M{\"u}ller and Arnd Poetzsch-Heffter },
+ editor = {Jarke, M. and Pasedach, K. and Pohl, K. },
+ booktitle = {Informatik 97: Informatik als Innovationsmotor },
+ series = {Informatik Aktuell },
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ acknowledgement={none},
+ year = 1997,
+ abstract = {Specification techniques for object-oriented programs
+ relate the operational world of programs to the declarative
+ world of specifications. We present a formal foundation of
+ interface specification languages. Based on the formal
+ foundation, we develop new specification techniques to
+ describe functional behavior, invariants, and side-effects.
+ Furthermore, we discuss the influence of program extensions
+ on program correctness.}
+}
+
+@Article{ wolper:meaning:1997,
+ author = {Pierre Wolper},
+ title = {The Meaning of ``Formal'': From Weak to Strong Formal
+ Methods.},
+ journal = j-sttt,
+ volume = 1,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ number = {1-2},
+ year = 1997,
+ pages = {6--8},
+ doi = {10.1007/s100090050002},
+ acknowledgement={none}
+}
+
+@TechReport{ aredo.ea:towards:1999,
+ title = {Towards a formalization of {UML} Class Structure in
+ {PVS}},
+ author = {Demissie B. Aredo and I. Traore and K. St{\o}len},
+ institution = {Department of Informatics, University of Oslo},
+ year = 1999,
+ month = aug,
+ number = 272,
+ acknowledgement={none}
+}
+
+@Book{ derrick.ea:refinement:2001,
+ author = {John Derrick and Eerke Boiten},
+ title = {Refinement in {Z} and {Object-Z}},
+ library = {ETH-BIB},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ isbn = {1-85233-245-X},
+ url = {http://www.cs.kent.ac.uk/people/staff/jd1/books/refine/},
+ year = 2001,
+ acknowledgement={none},
+ bibkey = {derrick.ea:refinement:2001}
+}
+
+@TechReport{ boer.ea:towards:2003,
+ author = {Frank S. de Boer and Cees Pierik},
+ year = 2003,
+ title = {Towards an environment for the verification of annotated
+ object-oriented programs},
+ number = {UU-CS-2003-002},
+ institution = {Institute of Information and Computing Sciences, Utrecht
+ University},
+ acknowledgement={none}
+}
+
+@Article{ dybjer.ea:verifying:2004,
+ author = {Peter Dybjer and Qiao Haiyana and Makoto Takeyama},
+ booktitle = {Third International Conference on Quality Software: QSIC
+ 2003},
+ title = {Verifying Haskell programs by combining testing, model
+ checking and interactive theorem proving},
+ journal = {Information and Software Technology},
+ year = 2004,
+ number = 15,
+ volume = 46,
+ pages = {1011--1025},
+ doi = {10.1016/j.infsof.2004.07.002},
+ abstract = {We propose a program verification method that combines
+ random testing, model checking and interactive theorem
+ proving. Testing and model checking are used for debugging
+ programs and specifications before a costly interactive
+ proof attempt. During proof development, testing and model
+ checking quickly eliminate false conjectures and generate
+ counterexamples which help to correct them. With an
+ interactive theorem prover we also ensure the correctness
+ of the reduction of a top level problem to subproblems that
+ can be tested or proved. We demonstrate the method using
+ our random testing tool and binary decision diagrams-based
+ (BDDs) tautology checker, which are added to the Agda/Alfa
+ interactive proof assistant for dependent type theory. In
+ particular we apply our techniques to the verification of
+ Haskell programs. The first example verifies the BDD
+ checker itself by testing its components. The second uses
+ the tautology checker to verify bitonic sort together with
+ a proof that the reduction of the problem to the checked
+ form is correct.},
+ acknowledgement={none}
+}
+
+@PhDThesis{ kopylov:type:2004,
+ author = {Alexei Pavlovich Kopylov},
+ title = {Type Theoretical Foundations for Data Structures, Classes,
+ and Objects},
+ school = {Cornell University},
+ year = 2004,
+ abstract = {In this thesis we explore the question of how to represent
+ programming data structures in a constructive type theory.
+ The basic data structures in programing languages are
+ records and objects. Most known papers treat such data
+ structure as primitive. That is, they add new primitive
+ type constructors and sup- porting axioms for records and
+ objects. This approach is not satisfactory. First of all it
+ complicates a type theory a lot. Second, the validity of
+ the new axioms is not easily established. As we will see
+ the naive choice of axioms can lead to contradiction even
+ in the simplest cases. We will show that records and
+ objects can be defined in a powerful enough type theory. We
+ will also show how to use these type constructors to define
+ abstract data structure. },
+ acknowledgement={none},
+ month = jan
+}
+
+@InProceedings{ kyas.ea:message:2004,
+ author = {Marcel Kyas and Frank S. de Boer},
+ title = {On Message Specification in {OCL}},
+ booktitle = {Compositional Verification in UML},
+ year = 2004,
+ editor = {Frank S. de Boer and Marcello Bonsangue},
+ acknowledgement={none},
+ series = entcs,
+ volume = 101,
+ pages = {73--93},
+ publisher = elsevier,
+ address = elsevier:adr,
+ abstract = {The object constraint language (OCL) is the established
+ language for specifying of properties of objects and object
+ structures. Recently an extension of OCL has been proposed
+ for the specification of messages sent between objects. In
+ this paper we present a generalization of this extension
+ which allows addition- ally to specify causality
+ constraints. From a pragmatic point of view, such causality
+ constraints are needed to express, for example, that each
+ acknowledgment must be preceded by a matching request,
+ which is frequently required by communication protocols.
+ Our generalization is based on the introduction of
+ histories into OCL. Histories describe the external
+ behavior of objects and groups of objects. Moreover, to
+ reason compositionally about the behavior of a complex
+ system we distinguish between local specifications of a
+ single object and global specifications describing the
+ interaction between objects. These two types of
+ specifications are expressed in syntactically difierent
+ dialects of OCL. Our notion of compositionality, which is
+ formalized in this paper by a compatibility predicate on
+ histories, allows the verification of models during the
+ early stages of a design. }
+}
+
+@InProceedings{ kyas.ea:extended:2004,
+ author = {Marcel Kyas and Harald Fecher},
+ title = {An Extended Type System for {OCL} supporting Templates and
+ Transformations},
+ booktitle = {Formal Methods for Open Object-Based Distributed Systems,
+ 7th {IFIP} {WG} 6.1 International Conference, {FMOODS}
+ 2005, Athens, Greece, June 15-17, 2005, Proceedings},
+ acknowledgement={none},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ year = 2004,
+ volume = 3535,
+ editor = {Martin Steffen and Gianluigi Zavattaro},
+ isbn = {3-540-26181-8},
+ pages = {83--98},
+ series = llncs,
+ doi = {10.1007/11494881_6}
+}
+
+@InProceedings{ giese.ea:simplifying:2005,
+ author = {Martin Giese and Daniel Larsson},
+ title = {Simplifying Transformations of {OCL} Constraints},
+ booktitle = {Proceedings, Model Driven Engineering Languages and
+ Systems (MoDELS) Conference 2005, Montego Bay, Jamaica},
+ editor = {Lionel Briand and Clay Williams},
+ pages = {309--323},
+ volume = 3713,
+ acknowledgement={none},
+ month = oct,
+ series = lncs,
+ year = 2005
+}
+
+@InCollection{ okeefe:improving:2006,
+ paddress = {Heidelberg},
+ address = pub-springer:adr,
+ author = {Greg O'Keefe},
+ booktitle = {{MoDELS} 2006: Model Driven Engineering Languages and
+ Systems},
+ language = {USenglish},
+ publisher = pub-springer,
+ acknowledgement={none},
+ series = lncs,
+ doi = {10.1007/11880240_4},
+ number = 4199,
+ year = 2006,
+ pages = {42--56},
+ editor = {Oscar Nierstrasz and Jon Whittle and David Harel and
+ Gianna Reggio},
+ title = {Improving the Definition of {UML}},
+ abstract = {The literature on formal semantics for UML is huge and
+ growing rapidly. Most contributions open with a brief
+ remark motivating the work, then quickly move on to the
+ technical detail. How do we decide whether more rigorous
+ semantics are needed? Do we currently have an adequate
+ definition of the syntax? How do we evaluate proposals to
+ improve the definition? We provide criteria by which these
+ and other questions can be answered. The growing role of
+ UML is examined. We compare formal language definition
+ techniques with those currently used in the definition of
+ UML. We study this definition for both its content and
+ form, and conclude that improvements are required. Finally,
+ we briefly survey the UML formalisation literature,
+ applying our criteria to determine which of the existing
+ approaches show the most potential.}
+}
+
+@TechReport{ wasserrab.ea:operational:2005,
+ author = {Daniel Wasserrab and Tobias Nipkow and Gregor Snelting and
+ Frank Tip},
+ title = {An Operational Semantics and Type Safety Proof for
+ {\Cpp}-Like Multiple Inheritance},
+ institution = {IBM Yorktown Heights},
+ number = {RC 23709},
+ month = aug,
+ year = 2005,
+ abstract = {We present, for the first time, an operational semantics
+ and a type system for a \Cpp-like object-oriented language
+ with both shared and repeated multiple inheritance,
+ together with a machine-checked proof of type safety. The
+ formalization uncovered several subtle ambiguities in \Cpp,
+ which \Cpp compilers resolve by ad-hoc means or which even
+ result in uncontrolled run-time errors. The semantics is
+ formalized in Isabelle/HOL.},
+ acknowledgement={none}
+}
+
+@Unpublished{ crane.ea:class:2006,
+ author = {Michelle L. Crane and Juergen Dingel and Zinovy Diskin},
+ title = {Class Diagrams: Abstract Syntax and Mapping to System
+ Model},
+ note = {Version 1.7.4},
+ url = {http://www.cs.queensu.ca/~stl/internal/uml2/documents.htm}
+ ,
+ pdf = {papers/2006/crane.ea-class-2006.pdf},
+ acknowledgement={none},
+ year = 2006
+}
+
+@Article{ henning:rise:2006,
+ author = {Michi Henning},
+ title = {The rise and fall of {CORBA}},
+ journal = {Queue},
+ volume = 4,
+ number = 5,
+ year = 2006,
+ issn = {1542-7730},
+ pages = {28--34},
+ doi = {10.1145/1142031.1142044},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none},
+ abstract = {Depending on exactly when one starts counting, CORBA is
+ about 10-15 years old. During its lifetime, CORBA has moved
+ from being a bleeding-edge technology for early adopters,
+ to being a popular middleware, to being a niche technology
+ that exists in relative obscurity. It is instructive to
+ examine why CORBA---despite once being heralded as the
+ {\^a}€œnext-generation technology for e-commerce---suffered
+ this fate. CORBA{\^a}€™s history is one that the computing
+ industry has seen many times, and it seems likely that
+ current middleware efforts, specifically Web services, will
+ reenact a similar history.}
+}
+
+@InProceedings{ briggs.ea:effective:1994,
+ author = {Preston Briggs and Keith D. Cooper},
+ title = {Effective partial redundancy elimination},
+ booktitle = PROC # { the ACM SIGPLAN 1994 conference on
+ Programming language design and implementation},
+ year = 1994,
+ isbn = {0-89791-662-X},
+ pages = {159--170},
+ location = {Orlando, Florida, United States},
+ doi = {10.1145/178243.178257},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none},
+ bibkey = {briggs.ea:effective:1994},
+ abstract = {Partial redundancy elimination is a code optimization with
+ a long history of literature and implementation. In
+ practice, its effectiveness depends on issues of naming and
+ code shape. This paper shows that a combination of global
+ reassociation and global value numbering can increase the
+ effectiveness of partial redundancy elimina- tion. By
+ imposing a discipline on the choice of names and the shape
+ of expressions, we are able to expose more redundancies, As
+ part of the work, we introduce a new algorithm for global
+ reassociation of expressions. It uses global in- formation
+ to reorder expressions, creating opportunities for other
+ optimization. The new algorithm generalizes earlier work
+ that ordered FORTRAN array address ex- pressions to improve
+ optimization.}
+}
+
+@Article{ binder:design:1994,
+ author = {Robert V. Binder},
+ title = {Design for testability in object-oriented systems},
+ journal = j-cacm,
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ volume = 37,
+ number = 9,
+ pages = {87--101},
+ month = sep,
+ year = 1994,
+ issn = {0001-0782},
+ acknowledgement={none},
+ keywords = {design; reliability},
+ bibkey = {binder:design:1994}
+}
+
+@InProceedings{ bernot.ea:theory:1997,
+ author = {Gilles Bernot and Laurent Bouaziz and Pascale {Le Gall}},
+ title = {A theory of probabilistic functional testing},
+ booktitle = PROC # { the 19th international conference on
+ Software engineering},
+ year = 1997,
+ isbn = {0-89791-914-9},
+ pages = {216--226},
+ pdf = {papers/1997/p216-bernot.pdf},
+ location = {Boston, Massachusetts, United States},
+ doi = {10.1145/253228.253273},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none}
+}
+
+@InProceedings{ ntafos:random:1998,
+ author = {Simeon Ntafos},
+ title = {On random and partition testing},
+ booktitle = PROC # { ACM SIGSOFT international symposium on
+ Software testing and analysis},
+ year = 1998,
+ isbn = {0-89791-971-8},
+ pages = {42--48},
+ location = {Clearwater Beach, Florida, United States},
+ doi = {10.1145/271771.271785},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none},
+ bibkey = {ntafos:random:1998}
+}
+
+@InProceedings{ hackett.ea:modular:2006,
+ author = {Brian Hackett and Manuvir Das and Daniel Wang and Zhe
+ Yang},
+ title = {Modular checking for buffer overflows in the large},
+ booktitle = {ICSE '06: Proceeding of the 28th international conference
+ on Software engineering},
+ year = 2006,
+ acknowledgement={none},
+ isbn = {1-59593-375-1},
+ pages = {232--241},
+ location = {Shanghai, China},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ doi = {10.1145/1134285.1134319}
+}
+
+@InProceedings{ biere.ea:sat-model-checking:1999,
+ author = {A. Biere and A. Cimatti and E. M. Clarke and M. Fujita and
+ Y. Zhu},
+ title = {Symbolic model checking using SAT procedures instead of
+ {BDDs}},
+ booktitle = PROC # { the 36th ACM/IEEE conference on Design
+ automation conference},
+ year = 1999,
+ isbn = {1-58133-109-7},
+ pages = {317--320},
+ location = {New Orleans, Louisiana, United States},
+ doi = {10.1145/309847.309942},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none},
+ bibkey = {biere.ea:sat-model-checking:1999}
+}
+
+@Article{ france:problem-oriented:34-10,
+ author = {Robert France},
+ title = {A problem-oriented analysis of basic {UML} static
+ requirements modeling concepts},
+ journal = {ACM SIG-PLAN Notices},
+ volume = 34,
+ number = 10,
+ pages = {57--69},
+ year = 1999,
+ abstract = {The Unified Modeling Language (UML) is a standard modeling
+ language in which some of the best object-oriented (OO)
+ modeling experiences are embedded. In this paper we
+ illustrate the role formal specification techniques can
+ play in developing a precise semantics for the UML. We
+ present a precise characterization of requirements-level
+ (problem-oriented) Class Diagrams and outline how the
+ characterization can be used to semantically analyze
+ requirements Class Diagrams.},
+ acknowledgement={none},
+ bibkey = {france:problem-oriented:34-10}
+}
+
+@InProceedings{ claessen.ea:quickcheck:2000,
+ author = {Koen Claessen and John Hughes},
+ title = {{QuickCheck}: a lightweight tool for random testing of
+ {Haskell} programs},
+ booktitle = PROC # { the fifth ACM SIGPLAN international
+ conference on Functional programming},
+ year = 2000,
+ isbn = {1-58113-202-6},
+ pages = {268--279},
+ doi = {10.1145/351240.351266},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {Quick Check is a tool which aids the Haskell programmer in
+ formulating and testing properties of programs. Properties
+ are described as Haskell functions, and can be
+ automatically tested on random input, but it is also
+ possible to define custom test data generators. We present
+ a number of case studies, in which the tool was
+ successfully used, and also point out some pitfalls to
+ avoid. Random testing is especially suitable for functional
+ programs because properties can be stated at a fine grain.
+ When a function is built from separately tested components,
+ then random testing suffices to obtain good coverage of the
+ definition under test. },
+ acknowledgement={none},
+ bibkey = {claessen.ea:quickcheck:2000}
+}
+
+@Article{ kozen:hoare:2000,
+ author = {Dexter Kozen},
+ title = {On Hoare logic and Kleene algebra with tests},
+ journal = {ACM Transactions on Computational Logic},
+ volume = 1,
+ number = 1,
+ year = 2000,
+ issn = {1529-3785},
+ pages = {60--76},
+ doi = {10.1145/343369.343378},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {We show that Kleene algebra with tests (KAT) subsumes
+ propositional Hoare logic (PHL). Thus the specialized
+ syntax and deductive apparatus of Hoare logic are
+ inessential and can be replaced by simple equational
+ reasoning. In addition, we show that all relationally valid
+ inference rules are derivable in KAT and that deciding the
+ relational validity of such rules is PSPACE-complete. },
+ acknowledgement={none},
+ bibkey = {kozen:hoare:2000}
+}
+
+@InProceedings{ chen.ea:semi-proving:2002,
+ author = {T. Y. Chen and T. H. Tse and Zhiquan Zhou},
+ title = {Semi-proving: an integrated method based on global
+ symbolic evaluation and metamorphic testing},
+ booktitle = PROC # { the international symposium on Software
+ testing and analysis},
+ year = 2002,
+ isbn = {1-58113-562-9},
+ pages = {191--195},
+ location = {Roma, Italy},
+ doi = {10.1145/566172.566202},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none},
+ bibkey = {chen.ea:semi-proving:2002}
+}
+
+@InProceedings{ naumovich.ea:static:2004,
+ author = {Gleb Naumovich and Paolina Centonze},
+ title = {Static Analysis of Role-Based Access Control in {J2EE}
+ Applications},
+ abstract = {This work describes a new technique for analysis of Java
+ 2, Enterprise Edition (J2EE) applications. In such
+ applications, Enterprise Java Beans (EJBs) are commonly
+ used to encapsulate the core computations performed on Web
+ servers. Access to EJBs is protected by application
+ servers, according to role-based access control policies
+ that may be created either at development or deployment
+ time. These policies may prohibit some types of users from
+ accessing specific EJB methods. We present a static
+ technique for analyzing J2EE access control policies with
+ respect to security-sensitive fields of EJBs and other
+ server-side objects. Our technique uses points-to analysis
+ to determine which object fields are accessed by which EJB
+ methods, directly or indirectly. Based on this information,
+ J2EE access control policies are analyzed to identify
+ potential inconsistencies that may lead to security holes.
+ },
+ volume = 29,
+ number = 5,
+ month = sep,
+ year = 2004,
+ booktitle = {TAV-WEB Proceedings},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ acknowledgement={none},
+ bibkey = {naumovich.ea:static:2004}
+}
+
+@InProceedings{ altenhofen.ea:high-level:2005,
+ author = {Michael Altenhofen and Egon B{\"o}rger and Jens Lemcke},
+ title = {A High-Level Specification for Mediators(Virtual
+ Providers)},
+ booktitle = {Business Process Management Workshops},
+ year = 2005,
+ pages = {116--129},
+ doi = {10.1007/11678564_11},
+ crossref = {bussler.ea:business:2006}
+}
+
+@Proceedings{ bussler.ea:business:2006,
+ editor = {Christoph Bussler and Armin Haller},
+ title = {Business Process Management Workshops, BPM 2005
+ International Workshops, BPI, BPD, ENEI, BPRM, WSCOBPM,
+ BPS, Nancy, France, September 5, 2005, Revised Selected
+ Papers},
+ booktitle = {Business Process Management Workshops},
+ volume = 3812,
+ year = 2006,
+ isbn = {3-540-32595-6}
+}
+
+@Article{ grieskamp.ea:generating:2002,
+ author = {Wolfgang Grieskamp and Yuri Gurevich and Wolfram Schulte
+ and Margus Veanes},
+ title = {Generating finite state machines from abstract state
+ machines},
+ journal = {SIGSOFT Softw. Eng. Notes},
+ volume = 27,
+ number = 4,
+ year = 2002,
+ issn = {0163-5948},
+ pages = {112--122},
+ doi = {10.1145/566171.566190},
+ publisher = pub-acm,
+ address = pub-acm:adr
+}
+
+@InProceedings{ paulson:isabelle:1988,
+ author = {Lawrence C. Paulson},
+ title = {Isabelle: The Next Seven Hundred Theorem Provers},
+ booktitle = {CADE},
+ year = 1988,
+ pages = {772--773},
+ crossref = {lusk.ea:cade:1988}
+}
+
+@Proceedings{ lusk.ea:cade:1988,
+ editor = {Ewing L. Lusk and Ross A. Overbeek},
+ title = {9th International Conference on Automated Deduction,
+ Argonne, Illinois, USA, May 23-26, 1988, Proceedings},
+ booktitle = {CADE},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 310,
+ year = 1988,
+ isbn = {3-540-19343-X}
+}
+
+@Article{ ntafos:comparison:1988,
+ author = {S. C. Ntafos},
+ title = {A Comparison of Some Structural Testing Strategies},
+ journal = j-ieee-tse,
+ volume = 14,
+ number = 6,
+ year = 1988,
+ pdf = {papers/1988/e0868.pdf},
+ issn = {0098-5589},
+ pages = {868--874},
+ doi = {http://csdl.computer.org/comp/trans/ts/1988/06/e0868abs.htm}
+ ,
+ publisher = pub-ieee,
+ address = pub-ieee:adr,
+ abstract = {Several structural testing strategies are compared in
+ terms of their relative coverage of the program's structure
+ and also in terms of the number of test cases needed to
+ satisfy each strategy. Some of the deficiencies of such
+ comparisons are discussed},
+ acknowledgement={none}
+}
+
+@InProceedings{ lange.ea:flyspeck:2008,
+ author = {Christoph Lange and Sean McLaughlin and Florian Rabe},
+ title = {Flyspeck in a Semantic {Wiki}},
+ booktitle = {SemWiki},
+ year = 2008,
+ url = {http://ceur-ws.org/Vol-360/paper-21.pdf},
+ crossref = {lange.ea:semwiki:2008}
+}
+
+@Proceedings{ lange.ea:semwiki:2008,
+ editor = {Christoph Lange and Sebastian Schaffert and Hala
+ Skaf-Molli and Max V{\"o}lkel},
+ title = PROC # {the 3rd Semantic Wiki Workshop (SemWiki
+ 2008) at the 5th European Semantic Web Conference (ESWC
+ 2008), Tenerife, Spain, June 2nd, 2008},
+ booktitle = {SemWiki},
+ publisher = {CEUR-WS.org},
+ series = {CEUR Workshop Proceedings},
+ volume = 360,
+ year = 2008
+}
+
+@Book{ matouvsek.ea:invitation:2008,
+ author = {Ji{\v}r{\'\i} Matou{\v}sek, and Jaroslav Ne{\v}set{\v}ril},
+ title = {Invitation to discrete mathematics.},
+ language = {English},
+ edition = {2nd},
+ publisher = pub-oxford,
+ address = pub-oxford:adr,
+ pages = 443,
+ year = 2008,
+ isbn = {978-0198570431},
+ abstract = {This is the second edition of a delightful textbook, see
+ [Invitation to discrete mathematics. (Oxford): Clarendon
+ Press. (1998; Zbl 0901.05001)]. Besides the usual
+ elimination of a few typos there are some additions, namely
+ a chapter on partially ordered sets, a section on
+ Tur\'{a}n's theorem on the number of edges in a
+ triangle-free graph and a chapter on Ramsey's theorem.\par
+ New to the second edition are also several proofs of the
+ Cauchy-Schwarz inequality, a very attractive elegant new
+ proof of Cayley's theorem on the number of labeled trees on
+ $n$ vertices via PARTs (Plans of Assembly of a Rooted
+ Tree), which the authors attribute to Jim Pitman, and
+ another proof of the determinant formula for counting
+ spanning trees of a given graph. The newly added geometric
+ interpretation of the construction of the real projective
+ plane is aided by the beautiful artistic rendering in the
+ figure with the caption ``The real projective plane in
+ moonlight''.},
+ keywords = {discrete mathematics; problem solving; counting
+ techniques; graph theory; trees; algorithms; planar graphs;
+ Sperner's theorem; finite projective planes; probabilistic
+ method; generating functions; partially ordered sets; Turan
+ theorem; Ramsey theorem; Cauchy Schwartz inequality; Cayley
+ theorem; geometric interpretation; real projective plane}
+}
+
+@Book{ syme.ea:expert-f:2007,
+ author = {Don Syme and Adam Granicz and Antonio Cisternino},
+ title = {Expert F\# (Expert's Voice in {.Net})},
+ isbn = 9781590598504,
+ publisher = {Apress},
+ pages = 609,
+ year = 2007
+}
+
+@Book{ baier.ea:principles:2008,
+ abstract = {Our growing dependence on increasingly complex computer
+ and software systems necessitates the development of
+ formalisms, techniques, and tools for assessing functional
+ properties of these systems. One such technique that has
+ emerged in the last twenty years is model checking, which
+ systematically (and automatically) checks whether a model
+ of a given system satisfies a desired property such as
+ deadlock freedom, invariants, or request-response
+ properties. This automated technique for verification and
+ debugging has developed into a mature and widely used
+ approach with many applications. \_Principles of Model
+ Checking\_ offers a comprehensive introduction to model
+ checking that is not only a text suitable for classroom use
+ but also a valuable reference for researchers and
+ practitioners in the field.
+
+ The book begins with the basic principles for modeling
+ concurrent and communicating systems, introduces different
+ classes of properties (including safety and liveness),
+ presents the notion of fairness, and provides automata-
+ based algorithms for these properties. It introduces the
+ temporal logics LTL and CTL, compares them, and covers
+ algorithms for verifying these logics, discussing real-time
+ systems as well as systems subject to random phenomena.
+ Separate chapters treat such efficiency-improving
+ techniques as abstraction and symbolic manipulation. The
+ book includes an extensive set of examples (most of which
+ run through several chapters) and a complete set of basic
+ results accompanied by detailed proofs. Each chapter
+ concludes with a summary, bibliographic notes, and an
+ extensive list of exercises of both practical and
+ theoretical nature.},
+ author = {Christel Baier and Joost-Pieter Katoen},
+ howpublished = {Hardcover},
+ isbn = {026202649X},
+ month = may,
+ publisher = pub-mit,
+ address = pub-mit:adr,
+ title = {Principles of Model Checking},
+ year = 2008
+}
+
+@Book{ bertot.ea:interactive:2004,
+ author = {Yves Bertot and Pierre Cast{\'e}ran},
+ keywords = {theorem-proving, type-theory, verification},
+ title = {Interactive Theorem Proving and Program Development.
+ Coq'Art: The Calculus of Inductive Constructions},
+ pages = 500,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ isbn = {978-3540208549},
+ year = 2004,
+ abstract = {Coq is an interactive proof assistant for the development
+ of mathematical theories and formally certified software.
+ It is based on a theory called the calculus of inductive
+ constructions, a variant of type theory. This book provides
+ a pragmatic introduction to the development of proofs and
+ certified programs using Coq. With its large collection of
+ examples and exercises it is an invaluable tool for
+ researchers, students, and engineers interested in formal
+ methods and the development of zero-fault software.}
+}
+
+@Article{ korel:automated:1990,
+ author = {Bogdan Korel},
+ title = {Automated Software Test Data Generation},
+ journal = j-ieee-tse,
+ volume = 16,
+ number = 8,
+ year = 1990,
+ issn = {0098-5589},
+ pages = {870--879},
+ doi = {10.1109/32.57624},
+ publisher = pub-ieee,
+ address = pub-ieee:adr,
+ acknowledgement={none},
+ bibkey = {korel:automated:1990}
+}
+
+@Article{ hamlet.ea:partition:1990,
+ author = {Dick Hamlet and Ross Taylor},
+ title = {Partition Testing Does Not Inspire Confidence (Program
+ Testing)},
+ journal = j-ieee-tse,
+ volume = 16,
+ number = 12,
+ year = 1990,
+ issn = {0098-5589},
+ pages = {1402--1411},
+ doi = {10.1109/32.62448},
+ publisher = pub-ieee,
+ address = pub-ieee:adr,
+ acknowledgement={none},
+ bibkey = {hamlet.ea:partition:1990}
+}
+
+@TechReport{ sharangpani.ea:statistical:1994,
+ language = {USenglish},
+ author = {H. P. Sharangpani and Ph. D. M. I. Barton },
+ title = {Statistical Analysis of Floating Point Flaw in the
+ Pentium$^{TM}$ Processor},
+ institution = {Intel Corporation},
+ month = nov,
+ year = 1994,
+ keywords = {pentium; flaw; FDIV; bug},
+ url = {http://www.intel.com/support/processors/pentium/fdiv/wp/},
+ abstract = {A subtle flaw in the hardware divide unit of the Pentium
+ TM Processor was discovered by Intel. Subsequently, a
+ characterization of its impact to the end-user application
+ base was conducted. The flaw is rare and data-dependent,
+ and causes a reduction in precision of the divide
+ instruc-tion and certain other operations in certain cases.
+ The significance of the flaw depends upon (a) the rate of
+ use of specific FP instructions in the Pentium TM CPU, (b)
+ the data fed to them, (c) the way in which the results of
+ these instructions are propagated into further computation
+ in the application; and (d) the way in which the final
+ results of the application are interpreted. The thorough
+ and detailed characterization of the flaw and the
+ subsequent investigations of its impact on applications
+ through elaborate surveys, analyses and empirical
+ observation lead us to the overall conclusion that the flaw
+ is of no concern to the vast majority of users of Pentium
+ processor based systems. A few users of applications in the
+ scientific/engineering and financial engineering fields who
+ require unusual precision and invoke millions of divides
+ per day may need t o employ either an updated Pen t ium
+ processor without the flaw or a software workaround.},
+ acknowledgement={none},
+ bibkey = {sharangpani.ea:statistical:1994}
+}
+
+@InProceedings{ paulson:formulation:1988,
+ author = {Lawrence C. Paulson},
+ title = {A formulation of the simple theory of types (for
+ Isabelle).},
+ booktitle = {Conference on Computer Logic},
+ year = 1988,
+ acknowledgement={none},
+ pages = {246--274},
+ doi = {10.1007/3-540-52335-9_58},
+ crossref = {martin-lof.ea:international:1990}
+}
+
+@Proceedings{ martin-lof.ea:international:1990,
+ editor = {Per Martin-L{\"o}f and Grigori Mints},
+ title = {International Conference on Computer Logic, Tallinn, USSR,
+ December 1988, Proceedings},
+ booktitle = {Conference on Computer Logic},
+ publisher = pub-springer,
+ series = lncs,
+ address = pub-springer:adr,
+ acknowledgement={none},
+ volume = 417,
+ year = 1990,
+ isbn = {3-540-52335-9}
+}
+
+@Article{ bernot.ea:software:1991,
+ author = {Gilles Bernot and Marie Claude Gaudel and Bruno Marre},
+ title = {Software testing based on formal specifications: a theory
+ and a tool},
+ journal = {Softw. Eng. J.},
+ volume = 6,
+ number = 6,
+ year = 1991,
+ issn = {0268-6961},
+ pages = {387--405},
+ publisher = {Michael Faraday House},
+ address = {Herts, UK, UK}
+}
+
+@Article{ chadwick.ea:permis:2008,
+ author = {David Chadwick and Gansen Zhao and Sassa Otenko and Romain
+ Laborde and Linying Su and Tuan Anh Nguyen},
+ title = {{PERMIS}: a modular authorization infrastructure},
+ journal = {Concurrency and Computation: Practice \& Experience},
+ volume = 20,
+ number = 11,
+ year = 2008,
+ issn = {1532-0626},
+ pages = {1341--1357},
+ doi = {10.1002/cpe.v20:11},
+ publisher = pub-wiley,
+ address = pub-wiley:adr,
+ abstract = {Authorization infrastructures manage privileges and render
+ access control decisions, allowing applications to adjust
+ their behavior according to the privileges allocated to
+ users. This paper describes the PERMIS role-based
+ authorization infrastructure along with its conceptual
+ authorization, access control, and trust models. PERMIS has
+ the novel concept of a credential validation service, which
+ verifies a user's credentials prior to access control
+ decision-making and enables the distributed management of
+ credentials. PERMIS also supports delegation of authority;
+ thus, credentials can be delegated between users, further
+ decentralizing credential management. Finally, PERMIS
+ supports history-based decision-making, which can be used
+ to enforce such aspects as separation of duties and
+ cumulative use of resources. Details of the design and the
+ implementation of PERMIS are presented along with details
+ of its integration with Globus Toolkit, Shibboleth, and
+ GridShib. A comparison of PERMIS with other authorization
+ and access control implementations is given, along with
+ suggestions where future research and development are still
+ needed.}
+}
+
+@Article{ altenhofen.ea:asms:2008,
+ author = {Michael Altenhofen and Andreas Friesen and Jens Lemcke},
+ title = {{ASMs} in Service Oriented Architectures},
+ journal = j-ucs,
+ volume = 14,
+ number = 12,
+ year = 2008,
+ pages = {2034--2058},
+ abstract = {We give a survey on work we did in the past where we have
+ successfully applied the ASM methodology to provide
+ abstract models for a number of problem areas that are
+ commonly found in Service Oriented Architectures (SOA). In
+ particular, we summarize our work on (1) service behavior
+ mediation, (2) service discovery, and (3) service
+ composition, showing that the corresponding solutions can
+ be described as variations of a fundamental abstract
+ processing model{\^a}the Virtual Provider.},
+ keywords = {process mediation, service discovery, workflow composition
+ }
+}
+
+@Book{ borger.ea:abstract:2003,
+ author = {Egon B{\"o}rger and Robert F. St{\"a}rk},
+ title = {Abstract State Machines: A Method for High-Level System
+ Design and Analysis},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ isbn = {3-540-00702-4},
+ abstract = {This book introduces into a new software engineering
+ method which guides the development of systems seamlessly
+ from requirements capture to coding. The method bridges the
+ gap between understanding and formulating real-world
+ problems by humans and the deployment of their solutions by
+ code-executing machines on changing platforms.It covers
+ design and analysis for both hardware and software
+ systems.It has a scientific foundation and improves current
+ industrial practice by linking the descriptions at the
+ successive stages of the system development cycle in a
+ coherent conceptual framework to keep the system models at
+ related levels synchronized.The method supports the
+ integration of standard design, analysis and documentation
+ techniques for model reuse (by abstraction), validation (by
+ simulation and high-level testing), verification (by
+ reasoning) and maintenance (by structured documentation).
+ },
+ year = 2003
+}
+
+@InProceedings{ altenhofen.ea:concurrent:2009,
+ author = {Michael Altenhofen and Egon B{\"o}rger},
+ title = {Concurrent Abstract State Machines and {$^+\mathit{CAL}$}
+ Programs},
+ pages = {1--17},
+ doi = {10.1007/978-3-642-03429-9_1},
+ abstract = {We apply the ASM semantics framework to define the await
+ construct in the context of concurrent ASMs. We link
+ {$^+\mathit{CAL}$} to concurrent control state ASMs with
+ turbo ASM submachines.},
+ booktitle = {Recent Trends in Algebraic Development Techniques},
+ series = s-lncs,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ year = 2009
+}
+
+@Article{ farahbod.ea:coreasm:2007,
+ author = {Roozbeh Farahbod and Vincenzo Gervasi and Uwe Gl{\"a}sser},
+ title = {{CoreASM}: An Extensible {ASM} Execution Engine},
+ journal = {Fundamenta Informaticae},
+ publisher = {IOS Press},
+ volume = 77,
+ number = {1-2},
+ year = 2007,
+ issn = {0169-2968},
+ pages = {71--103},
+ ee = {http://iospress.metapress.com/openurl.asp?genre=article{\&}issn=0169-2968{\&}volume=77{\&}issue=1{\&}spage=71}
+ ,
+ abstract = {In this paper we introduce a new research effort in making
+ abstract state machines (ASMs) executable. The aim is to
+ specify and implement an execution engine for a language
+ that is as close as possible to the mathematical definition
+ of pure ASMs. The paper presents the general architecture
+ of the engine, together with a high-level description of
+ the extensibility mechanisms that are used by the engine to
+ accommodate arbitrary backgrounds, scheduling policies, and
+ new rule forms.},
+ keywords = {CoreASM, Abstract state machines, Specification languages,
+ Executable specification}
+}
+
+@Article{ knuth:literate:1984,
+ author = {Donald E. Knuth},
+ title = {Literate Programming},
+ journal = {The Computer Journal},
+ volume = 27,
+ number = 2,
+ year = 1984,
+ pages = {97--111},
+ doi = {10.1093/comjnl/27.2.97},
+ publisher = {Oxford University Press},
+ address = {Oxford, UK},
+ issn = {0010-4620},
+ abstract = {The author and his associates have been experimenting for
+ the past several years with a programming language and
+ documentation system called WEB. This paper presents WEB by
+ example, and discusses why the new system appears to be an
+ improvement over previous ones.}
+}
+
+@Article{ forgy:rete:1982,
+ author = {Charles L. Forgy},
+ title = {Rete: A Fast Algorithm for the Many Patterns/Many Objects
+ Match Problem},
+ journal = {Artificial Intelligence},
+ volume = 19,
+ number = 1,
+ year = 1982,
+ pages = {17--37},
+ issn = {0004-3702},
+ abstract = {The Rete Match Algorithm is an efficient method for
+ comparing a large collection of patterns to a large
+ collection of objects. It finds all the objects that match
+ each pattern. The algorithm was developed for use in
+ production system interpreters, and it has been used for
+ systems containing from a few hundred to more than a
+ thousand patterns and objects. This article presents the
+ algorithm in detail. It explains the basic concepts of the
+ algorithm, it describes pattern and object representations
+ that are appropriate for the algorithm, and it describes
+ the operations performed by the pattern matcher. },
+ doi = {10.1016/0004-3702(82)90020-0}
+}
+
+@InProceedings{ burrows:chubby:2006,
+ author = {Mike Burrows},
+ title = {The Chubby lock service for loosely-coupled distributed
+ systems},
+ booktitle = {OSDI '06: Proceedings of the 7th symposium on Operating
+ systems design and implementation},
+ year = 2006,
+ isbn = {1-931971-47-1},
+ pages = {335--350},
+ publisher = {\acs{usenix} Association},
+ location = {Seattle, Washington},
+ address = {Berkeley, CA, USA},
+ abstract = {We describe our experiences with the Chubby lock service,
+ which is intended to provide coarse-grained locking as well
+ as reliable (though low-volume) storage for a
+ loosely-coupled distributed system. Chubby provides an
+ interface much like a distributed file system with advisory
+ locks, but the design emphasis is on availability and
+ reliability, as opposed to high performance. Many instances
+ of the service have been used for over a year, with several
+ of them each handling a few tens of thousands of clients
+ concurrently. The paper describes the initial design and
+ expected use, compares it with actual use, and explains how
+ the design had to be modified to accommodate the
+ differences.}
+}
+
+@InProceedings{ mccarthy.ea:architecture:1989,
+ author = {Dennis McCarthy and Umeshwar Dayal},
+ title = {The architecture of an active database management system},
+ booktitle = {SIGMOD '89: Proceedings of the 1989 ACM SIGMOD
+ international conference on Management of data},
+ year = 1989,
+ isbn = {0-89791-317-5},
+ pages = {215--224},
+ location = {Portland, Oregon, United States},
+ doi = {10.1145/67544.66946},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {he HiPAC project is investigating active, time-constrained
+ database management. An active DBMS is one which
+ automatically executes specified actions when specified
+ conditions arise. HiPAC has proposed Event-Condition-Action
+ (ECA) rules as a formalism for active database
+ capabilities. We have also developed an execution model
+ that specifies how these rules are processed in the context
+ of database transactions. The additional functionality
+ provided by ECA rules makes new demands on the design of an
+ active DBMS. In this paper we propose an architecture for
+ an active DBMS that supports ECA rules. This architecture
+ provides new forms of interaction, in support of ECA rules,
+ between application programs and the DBMS. This leads to a
+ new paradigm for constructing database applications.}
+}
+
+@InProceedings{ carioni.ea:scenario-based:2008,
+ author = {Alessandro Carioni and Angelo Gargantini and Elvinia
+ Riccobene and Patrizia Scandurra},
+ title = {A Scenario-Based Validation Language for {ASMs}},
+ booktitle = {ABZ},
+ year = 2008,
+ pages = {71--84},
+ doi = {10.1007/978-3-540-87603-8_7},
+ abstract = {This paper presents the AValLa language, a domain-specific
+ modelling language for scenario-based validation of ASM
+ models, and its supporting tool, the AsmetaV validator.
+ They have been developed according to the model-driven
+ development principles as part of the asmeta (ASM
+ mETAmodelling) toolset, a set of tools around ASMs. As a
+ proof-of-concepts, the paper reports the results of the
+ scenario-based validation for the well-known LIFT control
+ case study.},
+ crossref = {borger.ea:abstract:2008}
+}
+
+@Proceedings{ borger.ea:abstract:2008,
+ editor = {Egon B{\"o}rger and Michael J. Butler and Jonathan P.
+ Bowen and Paul Boca},
+ title = {Abstract State Machines, B and Z, First International
+ Conference, ABZ 2008, London, UK, September 16-18, 2008.
+ Proceedings},
+ booktitle = {ABZ},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 5238,
+ year = 2008,
+ isbn = {978-3-540-87602-1}
+}
+
+@Article{ decandia.ea:dynamo:2007,
+ author = {Giuseppe DeCandia and Deniz Hastorun and Madan Jampani and
+ Gunavardhan Kakulapati and Avinash Lakshman and Alex
+ Pilchin and Swaminathan Sivasubramanian and Peter Vosshall
+ and Werner Vogels},
+ title = {{Dynamo}: {Amazon's} highly available key-value store},
+ journal = {ACM SIGOPS Operating Systems Review},
+ volume = 41,
+ number = 6,
+ year = 2007,
+ issn = {0163-5980},
+ pages = {205--220},
+ doi = {10.1145/1323293.1294281},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {Reliability at massive scale is one of the biggest
+ challenges we face at Amazon.com, one of the largest
+ e-commerce operations in the world; even the slightest
+ outage has significant financial consequences and impacts
+ customer trust. The Amazon.com platform, which provides
+ services for many web sites worldwide, is implemented on
+ top of an infrastructure of tens of thousands of servers
+ and network components located in many datacenters around
+ the world. At this scale, small and large components fail
+ continuously and the way persistent state is managed in the
+ face of these failures drives the reliability and
+ scalability of the software systems.
+
+ This paper presents the design and implementation of
+ Dynamo, a highly available key-value storage system that
+ some of Amazon's core services use to provide an
+ "always-on" experience. To achieve this level of
+ availability, Dynamo sacrifices consistency under certain
+ failure scenarios. It makes extensive use of object
+ versioning and application-assisted conflict resolution in
+ a manner that provides a novel interface for developers to
+ use.}
+}
+
+@InProceedings{ crampton.ea:secondary:2006,
+ author = {Jason Crampton and Wing Leung and Konstantin Beznosov},
+ title = {The secondary and approximate authorization model and its
+ application to {Bell-LaPadula} policies},
+ booktitle = {SACMAT '06: Proceedings of the eleventh ACM symposium on
+ Access control models and technologies},
+ year = 2006,
+ isbn = {1-59593-353-0},
+ pages = {111--120},
+ location = {Lake Tahoe, California, USA},
+ doi = {10.1145/1133058.1133075},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {We introduce the concept, model, and policy-specific
+ algorithms for inferring new access control decisions from
+ previous ones. Our secondary and approximate authorization
+ model (SAAM) defines the notions of primary vs. secondary
+ and precise vs. approximate authorizations. Approximate
+ authorization responses are inferred from cached primary
+ responses, and therefore provide an alternative source of
+ access control decisions in the event that the
+ authorization server is unavailable or slow. The ability to
+ compute approximate authorizations improves the reliability
+ and performance of access control sub-systems and
+ ultimately the application systems themselves.The operation
+ of a system that employs SAAM depends on the type of access
+ control policy it implements. We propose and analyze
+ algorithms for computing secondary authorizations in the
+ case of policies based on the Bell-LaPadula model. In this
+ context, we define a dominance graph, and describe its
+ construction and usage for generating secondary responses
+ to authorization requests. Preliminary results of
+ evaluating SAAM BLP algorithms demonstrate a 30\% increase
+ in the number of authorization requests that can be served
+ without consulting access control policies.}
+}
+
+@InProceedings{ turkmen.ea:performance:2008,
+ author = {Fatih Turkmen and Bruno Crispo},
+ title = {Performance evaluation of {XACML} {PDP} implementations},
+ booktitle = {SWS '08: Proceedings of the 2008 ACM workshop on Secure
+ web services},
+ year = 2008,
+ isbn = {978-1-60558-292-4},
+ pages = {37--44},
+ location = {Alexandria, Virginia, USA},
+ doi = {10.1145/1456492.1456499},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {eXtensible Access Control Markup Language (XACML), an
+ OASIS standard, is the most widely used policy specifica-
+ tion language for access control. Its simplicity in syntax
+ and strength in coverage makes it suitable for diverse en-
+ vironments such as Service Oriented Architectures (SOAs)
+ and P2P systems. There are different implementations of
+ XACML available. Some of these implementations are open
+ source and some others are proprietary. In this work we
+ intended to shed some lights to the performance issues of
+ XACML engines. We tested 3 open source XACML
+ implementations with different policy/request settings. Our
+ experiments revealed some important points to be taken into
+ consideration when deploying an XACML based access control
+ system. Besides, our results can be used as hints by policy
+ writers and system developers for deploying efficient
+ authorization services.}
+}
+
+@InProceedings{ chen.ea:constraint:2006,
+ author = {Hong Chen and Ninghui Li},
+ title = {Constraint generation for separation of duty},
+ booktitle = {SACMAT '06: Proceedings of the eleventh ACM symposium on
+ Access control models and technologies},
+ year = 2006,
+ isbn = {1-59593-353-0},
+ pages = {130--138},
+ location = {Lake Tahoe, California, USA},
+ doi = {10.1145/1133058.1133077},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {Separation of Duty (SoD) is widely recognized to be a
+ fundamental principle in computer security. A Static SoD
+ (SSoD) policy states that in order to have all permissions
+ necessary to complete a sensitive task, the cooperation of
+ at least a certain number of users is required. In
+ Role-Based Access Control (RBAC), Statically Mutually
+ Exclusive Role (SMER) constraints are used to enforce SSoD
+ policies. This paper studies the problem of generating sets
+ of constraints that (a) enforce a set of SSoD policies, (b)
+ are compatible with the existing role hierarchy, and (c)
+ are minimal in the sense that there is no other constraint
+ set that is less restrictive and satisfies (a) and (b).}
+}
+
+@InProceedings{ schaad.ea:case:2005,
+ author = {Andreas Schaad and Pascal Spadone and Helmut Weichsel},
+ title = {A case study of separation of duty properties in the
+ context of the Austrian {``eLaw''} process.},
+ booktitle = {SAC '05: Proceedings of the 2005 ACM symposium on Applied
+ computing},
+ year = 2005,
+ isbn = {1-58113-964-0},
+ pages = {1328--1332},
+ location = {Santa Fe, New Mexico},
+ doi = {10.1145/1066677.1066976},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {Over the last few years rapid progress has been made in
+ moving from conceptual studies, "whitepapers" and
+ initiatives to the actual deployment of e-Government
+ systems [13]. In this paper we present the case study of an
+ existing e-Government system (eLaw) which already supports
+ key legislative processes in the country of Austria1. The
+ study has been performed in the context of the EU FP6
+ project "eJustice".We present a detailed system and
+ workflow representation referring to the example process of
+ changing a federal law in Austria. Since such processes and
+ their results, i.e. the laws of a country, have an enormous
+ impact on society, they need to be secured against external
+ and internal alteration, be it inadvertent or malicious.
+ This is even more important in the electronic world.Instead
+ of discussing the obvious security requirements like virus
+ protection or network-level access control, our focus is on
+ an often neglected form of organisational security and
+ control properties called separation of duties. We will
+ analyse and discuss a set of these in terms of the
+ described eLaw process.}
+}
+
+@InProceedings{ evered.ea:case:2004,
+ author = {Mark Evered and Serge B{\"o}geholz},
+ title = {A case study in access control requirements for a Health
+ Information System},
+ booktitle = {ACSW Frontiers '04: Proceedings of the second workshop on
+ Australasian information security, Data Mining and Web
+ Intelligence, and Software Internationalisation},
+ year = 2004,
+ pages = {53--61},
+ location = {Dunedin, New Zealand},
+ publisher = {Australian Computer Society, Inc.},
+ address = {Darlinghurst, Australia, Australia},
+ abstract = {We present a detailed examination of the access
+ constraints for a small real-world Health Information
+ System with the aim of achieving minimal access rights for
+ each of the involved principals. We show that, even for
+ such a relatively simple system, the resulting constraints
+ are very complex and cannot be expressed easily or clearly
+ using the static per-method access control lists generally
+ supported by component-based software. We derive general
+ requirements for the expressiveness of access constraints
+ and propose criteria for a more suitable access control
+ mechanism in the context of component-based systems. We
+ describe a two-level mechanism which can fulfil these
+ criteria.}
+}
+
+@Article{ kapsalis.ea:dynamic:2006,
+ title = {A dynamic context-aware access control architecture for
+ e-services},
+ journal = {Computers \& Security},
+ volume = 25,
+ number = 7,
+ pages = {507--521},
+ year = 2006,
+ issn = {0167-4048},
+ doi = {10.1016/j.cose.2006.05.004},
+ author = {Vassilis Kapsalis and Loukas Hadellis and Dimitris Karelis
+ and Stavros Koubias},
+ keywords = {e-Services, Access control, Web services, Context-aware,
+ Authorization, UML},
+ abstract = { The universal adoption of the Internet and the emerging
+ web services technologies constitutes the infrastructure
+ that enables the provision of a new generation of
+ e-services and applications. However, the provision of
+ e-services through the Internet imposes increased risks,
+ since it exposes data and sensitive information outside the
+ client premises. Thus, an advanced security mechanism has
+ to be incorporated, in order to protect this information
+ against unauthorized access. In this paper, we present a
+ context-aware access control architecture, in order to
+ support fine-grained authorizations for the provision of
+ e-services, based on an end-to-end web services
+ infrastructure. Access permissions to distributed web
+ services are controlled through an intermediary server, in
+ a completely transparent way to both clients and protected
+ resources. The access control mechanism is based on a
+ Role-Based Access Control (RBAC) model, which incorporates
+ dynamic context information, in the form of context
+ constraints. Context is dynamically updated and provides a
+ high level of abstraction of the physical environment by
+ using the concepts of simple and composite context
+ conditions. Also, the paper deals with implementation
+ issues and presents a system that incorporates the proposed
+ access control mechanism in a web services infrastructure
+ that conform to the OPC XML-DA specification.}
+}
+
+@InProceedings{ anderson:comparison:2006,
+ author = {Anne H. Anderson},
+ title = {A comparison of two privacy policy languages: {EPAL} and
+ {XACML}},
+ booktitle = {SWS '06: Proceedings of the 3rd ACM workshop on Secure web
+ services},
+ year = 2006,
+ isbn = {1-59593-546-0},
+ pages = {53--60},
+ location = {Alexandria, Virginia, USA},
+ doi = {10.1145/1180367.1180378},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {Current regulatory requirements in the U.S. and other
+ countries make it increasingly important for Web Services
+ to be able to enforce and verify their compliance with
+ privacy policies. Structured policy languages can play a
+ major role by supporting automated enforcement of policies
+ and auditing of access decisions. This paper compares two
+ policy languages that have been developed for use in
+ expressing directly enforceable privacy policies -- the
+ Enterprise Privacy Authorization Language (EPAL) and the
+ OASIS Standard eXtensible Access Control Markup Language
+ (XACML), together with its standard privacy profile.}
+}
+
+@Book{ rankl.ea:smart-card:2003,
+ author = {Wolfgang Rankl and Wolfgang Effing},
+ title = {Smart Card Handbook},
+ year = 2003,
+ isbn = 9780470856680,
+ doi = {10.1002/047085670X},
+ publisher = pub-wiley,
+ address = pub-wiley:adr,
+ abstract = {The boom in smart card technology reflects the medium's
+ broad solutions potential. Embedded with a sophisticated
+ microprocessor, smart cards offer unparalleled memory
+ capacity and data encryption capability. From providing
+ secure access to the Internet and mobile radio networks to
+ performing security-sensitive financial transactions in
+ credit card schemes, the Electronic Purse and Pay TV
+ systems, smart card technology is now a multi-billion
+ dollar industry. The Smart Card Handbook presents a
+ state-of-the-art overview of the technology from
+ fundamental information processing through design,
+ manufacture and operation of smart card schemes. Written in
+ a highly accessible style the Smart Card Handbook meets the
+ needs of both novice and expert. This is an essential
+ reference for computer and electronics engineers and
+ students in microchip design and security system
+ development. For professionals developing smart card
+ products, this unique reference will provide an invaluable
+ insight to all the facets of this sophisticated
+ technology.}
+}
+
+@Book{ graham.ea:concrete:1989,
+ title = {Concrete Mathematics},
+ author = {Roland L. Graham and Donald E. Knuth and Oren Patashnik},
+ isbn = {0-201-14236-8},
+ publisher = pub-aw,
+ address = pub-aw:adr,
+ pages = 578,
+ year = 1989
+}
+
+@Manual{ iso:ansi-cpp:1998,
+ bibkey = {iso:ansi-cpp:1998},
+ abstract = {Specifies requirements for implementations of the C++
+ programming language. This International Standard also
+ defines C++. Other requirements and relaxations of the
+ first requirement appear at various places within this
+ standard.},
+ note = {Doc. No. ISO/IEC 14882-1998},
+ title = {International Standard: Programming languages -C++ },
+ organization = {ANSI/ISO},
+ year = 1998,
+ month = sep,
+ publisher = {The American National Standards Institute},
+ address = {New York}
+}
+
+@Book{ reid:thinking:1990,
+ abstract = {The book is a result of Glenn Reid's years trying to teach
+ people to write PostScript programs, during which he
+ discovered that people tended to try to make PostScript
+ "look like" other programming languages they already knew.
+ There is even a chapter in this book entitled "PostScript
+ Is Not Like C", because it is really a very different
+ language, and one must learn to "think" in PostScript in
+ order to be a good programmer. },
+ author = {Glenn C. Reid},
+ title = {Thinking in Postscript},
+ publisher = pub-aw,
+ address = pub-aw:adr,
+ month = sep,
+ year = 1990,
+ language = {USenglish},
+ keywords = {Postscript},
+ public = {yes},
+ isbn = {0-201-52372-8},
+ url = {http://www.rightbrain.com/download/books/ThinkingInPostScript.pdf}
+
+}
+
+@Book{ knuth:seminumerical:1981,
+ author = {Donald E. Knuth},
+ series = {The Art of Computer Programming},
+ volume = 2,
+ title = {Seminumerical Algorithms},
+ edition = {second},
+ isbn = {0-201-03822-6},
+ year = 1981,
+ publisher = pub-aw,
+ address = pub-aw:adr
+}
+
+@Book{ wegener:complexity:1987,
+ address = {Stuttgart},
+ author = {Ingo Wegener},
+ language = {USenglish},
+ public = {yes},
+ publisher = {John Wiley \& Sons Ltd., and B.G. Teubner},
+ title = {The Complexity of Boolean Functions},
+ url = {\url{http://ls2-www.informatik.uni-dortmund.de/monographs/bluebook/}}
+ ,
+ year = 1987,
+ cover = {1987/wegener:complexity:1987.png},
+ timestamp = 948019205
+}
+
+@Article{ stallman:societal:1997,
+ author = {Richard Stallman},
+ title = {Societal Dimensions: The Right to Read},
+ journal = j-cacm,
+ volume = 40,
+ number = 2,
+ pages = {85--87},
+ month = feb,
+ year = 1997,
+ coden = {CACMA2},
+ issn = {0001-0782},
+ url = {http://www.acm.org/pubs/citations/journals/cacm/1997-40-2/p85-stallman/}
+ ,
+ localurl = {papers/1997/p85-stallman.pdf},
+ note = {\url{http://www.gnu.org/}},
+ acknowledgement=ack-nhfb,
+ classification= {C0230 (Economic, social and political aspects of
+ computing); C0310D (Computer installation management)},
+ keywords = {Clinton administration; Clipper chip; computer crime;
+ design; industrial property; key-escrow proposals; legal
+ aspects; management; pirates; right to read; security;
+ Software Protection Authority; Software Publisher's
+ Association},
+ subject = {{\bf K.1} Computing Milieux, THE COMPUTER INDUSTRY. {\bf
+ K.5.0} Computing Milieux, LEGAL ASPECTS OF COMPUTING,
+ General. {\bf K.4.0} Computing Milieux, COMPUTERS AND
+ SOCIETY, General.},
+ treatment = {G General Review}
+}
+
+@Article{ stallman:societal:1997-b,
+ author = {Richard Stallman},
+ title = {Societal Dimensions: The Right to Read},
+ journal = j-cacm,
+ volume = 40,
+ number = 2,
+ pages = {85--87},
+ month = feb,
+ year = 1997,
+ issn = {0001-0782},
+ classification= {C0230 (Economic, social and political aspects of
+ computing); C0310D (Computer installation management)},
+ keywords = {Clinton administration; Clipper chip; computer crime;
+ design; industrial property; key-escrow proposals; legal
+ aspects; management; pirates; right to read; security;
+ Software Protection Authority; Software Publisher's
+ Association},
+ subject = {{\bf K.1} Computing Milieux, THE COMPUTER INDUSTRY. {\bf
+ K.5.0} Computing Milieux, LEGAL ASPECTS OF COMPUTING,
+ General. {\bf K.4.0} Computing Milieux, COMPUTERS AND
+ SOCIETY, General.},
+ treatment = {G General Review}
+}
+
+@Article{ dalton.ea:securing:2001,
+ bibkey = {dalton.ea:securing:2001},
+ author = {Chris Dalton and Tse Huong Choo},
+ title = {An operating system approach to securing e--services},
+ journal = j-cacm,
+ volume = 44,
+ number = 2,
+ pages = {58--64},
+ month = feb,
+ abstract = {This article looks at some of the problems surrounding
+ application compromise in more detail and puts forward our
+ approach to solving these problems. We do not attempt to
+ guarantee that the application services are bug-free (a
+ difficult problem). Instead, we have found that the effects
+ of this type of attack, and quite a few others, can be
+ usefully mitigated by adding specific properties to the OSs
+ used to host those applications.
+
+ Specifically, we look at Trusted Linux, HP Laboratories'
+ implementation of a secure version of Linux, which we
+ believe is an ideal platform for e-service application
+ hosting.},
+ year = 2001,
+ issn = {0001-0782}
+}
+
+@Article{ cornea-hasegan:proving:1998,
+ language = {USenglish},
+ abstract = {The work presented in this paper was initiated as part of
+ a study on software alternatives to the hardware
+ implementations of floating-point operations such as divide
+ and square root. The results of the study proved the
+ viability of software implementations, and showed that
+ certain proposed algorithms are comparable in performance
+ to current hardware implementations. This paper discusses
+ two components of that study:
+
+ (1) A methodology for proving the IEEE correctness of the
+ result of iterative algorithms that implement the
+ floating-point square root, divide, or remainder operation.
+ (2) Identification of operands for the floating-point
+ divide and square root operations that lead to results
+ representing difficult cases for IEEE rounding.
+
+ Some general properties of floating-point computations are
+ presented first. The IEEE correctness of the floating-point
+ square root operation is discussed next. We show how
+ operands for the floating-point square root that lead to
+ difficult cases for rounding can be generated, and how to
+ use this knowledge in proving the IEEE correctness of the
+ result of iterative algorithms that calculate the square
+ root of a floating-point number. Similar aspects are
+ analyzed for the floating-point divide operation, and we
+ present a method for generating difficult cases for
+ rounding. In the case of the floating-point divide
+ operation, however, it is more difficult to use this
+ information in proving the IEEE correctness of the result
+ of an iterative algorithm than it is for the floating-point
+ square root operation. We examine the restrictions on the
+ method used for square root. Finally, we present possible
+ limitations due to the finite exponent range.},
+ journal = {Intel Technology Journal},
+ volume = {Q2},
+ year = 1998,
+ title = {Proving the {IEEE} Correctness of Iterative Floating-Point
+ Square Root, Divide, and Remainder Algorithms },
+ author = {Marius Cornea-Hasegan},
+ keywords = {floating-point, IEEE correctness, divide, square root,
+ remainder},
+ url = {\url{http://developer.intel.com/technology/itj/q21998/articles/art_3.htm}}
+
+}
+
+@Article{ edelman:mathematics:1997,
+ author = {Alan Edelman},
+ abstract = {Despite all of the publicity surrounding the Pentium bug
+ of 1994, the mathematical details of the bug are poorly
+ understood. We discuss these details and supply a new proof
+ of the Coe--Tang result that the at-risk divisors have six
+ consecutive ones in positions 5 through 10. Also, we prove
+ that the worst-case absolute error for arguments in [1,2)
+ is on the order of 1e--5. },
+ journal = {SIAM},
+ title = {The Mathematics of the Pentium Division Bug},
+ keywords = {Pentium, SRT division, floating point operations },
+ year = 1997,
+ url = {\url{http://epubs.siam.org/sam-bin/dbq/article/29395}},
+ pages = {54--67},
+ volume = 39,
+ number = 1,
+ public = {yes}
+}
+
+@Article{ oleary.ea:formally:1999,
+ language = {USenglish},
+ abstract = {This paper describes the formal specification and
+ verification of floating-point arithmetic hardware at the
+ level of IEEE Standard 754. Floating-point correctness is a
+ crucial problem: the functionality of Intel's
+ floating-point hardware is architecturally visible and,
+ once discovered, floating-point bugs are easily reproduced
+ by the consumer. We have formally specified and verified
+ IEEE-compliance of the Pentium{\textregistered} Pro
+ processor's FADD, FSUB, FMUL, FDIV, FSQRT, and FPREM
+ operations, as well as the correctness of various
+ miscellaneous operations including conversion to and from
+ integers. Compliance was verified against the gate-level
+ descriptions from which the actual silicon is derived and
+ on which all traditional pre-silicon dynamic validation is
+ performed. Our results demonstrate that formal functional
+ verification of gate-level floating-point designs against
+ IEEE-level specifications is both feasible and practical.
+ As far as the authors are aware, this is the first such
+ demonstration. },
+ journal = {Intel Technology Journal},
+ volume = {Q1},
+ year = 1999,
+ title = {Formally Verifying {IEEE} Compliance of Floating-Point
+ Hardware},
+ author = {John O'Leary and Xudong Zhao and Rob Gerth and Carl-Johan
+ H. Seger},
+ url = {\url{http://developer.intel.com/technology/itj/q11999/articles/art_5.htm}}
+ ,
+ keywords = {verification; pentium; FDIV bug; flaw;
+ floating-point-hardware; floating-point; IEEE compliance;
+ formal verification; model checking; theorem proving }
+}
+
+@Article{ neubauer:feinheiten:1996,
+ author = {Marion Neubauer},
+ title = {Feinheiten bei wissenschaftlichen {P}ublikationen --
+ {M}ikrotypographie-{R}egeln, {T}eil {I}},
+ journal = dtk,
+ year = 1996,
+ volume = {4/96},
+ altvolume = 8,
+ altnumber = 4,
+ month = feb,
+ pages = {23--40},
+ annote = bretter,
+ localurl = {papers/1996/dtk96_4_neubauer_feinheiten.pdf},
+ url = {\url{http://www.dante.de/dante/DTK/}},
+ keywords = {Mikrotypographie, Abk{\"u}rzungen, Akronyme, Einheiten,
+ Himmelsrichtungen, Anf{\"u}hrungszeichen, Satzzeichen,
+ Auslassungen, Sonderzeichen, email-Adressen, Ligaturen}
+}
+
+@Article{ neubauer:feinheiten:1997,
+ author = {Marion Neubauer},
+ title = {Feinheiten bei wissenschaftlichen {P}ublikationen --
+ {M}ikrotypographie-{R}egeln, {T}eil {II}},
+ journal = dtk,
+ year = 1997,
+ volume = {1/97},
+ altvolume = 9,
+ altnumber = 1,
+ month = may,
+ pages = {25--44},
+ url = {\url{http://www.dante.de/dante/DTK/}},
+ localurl = {papers/1997/dtk97_1_neubauer_feinheiten.pdf},
+ annote = bretter,
+ keywords = {Mikrotypographie, Zahlen, Ziffern, Nummern, Striche,
+ Klammern, geschachtelte Klammern, Wortzwischenr{\"a}ume,
+ Abst{\"a}nde, mathematischer Satz, Worttennungen,
+ Zeilenumbruch}
+}
+
+@Article{ szpiro:mathematics:2003,
+ author = {George Szpiro},
+ url = {http://www.nature.com/cgi-taf/DynaPage.taf?file=/nature/journal/v424/n6944/full/424012a_fs.html}
+ ,
+ journal = {Nature},
+ pages = {12--13},
+ month = jul,
+ year = 2003,
+ number = 424,
+ title = {Mathematics: Does the proof stack up?},
+ acknowledgement={none},
+ bibkey = {szpiro:mathematics:2003}
+}
+
+@Article{ venet:practical:2008,
+ author = {Arnaud Venet},
+ title = {A practical approach to formal software verification by
+ static analysis},
+ journal = {Ada Lett.},
+ volume = {XXVIII},
+ number = 1,
+ year = 2008,
+ issn = {1094-3641},
+ pages = {92--95},
+ doi = {10.1145/1387830.1387836},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ abstract = {Static analysis by Abstract Interpretation is a promising
+ way for conducting formal verification of large software
+ applications. In spite of recent successes in the
+ verification of aerospace codes, this approach has limited
+ industrial applicability due to the level of expertise
+ required to engineer static analyzers. In this paper we
+ investigate a pragmatic approach that consists of focusing
+ on the most critical components of the application first.
+ In this approach the user provides a description of the
+ usage of functionalities in the critical component via a
+ simple specification language, which is used to drive a
+ fully automated static analysis engine. We present
+ experimental results of the application of this approach to
+ the verification of absence of buffer overflows in a
+ critical library of the OpenSSH distribution.}
+}
+
+@InProceedings{ balser.ea:formal:2000,
+ author = {Michael Balser and Wolfgang Reif and Gerhard Schellhorn
+ and Kurt Stenzel and Andreas Thums},
+ title = {Formal System Development with {KIV}},
+ booktitle = {FASE},
+ year = 2000,
+ pages = {363--366},
+ doi = {10.1007/3-540-46428-X_25},
+ crossref = {maibaum:fundamental:2000},
+ abstract = {KIV is a tool for formal systems development. It can be
+ employed, e.g., 1) for the development of safety critical
+ systems from formal requirements specifications to
+ executable code, including the verification of safety
+ requirements and the correctness of implementations, 2) for
+ semantical foundations of programming languages from a
+ specification of the semantics to a verified compiler, 3)
+ for building security models and architectural models as
+ they are needed for high level ITSEC [7] or CC [1]
+ evaluations. }
+}
+
+@Proceedings{ maibaum:fundamental:2000,
+ editor = {T. S. E. Maibaum},
+ title = {Fundamental Approaches to Software Engineering, Third
+ Internationsl Conference, FASE 2000, Held as Part of the
+ European Joint Conferences on the Theory and Practice of
+ Software, ETAPS 2000, Berlin, Germany, March 25 - April 2,
+ 2000, Proceedings},
+ booktitle = {FASE},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 1783,
+ year = 2000,
+ isbn = {3-540-67261-3}
+}
+
+@InProceedings{ castillo:asm:2001,
+ author = {Giuseppe Del Castillo},
+ title = {The {ASM} Workbench: A Tool Environment for Computer-Aided
+ Analysis and Validation of Abstract State Machine Models
+ Tool Demonstration},
+ booktitle = {TACAS},
+ year = 2001,
+ pages = {578--581},
+ doi = {10.1007/3-540-45319-9_40},
+ abstract = {Gurevich{\^a}s Abstract State Machines (ASMs) constitute a
+ high-level state-based modelling language, which has been
+ used in a wide range of applications. The ASM Workbench is
+ a comprehensive tool environment supporting the development
+ and computer-aided analysis and validation of ASM models.
+ It is based on a typed version of the ASM language, called
+ ASM-SL, and includes features for type-checking,
+ simulation, debugging, and verification of ASM models.},
+ crossref = {margaria.ea:tools:2001}
+}
+
+@Proceedings{ margaria.ea:tools:2001,
+ editor = {Tiziana Margaria and Wang Yi},
+ title = {Tools and Algorithms for the Construction and Analysis of
+ Systems, 7th International Conference, TACAS 2001 Held as
+ Part of the Joint European Conferences on Theory and
+ Practice of Software, ETAPS 2001 Genova, Italy, April 2-6,
+ 2001, Proceedings},
+ booktitle = {TACAS},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2031,
+ year = 2001,
+ isbn = {3-540-41865-2}
+}
+
+@Article{ gurevich.ea:semantic:2005,
+ title = {Semantic essence of {AsmL}},
+ journal = {Theoretical Computer Science},
+ volume = 343,
+ number = 3,
+ pages = {370--412},
+ year = 2005,
+ note = {Formal Methods for Components and Objects},
+ issn = {0304-3975},
+ doi = {10.1016/j.tcs.2005.06.017},
+ author = {Yuri Gurevich and Benjamin Rossman and Wolfram Schulte},
+ keywords = {Abstract state machine,Executable specification language},
+ abstract = { The Abstract State Machine Language, AsmL, is a novel
+ executable specification language based on the theory of
+ Abstract State Machines. AsmL is object-oriented, provides
+ high-level mathematical data-structures, and is built
+ around the notion of synchronous updates and finite choice.
+ AsmL is fully integrated into the .NET framework and
+ Microsoft development tools. In this paper, we explain the
+ design rationale of AsmL and provide static and dynamic
+ semantics for a kernel of the language.}
+}
+
+@Article{ gargantini.ea:metamodel-based:2008,
+ author = {Angelo Gargantini and Elvinia Riccobene and Patrizia
+ Scandurra},
+ title = {A Metamodel-based Language and a Simulation Engine for
+ Abstract State Machines},
+ journal = j-ucs,
+ volume = 14,
+ number = 12,
+ year = 2008,
+ pages = {1949--1983},
+ abstract = {In this paper, we present a concrete textual notation,
+ called AsmetaL, and a general-purpose simulation engine,
+ called AsmetaS, for Abstract State Machine (ASM)
+ specifications. They have been developed as part of the
+ ASMETA (ASMs mETAmodelling) toolset, which is a set of
+ tools for ASMs based on the metamodelling approach of the
+ Model-driven Engineering. We briefly present the ASMETA
+ framework, and we discuss how the language and the
+ simulator have been developed exploiting the advantages
+ offered by the metamodelling approach. We introduce the
+ language AsmetaL used to write ASM specifications, and we
+ provide the AsmetaL encoding of ASM specifications of
+ increasing complexity. We explain the AsmetaS architecture,
+ its kernel engine, and how the simulator works within the
+ ASMETA tool set. We discuss the features currently
+ supported by the simulator and how it has been validated.}
+}
+
+@Manual{ schmid:introduction:2001,
+ author = {Joachim Schmid},
+ title = {Introduction to {AsmGofer}},
+ year = 2001
+}
+
+@InProceedings{ miller.ea:czt:2005,
+ author = {Tim Miller and Leo Freitas and Petra Malik and Mark
+ Utting},
+ title = {{CZT} Support for {Z} Extensions},
+ year = 2005,
+ pages = {227--245},
+ doi = {10.1007/11589976_14},
+ crossref = {romijn.ea:integrated:2005},
+ abstract = {Community Z Tools (CZT) is an integrated framework for the
+ Z formal specification language. In this paper, we show how
+ it is also designed to support extensions of Z, in a way
+ that minimises the work required to build a new Z
+ extension. The goals of the framework are to maximise
+ extensibility and reuse, and minimise code duplication and
+ maintenance effort. To achieve these goals, CZT uses a
+ variety of different reuse mechanisms, including generation
+ of Java code from a hierarchy of XML schemas, XML templates
+ for shared code, and several design patterns for maximising
+ reuse of Java code. The CZT framework is being used to
+ implement several integrated formal methods, which add
+ object-orientation, real-time features and process algebra
+ extensions to Z. The effort required to implement such
+ extensions of Z has been dramatically reduced by using the
+ CZT framework.}
+}
+
+@Proceedings{ romijn.ea:integrated:2005,
+ editor = {Judi Romijn and Graeme Smith and Jaco van de Pol},
+ booktitle = {Integrated Formal Methods (IFM)},
+ location = {Eindhoven, The Netherlands},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 3771,
+ year = 2005,
+ isbn = {3-540-30492-4}
+}
+
+@TechReport{ ashley.ea:enterprise:2003,
+ author = {Paul Ashley and Satoshi Hada and G{\"u}nter Karjoth and
+ Calvin Powers and Matthias Schunter},
+ editor = {Calvin Powers and Matthias Schunter},
+ title = {Enterprise Privacy Authorization Language ({EPAL} 1.2)},
+ institution = {IBM},
+ year = 2003,
+ url = {http://www.zurich.ibm.com/security/enterprise-privacy/epal}
+
+}
+
+@TechReport{ cisc:securing:2008,
+ title = {Securing Cyberspace for the 44th Presidency},
+ institution = {Center for Strategic and International Studies (CSIS)},
+ month = dec,
+ year = 2008
+}
+
+@InProceedings{ wei.ea:authorization:2008,
+ author = {Qiang Wei and Jason Crampton and Konstantin Beznosov and
+ Matei Ripeanu},
+ title = {Authorization recycling in {RBAC} systems},
+ booktitle = {ACM symposium on Access control models and technologies
+ (SACMAT)},
+ year = 2008,
+ isbn = {978-1-60558-129-3},
+ pages = {63--72},
+ location = {Estes Park, CO, USA},
+ doi = {10.1145/1377836.1377848},
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ abstract = {As distributed applications increase in size and
+ complexity, traditional authorization mechanisms based on a
+ single policy decision point are increasingly fragile
+ because this decision point represents a single point of
+ failure and a performance bottleneck. Authorization
+ recycling is one technique that has been used to address
+ these challenges.
+
+ This paper introduces and evaluates the mechanisms for
+ authorization recycling in RBAC enterprise systems. The
+ algorithms that support these mechanisms allow precise and
+ approximate authorization decisions to be made, thereby
+ masking possible failures of the policy decision point and
+ reducing its load. We evaluate these algorithms
+ analytically and using a prototype implementation. Our
+ evaluation results demonstrate that authorization recycling
+ can improve the performance of distributed access control
+ mechanisms.}
+}
+
+@Article{ karjoth:access:2003,
+ author = {G{\"u}nter Karjoth},
+ title = {Access control with {IBM} {Tivoli} access manager},
+ journal = j-tissec,
+ publisher = pub-acm,
+ address = pub-acm:adr,
+ volume = 6,
+ number = 2,
+ year = 2003,
+ pages = {232--257},
+ doi = {10.1145/762476.762479},
+ abstract = {Web presence has become a key consideration for the
+ majority of companies and other organizations. Besides
+ being an essential information delivery tool, the Web is
+ increasingly being regarded as an extension of the
+ organization itself, directly integrated with its operating
+ processes. As this transformation takes place, security
+ grows in importance. IBM Tivoli Access Manager offers a
+ shared infrastructure for authentication and access
+ management, technologies that have begun to emerge in the
+ commercial marketplace. This paper describes the
+ Authorization Service provided by IBM Tivoli Access Manager
+ for e-business (AM) and its use by AM family members as
+ well as third-party applications. Policies are defined over
+ a protected object namespace and stored in a database,
+ which is managed via a management console and accessed
+ through an Authorization API. The protected object
+ namespace abstracts from heterogeneous systems and thus
+ enables the definition of consistent policies and their
+ centralized management. ACL inheritance and delegated
+ management allow these policies to be managed efficiently.
+ The Authorization API allows applications with their own
+ access control requirements to decouple authorization logic
+ from application logic. Policy checking can be externalized
+ by using either a proxy that sits in front of the Web
+ servers and application servers or a plug-in that examines
+ the request. Thus, AM familiy members establish a single
+ entry point to enforce enterprise policies that regulate
+ access to corporate data.}
+}
+
+@Book{ heijenoort:from:2002,
+ abstract = {The fundamental texts of the great classical period in
+ modern logic, some of them never before available in
+ English translation, are here gathered together for the
+ first time. Modern logic, heralded by Leibniz, may be said
+ to have been initiated by Boole, De Morgan, and Jevons, but
+ it was the publication in 1879 of Gottlob Frege's
+ Begriffsschrift that opened a great epoch in the history of
+ logic by presenting, in full-fledged form, the
+ propositional calculus and quantification theory. Frege's
+ book, translated in its entirety, begins the present
+ volume. The emergence of two new fields, set theory and
+ foundations of mathematics, on the borders of logic,
+ mathematics, and philosophy, is depicted by the texts that
+ follow. Peano and Dedekind illustrate the trend that led to
+ Principia Mathematica. Burali-Forti, Cantor, Russell,
+ Richard, and K\"{o}nig mark the appearance of the modern
+ paradoxes. Hilbert, Russell, and Zermelo show various ways
+ of overcoming these paradoxes and initiate, respectively,
+ proof theory, the theory of types, and axiomatic set
+ theory. Skolem generalizes L\"{o}wenheim's theorem, and he
+ and Fraenkel amend Zermelo's axiomatization of set theory,
+ while von Neumann offers a somewhat different system. The
+ controversy between Hubert and Brouwer during the twenties
+ is presented in papers of theirs and in others by Weyl,
+ Bernays, Ackermann, and Kolmogorov. The volume concludes
+ with papers by Herbrand and by G\"{o}del, including the
+ latter's famous incompleteness paper. Of the forty-five
+ contributions here collected all but five are presented in
+ extenso. Those not originally written in English have been
+ translated with exemplary care and exactness; the
+ translators are themselves mathematical logicians as well
+ as skilled interpreters of sometimes obscure texts. Each
+ paper is introduced by a note that sets it in perspective,
+ explains its importance, and points out difficulties in
+ interpretation. Editorial comments and footnotes are
+ interpolated where needed, and an extensive bibliography is
+ included.},
+ author = {Jean van Heijenoort},
+ howpublished = {Paperback},
+ isbn = 0674324498,
+ keywords = {frege, godel, logic},
+ month = {January},
+ posted-at = {2006-05-07 22:17:38},
+ priority = 2,
+ publisher = {{Harvard University Press}},
+ title = {From Frege to G{\"o}del : A Source Book in Mathematical
+ Logic, 1879-1931 (Source Books in the History of the
+ Sciences)},
+ year = 2002
+}
+
+@InProceedings{ kohler.ea:avoiding:2008,
+ author = {Mathias Kohler and Andreas Schaad},
+ title = {Avoiding Policy-based Deadlocks in Business Processes},
+ year = 2008,
+ pages = {709--716},
+ doi = {10.1109/ARES.2008.131},
+ address = pub-ieee:adr,
+ publisher = pub-ieee,
+ abstract = {In the field of business process management, deadlocks
+ describe a situation where a workflow execution is blocked
+ and cannot be completed. We speak of policy-based deadlocks
+ if such a situation is caused by unsatisfiable resource
+ requirements due to security constraints specified as part
+ of the business process. In this paper we propose a method
+ to avoid policy-based deadlocks by analyzing a workflow's
+ security constraints, determine the minimal required number
+ of users, and provide an optimal user-activity assignment
+ for a deadlock-free workflow execution. We will finally
+ validate our proposed approach by applying it to a
+ real-world scenario. },
+ booktitle = {Third International Conference on Availability,
+ Reliability and Security (ARES 2008)},
+ location = {Technical University of Catalonia, Barcelona , Spain},
+ month = mar
+}
+
+@InProceedings{ modersheim.ea:open-source:2009,
+ author = {Sebastian M{\"o}dersheim and Luca Vigan{\`o}},
+ title = {The Open-Source Fixed-Point Model Checker for Symbolic
+ Analysis of Security Protocols},
+ booktitle = {FOSAD},
+ year = 2009,
+ pages = {166--194},
+ doi = {10.1007/978-3-642-03829-7_6},
+ crossref = {aldini.ea:foundations:2009}
+}
+
+@Proceedings{ aldini.ea:foundations:2009,
+ editor = {Alessandro Aldini and Gilles Barthe and Roberto Gorrieri},
+ title = {Foundations of Security Analysis and Design V, FOSAD
+ 2007/2008/2009 Tutorial Lectures},
+ booktitle = {FOSAD},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 5705,
+ year = 2009,
+ isbn = {978-3-642-03828-0},
+ doi = {10.1007/978-3-642-03829-7}
+}
+
+@Article{ dolev.ea:security:1981,
+ author = {D. Dolev and A. C. Yao},
+ title = {On the security of public key protocols},
+ journal = {Symposium on Foundations of Computer Science},
+ volume = 0,
+ year = 1981,
+ issn = {0272-5428},
+ pages = {350--357},
+ doi = {10.1109/SFCS.1981.32},
+ publisher = {IEEE Computer Society},
+ address = {Los Alamitos, CA, USA}
+}
+
+@InProceedings{ levin.ea:securing:2009,
+ author = {Timothy E. Levin and Jeffrey S. Dwoskin and Ganesha
+ Bhaskara and Thuy D. Nguyen and Paul C. Clark and Ruby B.
+ Lee and Cynthia E. Irvine and Terry Benzel},
+ title = {Securing the Dissemination of Emergency Response Data with
+ an Integrated Hardware-Software Architecture},
+ year = 2009,
+ pages = {133--152},
+ doi = {10.1007/978-3-642-00587-9_9},
+ crossref = {chen.ea:trusted:2009},
+ abstract = {During many crises, access to sensitive emergency-support
+ information is required to save lives and property. For
+ example, for effective evacuations first responders need
+ the names and addresses of non-ambulatory residents. Yet,
+ currently, access to such information may not be possible
+ because government policy makers and third-party data
+ providers lack confidence that today{\^a}s IT systems will
+ protect their data. Our approach to the management of
+ emergency information provides first responders with
+ temporary, transient access to sensitive information, and
+ ensures that the information is revoked after the
+ emergency. The following contributions are presented: a
+ systematic analysis of the basic forms of trusted
+ communication supported by the architecture; a
+ comprehensive method for secure, distributed emergency
+ state management; a method to allow a userspace application
+ to securely display data; a multifaceted system analysis of
+ the confinement of emergency information and the secure and
+ complete revocation of access to that information at the
+ closure of an emergency.}
+}
+
+@Proceedings{ chen.ea:trusted:2009,
+ editor = {Liqun Chen and Chris J. Mitchell and Andrew Martin},
+ booktitle = PROC # {International Conference on Trusted
+ Computing (Trust)},
+ location = {Trusted Computing, Second International Conference, Trust
+ 2009, Oxford, UK, April 6-8, 2009, Proceedings},
+ series = s-lncs,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ volume = 5471,
+ year = 2009,
+ isbn = {978-3-642-00586-2},
+ doi = {10.1007/978-3-642-00587-9}
+}
+
+@Book{ wunder.ea:verteilte:2009,
+ editor = {Michael Wunder and J{\"u}rgen Grosche},
+ title = {Verteilte F{\"u}hrungsinformationssysteme},
+ abstract = {R{\"u}ckblick und Sachstand der technologischen Aspekte
+ bei der Entwicklung verteilter
+ F{\"u}hrungsinformationssysteme, einer zentralen Aufgabe in
+ der Bundeswehr sowie bei Beh{\"o}rden und Organisationen
+ mit Sicherheitsaufgeben (z.B. Polizei, Rettungskr{\"a}fte).
+
+ Vornehmlich Wissenschaftler der Abteilung
+ Informationstechnik f{\"u}r F{\"u}hrungssysteme des
+ Forschungsinstituts f{\"u}r Kommunikation,
+ Informationsverarbeitung und Ergonomie beschreiben
+ basierend auf einer 40-j{\"a}hrigen Erfahrung in diesem
+ Anwendungsgebiet Konzepte und Einzelaspekte bei der
+ Gestaltung von F{\"u}hrungsinformationssystemen.
+ Reflektiert werden aktuelle Problembereiche bei der
+ Vernetzung unterschiedlicher Systeme, einer der derzeit
+ gr{\"o}{\ss}ten Herausforderungen bei der Neugestaltung der
+ Abl{\"a}ufe und Systeme in der Bundeswehr und in verwandten
+ Einrichtungen. Dazu werden Informationsstrukturen und
+ Prozesse untersucht, Systemarchitekturen ausgewertet und
+ kombiniert sowie Laborstudien und Feldversuche beschrieben.
+
+ In ca. 25 Beitr{\"a}gen wird eine L{\"u}cke in der
+ verf{\"u}gbaren Literatur geschlossen, die der Vielzahl von
+ Entwicklern und Anwendern einen Einblick in die aktuelle
+ Lage und die zuk{\"u}nftigen Gestaltungsm{\"o}glichkeiten bietet.},
+ isbn = {978-3-642-00508-4},
+ language = {German},
+ doi = {10.1007/978-3-642-00509-1},
+ year = 2009,
+ publisher = pub-springer,
+ address = pub-springer:adr
+}
+
+@InProceedings{ levin.ea:idea:2009,
+ author = {Timothy E. Levin and Cynthia E. Irvine and Terry Benzel
+ and Thuy D. Nguyen and Paul C. Clark and Ganesha Bhaskara},
+ title = {Idea: Trusted Emergency Management},
+ booktitle = {ESSoS},
+ year = 2009,
+ pages = {32--36},
+ doi = {10.1007/978-3-642-00199-4_3},
+ abstract = {Through first-responder access to sensitive information
+ for which they have not been pre-vetted, lives and property
+ can be saved. We describe enhancements to a trusted
+ emergency information management (EIM) system that securely
+ allows for extraordinary access to sensitive information
+ during a crisis. A major component of the architecture is
+ the end-user device, the security of which is enhanced with
+ processor-level encryption of memory. This paper introduces
+ an approach to more efficiently use the
+ processor-encryption feature for secure data storage, as
+ well as ISA instructions for the management of emergency
+ state.},
+ crossref = {massacci.ea:engineering:2009}
+}
+
+@Proceedings{ massacci.ea:engineering:2009,
+ editor = {Fabio Massacci and Samuel T. Redwine Jr. and Nicola
+ Zannone},
+ title = {Engineering Secure Software and Systems, First
+ International Symposium ESSoS 2009, Leuven, Belgium,
+ February 4-6, 2009. Proceedings},
+ booktitle = {ESSoS},
+ volume = 5429,
+ year = 2009,
+ isbn = {978-3-642-00198-7},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ doi = {10.1007/978-3-642-00199-4}
+}
+
+@Article{ phan.ea:survey:2008,
+ author = {Tan Phan and Jun Han and Jean-Guy Schneider and Tim
+ Ebringer and Tony Rogers},
+ title = {A Survey of Policy-Based Management Approaches for Service
+ Oriented Systems},
+ journal = {Australian Software Engineering Conference},
+ volume = 0,
+ year = 2008,
+ issn = {1530-0803},
+ pages = {392--401},
+ doi = {10.1109/ASWEC.2008.56},
+ address = pub-ieee:adr,
+ publisher = pub-ieee,
+ abstract = {Policy based management in Service Oriented Architecture
+ (SOA) allows organizations to apply rules and regulations
+ on their business processes. Policy has long been employed
+ in the management of traditional distributed systems and
+ many policy frameworks have been proposed. However,SOA
+ differs in several aspects to traditional systems; thus,
+ there is a unique set of requirements for an effective SOA
+ policy system. In this paper, we evaluate five popular
+ policy frameworks which are IETF, Ponder, KAoS, Rei and
+ WS-Policy against a number of general and SOA-specific
+ criteria to identify what features of these existing
+ systems can be adopted for SOA and what are not. We then,
+ based on their feature sets, discuss the applicability of
+ the frameworks for SOA management.}
+}
+
+@InProceedings{ sevinc.ea:securing:2007,
+ author = {Paul E. Sevin\c{c} and Mario Strasser and David A. Basin},
+ title = {Securing the Distribution and Storage of Secrets with
+ Trusted Platform Modules},
+ booktitle = {WISTP},
+ year = 2007,
+ pages = {53--66},
+ doi = {10.1007/978-3-540-72354-7_5},
+ crossref = {sauveron.ea:information:2007},
+ abstract = {We present a protocol that allows servers to securely
+ distribute secrets to trusted platforms. The protocol
+ maintains the confidentiality of secrets in the face of
+ eavesdroppers and careless users. Given an ideal
+ (tamper-proof) trusted platform, the protocol can even
+ withstand attacks by dishonest users. As an example of its
+ use, we present an application to secure document
+ processing.}
+}
+
+@Proceedings{ sauveron.ea:information:2007,
+ editor = {Damien Sauveron and Constantinos Markantonakis and Angelos
+ Bilas and Jean-Jacques Quisquater},
+ title = {Information Security Theory and Practices. Smart Cards,
+ Mobile and Ubiquitous Computing Systems, First IFIP TC6 /
+ WG 8.8 / WG 11.2 International Workshop, WISTP 2007,
+ Heraklion, Crete, Greece, May 9-11, 2007, Proceedings},
+ booktitle = {WISTP},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 4462,
+ year = 2007,
+ isbn = {978-3-540-72353-0}
+}
+
+@InProceedings{ liu.ea:fabric:2009,
+ author = {Jed Liu and Michael D. George and K. Vikram and Xin Qi and
+ Lucas Waye and Andrew C. Myers},
+ title = {Fabric: a platform for secure distributed computation and
+ storage},
+ booktitle = {SOSP '09: Proceedings of the ACM SIGOPS 22nd symposium on
+ Operating systems principles},
+ year = 2009,
+ isbn = {978-1-60558-752-3},
+ pages = {321--334},
+ location = {Big Sky, Montana, USA},
+ doi = {10.1145/1629575.1629606},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ abstract = {Fabric is a new system and language for building secure
+ distributed information systems. It is a decentralized
+ system that allows heterogeneous network nodes to securely
+ share both information and computation resources despite
+ mutual distrust. Its high-level programming language makes
+ distribution and persistence largely transparent to
+ programmers. Fabric supports data-shipping and
+ function-shipping styles of computation: both computation
+ and information can move between nodes to meet security
+ requirements or to improve performance. Fabric provides a
+ rich, Java-like object model, but data resources are
+ labeled with confidentiality and integrity policies that
+ are enforced through a combination of compile-time and
+ run-time mechanisms. Optimistic, nested transactions ensure
+ consistency across all objects and nodes. A peer-to-peer
+ dissemination layer helps to increase availability and to
+ balance load. Results from applications built using Fabric
+ suggest that Fabric has a clean, concise programming model,
+ offers good performance, and enforces security.}
+}
+
+@InProceedings{ ferreira.ea:how:2009,
+ author = {Ana Ferreira and David Chadwick and Pedro Farinha and
+ Gansen Zhao and Rui Chilro and Ricardo Cruz-Correia and
+ Luis Antunes},
+ title = {How to securely break into RBAC: the BTG-RBAC model},
+ booktitle = {Annual Computer Security Applications Conference (ACSAC)},
+ year = 2009,
+ abstract = {Access control models describe frameworks that dictate how
+ subjects (e.g. users) access resources. In the Role-Based
+ Access Control (RBAC) model access to resources is based on
+ the role the user holds within the organization. Although
+ flexible and easier to manage within large-scale
+ authorization frameworks, RBAC is usually a static model
+ where access control decisions have only two output
+ options: Grant or Deny. Break The Glass (BTG) policies can
+ be provided in order to break or override the access
+ controls within an access control policy but in a
+ controlled and justifiable manner. The main objective of
+ this paper is to integrate BTG within the NIST/ANSI RBAC
+ model in a transparent and secure way so that it can be
+ adopted generically in any domain where unanticipated or
+ emergency situations may occur. The new proposed model,
+ called BTG-RBAC, provides a third decision option BTG. This
+ allows break the glass policies to be implemented in any
+ application without any major changes to either the
+ application or the RBAC authorization infrastructure, apart
+ from the decision engine. Finally, in order to validate the
+ model, we discuss how the BTG-RBAC model is being
+ introduced within a Portuguese healthcare institution where
+ the legislation requires that genetic information must be
+ accessed by a restricted group of healthcare professionals.
+ These professionals, advised by the ethical committee, have
+ required and asked for the implementation of the BTG
+ concept in order to comply with the said legislation.}
+}
+
+@Article{ moggi:notions:1991,
+ author = {Eugenio Moggi},
+ title = {Notions of Computation and Monads},
+ journal = {Information and Computation},
+ volume = 93,
+ number = 1,
+ year = 1991,
+ pages = {55--92}
+}
+
+@InProceedings{ wadler:monads:1995,
+ author = {Philip Wadler},
+ title = {Monads for Functional Programming},
+ booktitle = {Advanced Functional Programming},
+ year = 1995,
+ pages = {24--52},
+ crossref = {jeuring.ea:advanced:1995}
+}
+
+@Proceedings{ jeuring.ea:advanced:1995,
+ editor = {Johan Jeuring and Erik Meijer},
+ title = {Advanced Functional Programming, First International
+ Spring School on Advanced Functional Programming
+ Techniques, B{\aa}stad, Sweden, May 24-30, 1995, Tutorial
+ Text},
+ booktitle = {Advanced Functional Programming},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 925,
+ year = 1995,
+ isbn = {3-540-59451-5}
+}
+
+@InProceedings{ grieskamp.ea:model-based:2008,
+ author = {Wolfgang Grieskamp and Nicolas Kicillof and Dave MacDonald
+ and Alok Nandan and Keith Stobie and Fred L. Wurden},
+ title = {Model-Based Quality Assurance of Windows Protocol
+ Documentation},
+ booktitle = {Software Testing, Verification, and Validation (ICST)},
+ year = 2008,
+ pages = {502--506},
+ doi = {10.1109/ICST.2008.50},
+ abstract = {Microsoft is producing high-quality documentation for
+ Windows client-server and server-server protocols. Our
+ group in the Windows organization is responsible for
+ verifying the documentation to ensure it is of the highest
+ quality. We are applying various test-driven methods
+ including, when appropriate, a model-based approach. This
+ paper describes certain aspects of the quality assurance
+ process we put in place, and specifically focuses on
+ model-based testing (MBT). Our experiences so far confirm
+ that MBT works and that it scales, provided it is
+ accompanied by sound tool support and clear methodological
+ guidance.},
+ location = {Lillehammer, Norway, April 9-11, 2008},
+ volume = 0,
+ isbn = {978-0-7695-3127-4},
+ publisher = pub-ieee,
+ address = pub-ieee:adr
+}
+
+@InProceedings{ berghofer.ea:random:2004,
+ author = {Stefan Berghofer and Tobias Nipkow},
+ title = {Random Testing in Isabelle/HOL},
+ booktitle = {Software Engineering and Formal Methods (SEFM)},
+ year = 2004,
+ pages = {230--239},
+ doi = {10.1109/SEFM.2004.36},
+ abstract = {When developing non-trivial formalizations in a theorem
+ prover, a considerable amount of time is devoted to
+ "debugging" specifications and conjectures by failed proof
+ attempts. To detect such problems early in the proof and
+ save development time, we have extended the Isabelle
+ theorem prover with a tool for testing specifications by
+ evaluating propositions under an assignment of random
+ values to free variables. Distribution of the test data is
+ optimized via mutation testing. The technical contributions
+ are an extension of earlier work with inductive definitions
+ and a generic method for randomly generating elements of
+ recursive datatypes.},
+ location = {28-30 September 2004, Beijing, China},
+ publisher = pub-ieee,
+ address = pub-ieee:adr,
+ isbn = {0-7695-2222-X}
+}
+
+@TechReport{ gallaher.ea:economic:2002,
+ institution = {National Institute of Standards \& Technology},
+ number = {Planning Report 02-03},
+ year = 2002,
+ month = may,
+ author = {M.P. Gallaher and B.M. Kropp},
+ title = {The Economic Impacts of Inadequate Infrastructure for
+ Software Testing},
+ abstract = {Software has become an intrinsic part of business over the
+ last decade. Virtually every business in the U.S. in every
+ sector depends on it to aid in the development, production,
+ marketing, and support of its products and services.
+ Advances in computers and related technology have provided
+ the building blocks on which new industries have evolved.
+ Innovations in the fields of robotic manufacturing,
+ nanotechnologies, and human genetics research all have been
+ enabled by low cost computational and control capabilities
+ supplied by computers and software. In 2000, total sales of
+ software reached approximately \$180 billion. Rapid growth
+ has created a significant and high-paid workforce, with
+ 697,000 employed as software engineers and an additional
+ 585,000 as computer programmers. Reducing the cost of
+ software development and improving software quality are
+ important objectives of the U.S. software industry.
+ However, the complexity of the underlying software needed
+ to support the U.S.'s computerized economy is increasing at
+ an alarming rate. The size of software products is no
+ longer measured in terms of thousands of lines of code, but
+ millions of lines of code. This increasing complexity along
+ with a decreasing average market life expectancy for many
+ software products has heightened concerns over software
+ quality.}
+}
+
+@InProceedings{ tej.ea:corrected:1997,
+ author = {Haykal Tej and Burkhart Wolff},
+ title = {A Corrected Failure Divergence Model for {CSP} in
+ {Isabelle/HOL}},
+ year = 1997,
+ pages = {318--337},
+ doi = {10.1007/3-540-63533-5_17},
+ abstract = {We present a failure-divergence model for CSP following
+ the concepts of [BR 85]. Its formal representation within
+ higher order logic in the theorem prover Isabelle/HOL [Pau
+ 94] revealed an error in the basic definition of CSP
+ concerning the treatment of the termination symbol tick. A
+ corrected model has been formally proven consistent with
+ Isabelle/HOL. Moreover, the changed version maintains the
+ essential algebraic properties of CSP. As a result, there
+ is a proven correct implementation of a ldquoCSP
+ workbenchrdquo within Isabelle.},
+ crossref = {fitzgerald.ea:formal:1997}
+}
+
+@Proceedings{ fitzgerald.ea:formal:1997,
+ editor = {John S. Fitzgerald and Cliff B. Jones and Peter Lucas},
+ booktitle = {Formal Methods Europe (FME)},
+ location = {Graz, Austria, September 15-19, 1997, Proceedings},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 1313,
+ year = 1997,
+ isbn = {3-540-63533-5}
+}
+
+@InProceedings{ bentakouk.ea:formal:2009,
+ author = {Lina Bentakouk and Pascal Poizat and Fatiha Za\"{\i}di},
+ title = {A Formal Framework for Service Orchestration Testing Based
+ on Symbolic Transition Systems},
+ year = 2009,
+ pages = {16--32},
+ doi = {10.1007/978-3-642-05031-2_2},
+ crossref = {nunez.ea:testing:2009},
+ abstract = {The pre-eminent role played by software composition, and
+ more particularly service composition, in modern software
+ development, together with the complexity of workflow
+ languages such as WS-BPEL have made composite service
+ testing a topical issue. In this article we contribute to
+ this issue with an automatic testing approach for WS-BPEL
+ orchestrations. Compared to related work, we support
+ WS-BPEL data computations and exchanges, while overcoming
+ the consequential state explosion problem. This is achieved
+ through the use of symbolic transition system models and
+ their symbolic execution. Throughout the article, we
+ illustrate our approach on a realistic medium-size example.
+
+ }
+}
+
+@Proceedings{ nunez.ea:testing:2009,
+ editor = {Manuel N{\'u}{\~n}ez and Paul Baker and Mercedes G. Merayo},
+ title = {Testing of Software and Communication Systems, 21st IFIP
+ WG 6.1 International Conference, TESTCOM 2009 and 9th
+ International Workshop, FATES 2009, Eindhoven, The
+ Netherlands, November 2-4, 2009. Proceedings},
+ booktitle = {TestCom/FATES},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 5826,
+ year = 2009,
+ isbn = {978-3-642-05030-5},
+ doi = {10.1007/978-3-642-05031-2}
+}
+
+@InProceedings{ anand.ea:demand-driven:2008,
+ author = {Saswat Anand and Patrice Godefroid and Nikolai Tillmann},
+ title = {Demand-Driven Compositional Symbolic Execution},
+ booktitle = {TACAS},
+ year = 2008,
+ pages = {367--381},
+ doi = {10.1007/978-3-540-78800-3_28},
+ crossref = {ramakrishnan.ea:tools:2008},
+ abstract = {We discuss how to perform symbolic execution of large
+ programs in a manner that is both compositional (hence more
+ scalable) and demand-driven. Compositional symbolic
+ execution means finding feasible interprocedural program
+ paths by composing symbolic executions of feasible
+ intraprocedural paths. By demand-driven, we mean that as
+ few intraprocedural paths as possible are symbolically
+ executed in order to form an interprocedural path leading
+ to a specific target branch or statement of interest (like
+ an assertion). A key originality of this work is that our
+ demand-driven compositional interprocedural symbolic
+ execution is performed entirely using first-order logic
+ formulas solved with an off-the-shelf SMT
+ (Satisfiability-Modulo-Theories) solver {\^a} no procedure
+ in-lining or custom algorithm is required for the
+ interprocedural part. This allows a uniform and elegant way
+ of summarizing procedures at various levels of detail and
+ of composing those using logic formulas. We have
+ implemented a prototype of this novel symbolic execution
+ technique as an extension of Pex, a general automatic
+ testing framework for .NET applications. Preliminary
+ experimental results are encouraging. For instance, our
+ prototype was able to generate tests triggering assertion
+ violations in programs with large numbers of program paths
+ that were beyond the scope of non-compositional test
+ generation. }
+}
+
+@Proceedings{ ramakrishnan.ea:tools:2008,
+ editor = {C. R. Ramakrishnan and Jakob Rehof},
+ title = {Tools and Algorithms for the Construction and Analysis of
+ Systems, 14th International Conference, TACAS 2008, Held as
+ Part of the Joint European Conferences on Theory and
+ Practice of Software, ETAPS 2008, Budapest, Hungary, March
+ 29-April 6, 2008. Proceedings},
+ booktitle = {TACAS},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 4963,
+ year = 2008,
+ isbn = {978-3-540-78799-0}
+}
+
+@InProceedings{ boyapati.ea:korat:2002,
+ author = {Chandrasekhar Boyapati and Sarfraz Khurshid and Darko
+ Marinov},
+ title = {{Korat}: automated testing based on {Java} predicates},
+ booktitle = {ISSTA},
+ year = 2002,
+ pages = {123--133},
+ doi = {10.1145/566172.566191},
+ abstract = {This paper presents Korat, a novel framework for automated
+ testing of Java programs. Given a formal specification for
+ a method, Korat uses the method precondition to
+ automatically generate all (nonisomorphic) test cases up to
+ a given small size. Korat then executes the method on each
+ test case, and uses the method postcondition as a test
+ oracle to check the correctness of each output.To generate
+ test cases for a method, Korat constructs a Java predicate
+ (i.e., a method that returns a boolean) from the method's
+ pre-condition. The heart of Korat is a technique for
+ automatic test case generation: given a predicate and a
+ bound on the size of its inputs, Korat generates all
+ (nonisomorphic) inputs for which the predicate returns
+ true. Korat exhaustively explores the bounded input space
+ of the predicate but does so efficiently by monitoring the
+ predicate's executions and pruning large portions of the
+ search space.This paper illustrates the use of Korat for
+ testing several data structures, including some from the
+ Java Collections Framework. The experimental results show
+ that it is feasible to generate test cases from Java
+ predicates, even when the search space for inputs is very
+ large. This paper also compares Korat with a testing
+ framework based on declarative specifications. Contrary to
+ our initial expectation, the experiments show that Korat
+ generates test cases much faster than the declarative
+ framework.}
+}
+
+@Article{ visser.ea:model:2003,
+ author = {Willem Visser and Klaus Havelund and Guillaume P. Brat and
+ Seungjoon Park and Flavio Lerda},
+ title = {Model Checking Programs},
+ journal = {Autom. Softw. Eng.},
+ volume = 10,
+ number = 2,
+ year = 2003,
+ pages = {203--232},
+ doi = {10.1023/A:1022920129859},
+ abstract = {The majority of work carried out in the formal methods
+ community throughout the last three decades has (for good
+ reasons) been devoted to special languages designed to make
+ it easier to experiment with mechanized formal methods such
+ as theorem provers, proof checkers and model checkers. In
+ this paper we will attempt to give convincing arguments for
+ why we believe it is time for the formal methods community
+ to shift some of its attention towards the analysis of
+ programs written in modern programming languages. In
+ keeping with this philosophy we have developed a
+ verification and testing environment for Java, called Java
+ PathFinder (JPF), which integrates model checking, program
+ analysis and testing. Part of this work has consisted of
+ building a new Java Virtual Machine that interprets Java
+ bytecode. JPF uses state compression to handle big states,
+ and partial order and symmetry reduction, slicing,
+ abstraction, and runtime analysis techniques to reduce the
+ state space. JPF has been applied to a real-time avionics
+ operating system developed at Honeywell, illustrating an
+ intricate error, and to a model of a spacecraft controller,
+ illustrating the combination of abstraction, runtime
+ analysis, and slicing with model checking.}
+}
+
+@InProceedings{ bjorner.ea:path:2009,
+ author = {Nikolaj Bj{\o}rner and Nikolai Tillmann and Andrei
+ Voronkov},
+ title = {Path Feasibility Analysis for String-Manipulating
+ Programs},
+ booktitle = {TACAS},
+ year = 2009,
+ pages = {307--321},
+ doi = {10.1007/978-3-642-00768-2_27},
+ crossref = {kowalewski.ea:tools:2009},
+ abstract = {We discuss the problem of path feasibility for programs
+ manipulating strings using a collection of standard string
+ library functions. We prove results on the complexity of
+ this problem, including its undecidability in the general
+ case and decidability of some special cases. In the context
+ of test-case generation, we are interested in an efficient
+ finite model finding method for string constraints. To this
+ end we develop a two-tier finite model finding procedure.
+ First, an integer abstraction of string constraints are
+ passed to an SMT (Satisfiability Modulo Theories) solver.
+ The abstraction is either unsatisfiable, or the solver
+ produces a model that fixes lengths of enough strings to
+ reduce the entire problem to be finite domain. The
+ resulting fixed-length string constraints are then solved
+ in a second phase. We implemented the procedure in a
+ symbolic execution framework, report on the encouraging
+ results and discuss directions for improving the method
+ further.}
+}
+
+@Proceedings{ kowalewski.ea:tools:2009,
+ editor = {Stefan Kowalewski and Anna Philippou},
+ title = {Tools and Algorithms for the Construction and Analysis of
+ Systems, 15th International Conference, TACAS 2009, Held as
+ Part of the Joint European Conferences on Theory and
+ Practice of Software, ETAPS 2009, York, UK, March 22-29,
+ 2009. Proceedings},
+ booktitle = {TACAS},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 5505,
+ year = 2009,
+ isbn = {978-3-642-00767-5},
+ doi = {10.1007/978-3-642-00768-2}
+}
+
+@InProceedings{ huima:implementing:2007,
+ author = {Antti Huima},
+ title = {Implementing Conformiq Qtronic},
+ booktitle = {TestCom/FATES},
+ year = 2007,
+ pages = {1--12},
+ doi = {10.1007/978-3-540-73066-8_1},
+ crossref = {petrenko.ea:testing:2007},
+ abstract = {Conformiq Qtronic is a commercial tool for model driven
+ testing. It derives tests automatically from behavioral
+ system models. These are black-box tests [1] by nature,
+ which means that they depend on the model and the
+ interfaces of the system under test, but not on the
+ internal structure (e.g. source code) of the
+ implementation. In this essay, which accompanies my invited
+ talk, I survey the nature of Conformiq Qtronic, the main
+ implementation challenges that we have encountered and how
+ we have approached them.}
+}
+
+@Proceedings{ petrenko.ea:testing:2007,
+ editor = {Alexandre Petrenko and Margus Veanes and Jan Tretmans and
+ Wolfgang Grieskamp},
+ title = {Testing of Software and Communicating Systems, 19th IFIP
+ TC6/WG6.1 International Conference, TestCom 2007, 7th
+ International Workshop, FATES 2007, Tallinn, Estonia, June
+ 26-29, 2007, Proceedings},
+ booktitle = {TestCom/FATES},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 4581,
+ year = 2007,
+ isbn = {978-3-540-73065-1}
+}
+
+@InProceedings{ tretmans.ea:torx:2003,
+ howpublished = {http://eprints.eemcs.utwente.nl/9475/},
+ month = {December},
+ author = {G. J. Tretmans and H. Brinksma},
+ booktitle = {First European Conference on Model-Driven Software
+ Engineering, Nuremberg, Germany},
+ editor = {A. Hartman and K. Dussa-Ziegler},
+ abstract = {Systematic testing is very important for assessing and
+ improving the quality of software systems. Yet, testing
+ turns out to be expensive, laborious, time-consuming and
+ error-prone. The Dutch research and development project
+ C\^ote de Resyste worked on methods, techniques and tools
+ for automating specification based testing using formal
+ methods. The main achievement of the project is a test
+ tool, baptized TorX, which integrates automatic test
+ generation, test execution, and test analysis in an
+ on-the-fly manner. On the one hand, TorX is based on
+ well-defined theory, viz. the ioco-test theory, which has
+ its roots in the theory of testing- and
+ refusal-equivalences for transition systems. On the other
+ hand, the applicability of TorX has been demonstrated by
+ testing several academic and industrial case studies. This
+ paper summarizes the main results of the project C\^ote de
+ Resyste.},
+ title = {TorX: Automated Model-Based Testing},
+ year = 2003,
+ pages = {31--43},
+ location = {Nuremberg, Germany},
+ trnumber = 9475,
+ event_dates = {December 11-12, 2003},
+ num_pages = 13
+}
+
+@InProceedings{ jaffuel.ea:leirios:2007,
+ author = {Eddie Jaffuel and Bruno Legeard},
+ title = {LEIRIOS Test Generator: Automated Test Generation from B
+ Models},
+ booktitle = {B},
+ year = 2007,
+ pages = {277--280},
+ doi = {10.1007/11955757_29},
+ crossref = {julliand.ea:b:2006},
+ abstract = {Since 2003, automated test generation from B abstract
+ machines has been trying out in the smart card industry,
+ using LEIRIOS Test Generator (LTG) for SmartCard tool. Now
+ the major card manufacturers, such as Gemalto and Giesecke
+ & Devrient, are regularly deploying model-based testing in
+ their validation processes. The purpose is black-box
+ functional testing: from the specifications (a standard or
+ specific requirements), a B formal model is developed which
+ is the basis for test generation. Generated test cases are
+ then translated into executable test scripts and then run
+ on the application.}
+}
+
+@Proceedings{ julliand.ea:b:2006,
+ editor = {Jacques Julliand and Olga Kouchnarenko},
+ title = {B 2007: Formal Specification and Development in B, 7th
+ International Conference of B Users, Besan\c{c}on, France,
+ January 17-19, 2007, Proceedings},
+ booktitle = {B},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 4355,
+ year = 2006,
+ isbn = {3-540-68760-2}
+}
+
+@InProceedings{ hu.ea:enabling:2008,
+ author = {Hongxin Hu and Gail-Joon Ahn},
+ title = {Enabling verification and conformance testing for access
+ control model},
+ booktitle = {ACM symposium on Access control models and technologies
+ (SACMAT)},
+ year = 2008,
+ isbn = {978-1-60558-129-3},
+ pages = {195--204},
+ location = {Estes Park, CO, USA},
+ doi = {10.1145/1377836.1377867},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ abstract = {Verification and testing are the important step for
+ software assurance. However, such crucial and yet
+ challenging tasks have not been widely adopted in building
+ access control systems. In this paper we propose a
+ methodology to support automatic analysis and conformance
+ testing for access control systems, integrating those
+ features to Assurance Management Framework (AMF). Our
+ methodology attempts to verify formal specifications of a
+ role-based access control model and corresponding policies
+ with selected security properties. Also, we systematically
+ articulate testing cases from formal specifications and
+ validate conformance to the system design and
+ implementation using those cases. In addition, we
+ demonstrate feasibility and effectiveness of our
+ methodology using SAT and Alloy toolset.}
+}
+
+@Article{ grindal.ea:combination:2005,
+ author = {Mats Grindal and Jeff Offutt and Sten F. Andler},
+ title = {Combination testing strategies: a survey},
+ journal = {Softw. Test., Verif. Reliab.},
+ volume = 15,
+ number = 3,
+ year = 2005,
+ pages = {167--199},
+ doi = {10.1002/stvr.319},
+ abstract = {Combination strategies are test case selection methods
+ that identify test cases by combining values of the
+ different test object input parameters based on some
+ combinatorial strategy. This survey presents 16 different
+ combination strategies, covering more than 40 papers that
+ focus on one or several combination strategies. This
+ collection represents most of the existing work performed
+ on combination strategies. This survey describes the basic
+ algorithms used by the combination strategies. Some
+ properties of combination strategies, including coverage
+ criteria and theoretical bounds on the size of test suites,
+ are also included in this description. This survey paper
+ also includes a subsumption hierarchy that attempts to
+ relate the various coverage criteria associated with the
+ identified combination strategies.}
+}
+
+@InProceedings{ goga:comparing:2001,
+ author = {Nicolae Goga},
+ title = {Comparing TorX, Autolink, TGV and UIO Test Algorithms},
+ booktitle = {SDL Forum},
+ year = 2001,
+ pages = {379--402},
+ doi = {10.1007/3-540-48213-X},
+ crossref = {reed.ea:sdl:2001},
+ abstract = {This paper presents a comparison of four algorithms for
+ test derivation: TorX, TGV, Autolink and UIO algorithms.
+ The algorithms are classified according to the detection
+ power of their conformance rela- tions. Because Autolink
+ does not have an explicit conformance relation, a
+ conformance relation is reconstructed for it. The
+ experimental results obtained by applying TorX, Autolink,
+ UIO and TGV to the Conference Protocol case study are
+ consistent with the theoretical results of this paper.}
+}
+
+@Proceedings{ reed.ea:sdl:2001,
+ editor = {Rick Reed and Jeanne Reed},
+ title = {SDL 2001: Meeting UML, 10th International SDL Forum
+ Copenhagen, Denmark, June 27-29, 2001, Proceedings},
+ booktitle = {SDL Forum},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2078,
+ year = 2001,
+ isbn = {3-540-42281-1}
+}
+
+@InProceedings{ belinfante.ea:tools:2004,
+ author = {Axel Belinfante and Lars Frantzen and Christian
+ Schallhart},
+ title = {Tools for Test Case Generation},
+ booktitle = {Model-Based Testing of Reactive Systems},
+ year = 2004,
+ pages = {391--438},
+ doi = {10.1007/11498490_18},
+ crossref = {broy.ea:model-based:2005}
+}
+
+@Proceedings{ broy.ea:model-based:2005,
+ editor = {Manfred Broy and Bengt Jonsson and Joost-Pieter Katoen and
+ Martin Leucker and Alexander Pretschner},
+ title = {Model-Based Testing of Reactive Systems, Advanced Lectures
+ [The volume is the outcome of a research seminar that was
+ held in Schloss Dagstuhl in January 2004]},
+ booktitle = {Model-Based Testing of Reactive Systems},
+ volume = 3472,
+ year = 2005,
+ isbn = {3-540-26278-4},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs
+}
+
+@InProceedings{ gardner.ea:securing:2009,
+ author = {Ryan W. Gardner and Sujata Garera and Matthew W. Pagano
+ and Matthew Green and Aviel D. Rubin},
+ title = {Securing medical records on smart phones},
+ booktitle = {ACM workshop on Security and privacy in medical and
+ home-care systems (SPIMACS)},
+ year = 2009,
+ isbn = {978-1-60558-790-5},
+ pages = {31--40},
+ location = {Chicago, Illinois, USA},
+ doi = {10.1145/1655084.1655090},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ abstract = {There is an inherent conflict between the desire to
+ maintain privacy of one's medical records and the need to
+ make those records available during an emergency. To
+ satisfy both objectives, we introduce a flexible
+ architecture for the secure storage of medical records on
+ smart phones. In our system, a person can view her records
+ at any time, and emergency medical personnel can view the
+ records as long as the person is present (even if she is
+ unconscious). Our solution allows for efficient revocation
+ of access rights and is robust against adversaries who can
+ access the phone's storage offline.}
+}
+
+
+@Article{ govaerts.ea:formal:2008,
+ author = {John Govaerts and Arosha K. Bandara and Kevin Curran},
+ title = {A formal logic approach to firewall packet filtering
+ analysis and generation},
+ journal = {Artif. Intell. Rev.},
+ volume = 29,
+ number = {3-4},
+ year = 2008,
+ pages = {223--248},
+ doi = {10.1007/s10462-009-9147-0},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ abstract = {Recent years have seen a significant increase in the usage
+ of computers and their capabilities to communicate with
+ each other. With this has come the need for more security
+ and firewalls have proved themselves an important piece of
+ the overall architecture, as the body of rules they
+ implement actually realises the security policy of their
+ owners. Unfor- tunately, there is little help for their
+ administrators to understand the actual meaning of the
+ firewall rules. This work shows that formal logic is an
+ important tool in this respect, because it is particularly
+ apt at modelling real-world situations and its formalism is
+ conductive to reason about such a model. As a consequence,
+ logic may be used to prove the properties of the models it
+ represents and is a sensible way to go in order to create
+ those models on com- puters to automate such activities. We
+ describe here a prototype which includes a description of a
+ network and the body of firewall rules applied to its
+ components. We were able to detect a number of anomalies
+ within the rule-set: inexistent elements (e.g. hosts or
+ services on destination components), redundancies in rules
+ defining the same action for a network and hosts belonging
+ to it, irrelevance as rules would involve traffic that
+ would not pass through a filtering device, and
+ contradiction in actions applied to elements or to a
+ network and its hosts. The prototype produces actual
+ firewall rules as well, generated from the model and
+ expressed in the syntax of IPChains and Cisco's PIX. }
+}
+
+@InProceedings{ jalili.ea:specification:2002,
+ author = {Rasool Jalili and Mohsen Rezvani},
+ title = {Specification and Verification of Security Policies in
+ Firewalls},
+ booktitle = {EurAsia-ICT},
+ year = 2002,
+ pages = {154--163},
+ doi = {10.1007/3-540-36087-5_18},
+ crossref = {shafazand.ea:eurasia-ict:2002},
+ abstract = {Rules are used as a way of managing and configuring
+ firewalls to fulfill security requirements in most cases.
+ Managers have to specify their organizational security
+ policies using low level and order-dependent rules.
+ Furthermore, dependency of firewalls to the network
+ topology, frequent changes in network topology (specially
+ in dynamic networks), and lack of a method for analysis and
+ verification of specified security policy may reduce to
+ inconsistencies and security holes. Existence of a higher
+ level environment for security policy specification can
+ rectify part of the problems. In this paper we present a
+ language for high level and formal specification of
+ security policy in firewalls. Using the language, a
+ security manager can configure its firewall based on his
+ required security policy independent of the network
+ topology. The language is used as a framework for analysis
+ and verification of security policies. We designed and
+ implemented a tool based on theorem proving for detecting
+ inconsistencies, coverage, as well as applying a query on
+ the specified policy. Results of analysis can be used to
+ detect security vulnerabilities.}
+}
+
+@Proceedings{ shafazand.ea:eurasia-ict:2002,
+ editor = {Hassan Shafazand and A. Min Tjoa},
+ title = {EurAsia-ICT 2002: Information and Communication
+ Technology, First EurAsian Conference, Shiraz, Iran,
+ October 29-31, 2002, Proceedings},
+ booktitle = {EurAsia-ICT},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2510,
+ year = 2002,
+ isbn = {3-540-00028-3}
+}
+
+@Article{ sutter:free:2005,
+ author = {Herb Sutter},
+ journal = {Dr. Dobb{\^a}s Journal},
+ number = 3,
+ pages = {202--210},
+ title = {The Free Lunch Is Over: A Fundamental Turn Toward
+ Concurrency in Software},
+ url = {http://www.gotw.ca/publications/concurrency-ddj.htm},
+ volume = 30,
+ year = 2005
+}
+
+
+@InProceedings{ lachner.ea:information:2008,
+ author = {Janine Lachner and Hermann Hellwagner},
+ title = {Information and Communication Systems for Mobile Emergency
+ Response},
+ year = 2008,
+ pages = {213--224},
+ doi = {10.1007/978-3-540-78942-0_22},
+ crossref = {kaschek.ea:information:2008},
+ abstract = {This discussion paper attempts to propose emergency
+ response and disaster management as worthwhile areas of
+ applied research for the information system community. The
+ typical requirements, entities and activities involved in
+ specifically mobile emergency response operations are
+ summarized. Recent research contributions in this area are
+ exemplarily reviewed in order to give a deeper insight into
+ the role and use of mobile information and communication
+ systems. Finally, the major challenges and research needs
+ regarding information systems are summarized, with a view
+ to draw the attention of information systems researchers to
+ this interesting and important field.}
+}
+
+@Proceedings{ kaschek.ea:information:2008,
+ editor = {Roland Kaschek and Christian Kop and Claudia Steinberger
+ and G{\"u}nther Fliedl},
+ title = {Information Systems and e-Business Technologies, 2nd
+ International United Information Systems Conference,
+ UNISCON 2008, Klagenfurt, Austria, April 22-25, 2008,
+ Proceedings},
+ booktitle = {Information Systems and e-Business Technologies (UNISCON)},
+ series = s-lnbip,
+ volume = 5,
+ year = 2008,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ isbn = {978-3-540-78941-3},
+}
+@InProceedings{ johnson:complexity:2008,
+ author = {Chris W. Johnson},
+ title = {Complexity, Structured Chaos and the Importance of
+ Information Management for Mobile Computing in the {UK}
+ Floods of 2007},
+ booktitle = {Mobile Response},
+ year = 2008,
+ pages = {1--11},
+ doi = {10.1007/978-3-642-00440-7_1},
+ crossref = {loffler.ea:mobile:2009},
+ abstract = {Many research teams have developed mobile computing
+ architectures to support the emergency and rescue services
+ in a range of civil contingencies. These proposals are
+ based on innovative technologies and show considerable
+ creativity in the design of their user interfaces. In
+ contrast, this paper presents lessons learned from the 2007
+ UK floods. Mobile telecommunications failed in many
+ different ways and from many different causes, including
+ physical damage to handsets, as well as the loss of base
+ stations and UPSs. The insights gained from the floods are
+ being used to inform the design of next generation mobile
+ digital communications systems for UK responders. However,
+ the technical problems are arguably less important than the
+ insights that were obtained about {\^a}systemic{\^a}
+ failures in the interfaces between local government,
+ emergency services and the variety of agencies that must
+ cooperate in major civil contingencies. Problems in
+ information management led to inconsistencies and
+ incompatibilities. In consequence, the output from one
+ application could not easily be used as input to systems
+ operated by other agencies. These issues must be addressed
+ before we are overwhelmed by the increased bandwidth
+ afforded by new mobile devices and novel sensing
+ technologies. It is concluded that unless we understand the
+ chaos, complexity and the contextual issues that
+ characterise previous emergency situations then there is
+ little prospect that we will be able to design effective
+ mobile technologies for future incidents.}
+}
+
+@Proceedings{ loffler.ea:mobile:2009,
+ editor = {Jobst L{\"o}ffler and Markus Klann},
+ location = {Mobile Response, Second International Workshop on Mobile
+ Information Technology for Emergency Response,
+ MobileResponse 2008. Bonn, Germany, May 29-30, 2008,
+ Revised Selected Papers},
+ title = {Mobile Information Technology for Emergency Response,
+ (MobileResponse)},
+ booktitle = {Mobile Information Technology for Emergency Response,
+ (MobileResponse)},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 5424,
+ year = 2009,
+ isbn = {978-3-642-00439-1},
+ doi = {10.1007/978-3-642-00440-7}
+}
+
+
+@book{Hoare:1985:CSP:3921,
+ author = {Hoare, C. A. R.},
+ title = {Communicating Sequential Processes},
+ year = {1985},
+ isbn = {0-13-153271-5},
+ publisher = {Prentice-Hall, Inc.},
+ address = {Upper Saddle River, NJ, USA},
+}
+
+@InProceedings{brookes-roscoe85,
+author="Brookes, S. D. and Roscoe, A. W.",
+editor="Brookes, Stephen D. and Roscoe, Andrew William and Winskel, Glynn",
+title="An improved failures model for communicating processes",
+booktitle="Seminar on Concurrency",
+year="1985",
+publisher="Springer Berlin Heidelberg",
+address="Berlin, Heidelberg",
+pages="281--305",
+abstract="We extend the failures model of communicating processes to allow a more satisfactory treatment of divergence in addition to deadlock. The relationship between the revised model and the old model is discussed, and we make some connections with various models proposed by other authors.",
+isbn="978-3-540-39593-5"
+}
+
+@techreport{KriegBrueckner95,
+ author = {Krieg-Br\"uckner, B. and Peleska, J. and Olderog, E.-R. and Balzer, D. and Baer, A.},
+ title = "Uniform Workbench --- Universelle Entwicklungsumgebung f{\"u}r formale Methoden",
+ institution = "Technischer Bericht 8/95",
+ year=1995,
+ address="Univ. Bremen",
+ note="\url{http://www.informatik.uni-bremen.de/~uniform}"
+}
+
+@InProceedings{Camilleri91,
+author="Camilleri, Albert J.",
+editor="Birtwistle, Graham",
+title="A Higher Order Logic Mechanization of the CSP Failure-Divergence Semantics",
+booktitle="IV Higher Order Workshop, Banff 1990",
+year="1991",
+publisher="Springer London",
+address="London",
+pages="123--150",
+abstract="Reasoning using process algebras often involves doing complex proofs, and computer-based support to facilitate the task is therefore desirable. In this paper we show how a general-purpose theorem prover based on higher order logic provides a natural framework for mechanizing the process algebra CSP. This is done by defining the semantics of the CSP operators in the logic and proving the high-level algebraic laws from the definitions as theorems. We mechanize a variation on the failure-divergence semantics that does not use alphabets at the syntactic level, but embeds them in the semantics. Our approach abstracts further from the explicit use of alphabets by modelling them as type variables. The result is a mechanized theory for a polymorphic formalization of CSP.",
+isbn="978-1-4471-3182-3"
+}
+
+
+@InProceedings{FDRTutorial2000,
+author="Broadfoot, Philippa
+and Roscoe, Bill",
+editor="Havelund, Klaus
+and Penix, John
+and Visser, Willem",
+title="Tutorial on FDR and Its Applications",
+booktitle="SPIN Model Checking and Software Verification",
+year="2000",
+publisher="Springer Berlin Heidelberg",
+address="Berlin, Heidelberg",
+pages="322--322",
+abstract="FDR [1] is a refinement checker for the process algebra CSP [2,4], based on that language's well-established semantic models. FDR stands for Failures-Divergences Refinement, after the premier model. In common with many other model checkers, it works by ``determinising'' (or normalising) a specification and enumerating states in the cartesian product of this and the implementation. Unlike most, the specification and implementation are written in the same language. Under development by its creators, Formal Systems (a spin-off of the Computing Laboratory) since 1991, it now offers a range of state compression methods. On current workstations it can work at up to 20M states/hour with only a small degradation on moving to disc-based storage.",
+isbn="978-3-540-45297-3"
+}
+
+@article{IsobeRoggenbach2010,
+ title={CSP-Prover: a Proof Tool for the Verification of Scalable Concurrent Systems},
+ author={Yoshinao Isobe and Markus Roggenbach},
+ journal={Information and Media Technologies},
+ volume={5},
+ number={1},
+ pages={32-39},
+ year={2010},
+ doi={10.11185/imt.5.32}
+}
+
+@article{Noninterference_CSP-AFP,
+ author = {Pasquale Noce},
+ title = {Noninterference Security in Communicating Sequential Processes},
+ journal = {Archive of Formal Proofs},
+ month = may,
+ year = 2014,
+ note = {\url{http://isa-afp.org/entries/Noninterference_CSP.html},
+ Formal proof development},
+ ISSN = {2150-914x},
+}
+
+@article{Noninterference_Sequential_Composition-AFP,
+ author = {Pasquale Noce},
+ title = {Conservation of CSP Noninterference Security under Sequential Composition},
+ journal = {Archive of Formal Proofs},
+ month = apr,
+ year = 2016,
+ note = {\url{http://isa-afp.org/entries/Noninterference_Sequential_Composition.html},
+ Formal proof development},
+ ISSN = {2150-914x},
+}
+
+@article{Noninterference_Concurrent_Composition-AFP,
+ author = {Pasquale Noce},
+ title = {Conservation of CSP Noninterference Security under Concurrent Composition},
+ journal = {Archive of Formal Proofs},
+ month = jun,
+ year = 2016,
+ note = {\url{http://isa-afp.org/entries/Noninterference_Concurrent_Composition.html},
+ Formal proof development},
+ ISSN = {2150-914x},
+}
+
+
+@article{Feliachi-Wolff-Gaudel-AFP12,
+ author = {Abderrahmane Feliachi and Burkhart Wolff and Marie-Claude Gaudel},
+ title = {Isabelle/Circus},
+ journal = {Archive of Formal Proofs},
+ month = jun,
+ year = 2012,
+ note = {\url{http://afp.sourceforge.net/entries/Circus.shtml},
+ Formal proof development},
+ area = {logical_representations},
+ 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.},
+ issn = {2150-914x}
+}
+
+
+
+@inproceedings{feliachigw12,
+ author = {Abderrahmane Feliachi and
+ Marie-Claude Gaudel and
+ Burkhart Wolff},
+ title = {Isabelle/{C}ircus: A Process Specification and Verification Environment},
+ booktitle = {VSTTE},
+ year = {2012},
+ pages = {243-260},
+ series = {Lecture Notes in Computer Science},
+ volume = {LNCS 7152},
+ isbn = {978-3-642-27704-7},
+ ee = {http://dx.doi.org/10.1007/978-3-642-27705-4_20},
+ doi = {10.1007/978-3-642-27705-4_20},
+ 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). We develop a machine-checked, formal semantics based
+ on a "shallow embedding" of Circus in Isabelle/UTP (our semantic theory of UTP based on Isabelle/HOL).
+ We derive proof rules from this semantics and imple- ment tactic support that finally allows for
+ proofs of refinement for Circus processes (involving both data and behavioral aspects).
+ This proof environment supports a syntax for the semantic definitions which is close to textbook
+ presentations of Circus. },
+ pdf = {http://www.lri.fr/~wolff/papers/conf/VSTTE-IsabelleCircus11.pdf},
+ classification = {conference},
+ area = {logical_representations},
+ bibsource = {DBLP, http://dblp.uni-trier.de}
+}
+
+
+@article{feliachi-wolff:SymbTestgenCirta:2013,
+ author = {Abderrahmane Feliachi and Marie-Claude Gaudel and Burkhart Wolff},
+ title = {Symbolic Test-generation in {HOL}-{T}est{G}en/{C}irTA: A Case Study},
+ journal = {Int. J. Software Informatics},
+ volume = {9},
+ number = {2},
+ year = {2015},
+ pages = {177--203},
+ abstract = {HOL-TestGen/CirTA is a theorem-prover based test generation
+ environment for specifications written in Circus, a
+ process-algebraic specification language in the tradition
+ of CSP. HOL-TestGen/CirTA is based on a formal embedding of
+ its semantics in Isabelle/HOL, allowing to derive rules over
+ specification constructs in a logically safe way.
+ Beyond the derivation of algebraic laws and calculi for
+ process refinement, the originality of HOL-TestGen/ CirTA
+ consists in an entire derived theory for the generation of
+ symbolic test-traces, including optimized rules for test-generation
+ as well as rules for symbolic execution. The deduction process
+ is automated by Isabelle tactics, allowing to protract the
+ state-space explosion resulting from blind enumeration of data.
+
+ The implementation of test-generation procedures in CirTA is
+ completed by an integrated tool chain that transforms the
+ initial Circus specification of a system into a set of
+ equivalence classes (or ⤽symbolic tests⤝), which were compiled
+ to conventional JUnit test-drivers.
+
+ This paper describes the novel tool-chain based on prior
+ theoretical work on semantics and test-theory and attempts
+ an evaluation via a medium-sized case study performed on a
+ component of a real-world safety-critical medical monitoring
+ system written in Java. We provide experimental measurements
+ of the kill-capacity of implementation mutants.},
+ public = yes,
+ url = {https://www.lri.fr/~wolff/papers/journals/2015-cirta-case-study.pdf}
+}
+
+
+@article{HayesBrendan95,
+ Abstract = {In the physical sciences and engineering, units of measurement provide a valuable aid to both the exposition and comprehension of physical systems. In addition, they provide an error checking facility comparable to static type checking commonly found with programming languages. It is argued that units of measurement can provide similar benefits in the specification and design of software and computer systems.},
+ Author = {Hayes, Ian J. and Mahony, Brendan P.},
+ Da = {1995/05/01},
+ Date-Added = {2020-02-24 17:35:41 +0100},
+ Date-Modified = {2020-02-24 17:35:41 +0100},
+ Doi = {10.1007/BF01211077},
+ Id = {Hayes1995},
+ Isbn = {1433-299X},
+ Journal = {Formal Aspects of Computing},
+ Number = {3},
+ Pages = {329--347},
+ Title = {Using units of measurement in formal specifications},
+ Ty = {JOUR},
+ Url = {https://doi.org/10.1007/BF01211077},
+ Volume = {7},
+ Year = {1995},
+ Bdsk-Url-1 = {https://doi.org/10.1007/BF01211077}}
+
+
+@TechReport{ jcgm:2008:EMDG,
+ author = {Joint Committee for Guides in Metrology},
+ title = {JCGM 100: Evaluation of Measurement Data - Guide to
+ the Expression of Uncertainty in Measurement},
+ institution = {JCGM},
+ year = {2008},
+}
+
+@TechReport{bipm-jcgm:2012:VIM,
+ author = {{Bureau International des Poids et Mesures} and {Joint Committee for Guides in Metrology}},
+ title = {Basic and general concepts and associated terms (VIM) (3rd ed.).},
+ institution = {BIPM, JCGM},
+ year = {2012},
+ note = {Version 2008 with minor corrections}
+}
+
+@TechReport{SI-Brochure,
+ author = {{Bureau International des Poids et Mesures} and {Joint Committee for Guides in Metrology}},
+ title = {{The International System of Units (SI)}},
+ institution = {BIPM, JCGM},
+ year = {2019},
+ note = {9th edition}
+}
+
+@Article{Aragon2004-SI,
+ author = {Aragon, S.},
+ title = {The algebraic structure of physical quantities},
+ journal = {Journal of Mathematical Chemistry},
+ year = 2004,
+ volume = 31,
+ number = 1,
+ month = {May}}
+
diff --git a/thys/Physical_Quantities/document/root.tex b/thys/Physical_Quantities/document/root.tex
new file mode 100755
--- /dev/null
+++ b/thys/Physical_Quantities/document/root.tex
@@ -0,0 +1,243 @@
+\documentclass[11pt,a4paper]{book}
+\usepackage{isabelle,isabellesym}
+\usepackage{graphicx}
+\graphicspath {{figures/}}
+
+% further packages required for unusual symbols (see also
+% isabellesym.sty), use only when needed
+
+
+\usepackage{latexsym}
+\usepackage{amssymb}
+ %for \<leadsto>, \<box>, \<diamond>, \<sqsupset>, \<mho>, \<Join>,
+ %\<lhd>, \<lesssim>, \<greatersim>, \<lessapprox>, \<greaterapprox>,
+ %\<triangleq>, \<yen>, \<lozenge>
+
+%\usepackage[greek,english]{babel}
+ %option greek for \<euro>
+ %option english (default language) for \<guillemotleft>, \<guillemotright>
+
+%\usepackage[latin1]{inputenc}
+ %for \<onesuperior>, \<onequarter>, \<twosuperior>, \<onehalf>,
+ %\<threesuperior>, \<threequarters>, \<degree>
+
+%\usepackage[only,bigsqcap]{stmaryrd}
+ %for \<Sqinter>
+
+%\usepackage{eufrak}
+ %for \<AA> ... \<ZZ>, \<aa> ... \<zz> (also included in amssymb)
+
+%\usepackage{textcomp}
+ %for \<cent>, \<currency>
+
+% this should be the last package used
+\usepackage{pdfsetup}
+
+% urls in roman style, theory text in math-similar italics
+\urlstyle{rm}
+\isabellestyle{it}
+\newcommand{\HOL}[1]{\verb{HOL}}
+\newcommand{\eg}[1]{e.g.}
+\renewcommand{\isasymdegree}{XXX}
+\newcommand{\acs}[1]{\textsc{#1}}
+
+\begin{document}
+
+\title{A Sound Type System for Physical \\ Quantities, Units, and Measurements}
+\author{Simon Foster \and Burkhart Wolff}
+
+\maketitle
+
+\chapter*{Abstract}
+The present Isabelle theory builds a formal model for both the \emph{International System of Quantities} (ISQ) and the
+\emph{International System of Units} (SI), which are both fundamental for physics and
+engineering~\cite{bipm-jcgm:2012:VIM}. Both the ISQ and the SI are deeply integrated into Isabelle's type
+system. Quantities are parameterised by \emph{dimension types}, which correspond to base vectors, and thus only
+quantities of the same dimension can be equated. Since the underlying ``algebra of quantities''
+from~\cite{bipm-jcgm:2012:VIM} 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).
+
+\tableofcontents
+
+% sane default for proof documents
+\parindent 0pt\parskip 0.5ex
+
+
+\chapter{ISQ and SI: An Introduction}
+
+Modern Physics is based on the concept of quantifiable properties of physical phenomena such
+as mass, length, time, current, etc. These phenomena, called \emph{quantities}, are linked via an
+\emph{algebra of quantities} to derived concepts such as speed, force, and energy. The latter
+allows for a \emph{dimensional analysis} of physical equations, which had already been the
+backbone of Newtonian Physics. In parallel, physicians developed their own research field called
+``metrology'' defined as a scientific study of the \emph{measurement} of physical quantities.
+
+The relevant international standard for quantities and measurements is distributed by the \emph{Bureau International des
+ Poids et des Mesures} (BIPM), which also provides the \emph{Vocabulaire International de M\`etrologie}
+(VIM)~\cite{bipm-jcgm:2012:VIM}. The VIM actually defines two systems: the \emph{International System of Quantities}
+(ISQ) and the \emph{International System of Units} (SI, abbreviated from the French Syst\`eme international
+(d’unit\'es)). The latter is also documented in the \emph{SI Brochure}~\cite{SI-Brochure}, a standard that is updated
+periodically, most recently in 2019. Finally, the VIM defines concrete reference measurement procedures as well as a
+terminology for measurement errors.
+
+Conceived as a refinement of the ISQ, the SI comprises a coherent system of units of measurement built on seven base
+units, which are the metre, kilogram, second, ampere, kelvin, mole, candela, and a set of twenty prefixes to the unit
+names and unit symbols, such as milli- and kilo-, that may be used when specifying multiples and fractions of the
+units. The system also specifies names for 22 derived units, such as lumen and watt, for other common physical
+quantities. While there is still nowadays a wealth of different measuring systems such as the \emph{British Imperial
+ System} (BIS) and the \emph{United States Customary System} (USC), the SI is more or less the de-facto reference
+behind all these systems.
+
+The present Isabelle theory builds a formal model for both the ISQ and the SI, together with a deep integration into
+Isabelle's type system~\cite{nipkow.ea:isabelle:2002}. Quantities and units are represented in a way that they have a
+\emph{quantity type} as well as a \emph{unit type} based on its base vectors and their magnitudes. Since the algebra of
+quantities induces congruences on quantity and SI types, specific tactic support has been 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).
+
+% We would like to stress that it is not only our objective to provide a sound type-system for
+% ISQ and SI; rather, our semantic construction produces an integration of quantities and SI units
+% \emph{as types} inside the Hindley-Milner style type system of
+% Isabelle/HOL\cite{nipkow.ea:isabelle:2002}. The objective of our construction is to
+% reflect the types of the magnitudes as well as their dimensions in order to allow type-safe
+% calculations on SI units and their conversion to other measuring systems.
+
+% The International System of Units (SI, abbreviated from the French
+% Système International (d'unités)) is the modern form of the metric
+% system and is the most widely used system of measurement. It comprises
+% a coherent system of units of measurement built on seven base units,
+% which are the second, metre, kilogram, ampere, kelvin, mole, candela,
+% and a set of twenty prefixes to the unit names and unit symbols that
+% may be used when specifying multiples and fractions of the units.
+% The system also specifies names for 22 derived units, such as lumen and
+% watt, for other common physical quantities.
+%
+% (cited from \url{https://en.wikipedia.org/wiki/International_System_of_Units}).
+
+In the following we describe the overall theory architecture in more detail.
+Our ISQ model provides the following fundamental concepts:
+%
+\begin{enumerate}%
+\item \emph{dimensions} represented by a type \isa{(int, 'd::enum) dimvec} , i.e. a \isa{'d}-indexed
+ vector space of integers representing the exponents of the dimension vector.
+ \isa{'d} is constrained to be a dimension type later.
+
+
+\item \emph{quantities} represented by type \isa{('a, 'd::enum) Quantity}, which are constructed as
+ a vector space and a magnitude type \isa{'a}.
+
+\item{quantity calculus} consisting of \emph{quantity equations} allowing to infer that
+ $LT^{-1}T^{-1}M = MLT^{-2} = F$
+ (the left-hand-side equals mass times acceleration which is equal to force).
+
+\item a kind of equivalence relation $\cong_{Q}$ on quantities, permitting to relate
+ quantities of different dimension types.
+
+
+\item \emph{base quantities} for
+ \emph{length}, \emph{mass}, \emph{time}, \emph{electric current},
+ \emph{temperature}, \emph{amount of substance}, and \emph{luminous intensity},
+ serving as concrete instance of the vector instances, and for syntax
+ a set of the symbols \isa{L}, \isa{M}, \isa{T}, \isa{I},
+ \isa{{\isasymTheta}}, \isa{N}, \isa{J} corresponding to the above mentioned
+ base vectors.
+
+\item \emph{(Abstract) Measurement Systems} represented by type
+ \isa{('a, 'd::enum, 's::unit\_system) Measurement\_System}, which are a refinement
+ of quantities. The refinement is modelled by a polymorphic record extensions; as a
+ consequence, Measurement Systems inherit the algebraic properties of quantities.
+
+\item \emph{derived dimensions} such as \emph{volume} $\isa{L}^3$ or energy
+ $\isa{M}\isa{L}^2\isa{T}^{-2}$ corresponding to \emph{derived quantities}.
+
+\end{enumerate}
+
+Then, through a fresh type-constructor \isa{SI}, the abstract measurement systems are instantiated to the SI system ---
+the \emph{British Imperial System} (BIS) is constructed analogously. Technically, \isa{SI} is a tag-type that
+represents the fact that the magnitude of a quantity is actually a quantifiable entity in the sense of the SI system. In
+other words, this means that the magnitude $1$ in quantity \isa{1[L]} actually refers to one metre intended to be
+measured according to the SI standard. At this point, it becomes impossible, for example, to add to one foot, in the
+sense of the BIS, to one metre in the SI without creating a type-inconsistency.
+
+The theory of the SI is created by specialising the \isa{Measurement\_System}-type with the
+SI-tag-type and adding new infrastructure. The SI theory provides the following fundamental
+concepts:
+\begin{enumerate}%
+\item measuring units and types corresponding to the ISQ base quantities sich
+ as \emph{metre}, \emph{kilogram}, \emph{second}, \emph{ampere}, \emph{kelvin}, \emph{mole} and
+ \emph{candela} (together with procedures how to measure a metre, for example, which are
+ defined in accompanying standards);
+\item a standardised set of symbols for units such as $m$, $kg$, $s$, $A$, $K$, $mol$, and $cd$;
+\item a standardised set of symbols of SI prefixes for multiples of SI units, such as
+ $giga$ ($=10^9$), $kilo$ ($=10^3$), $milli$ ($=10^-3$), etc.; and a set of
+\item \emph{unit equations} and conversion equations such as $J = kg\,m^2/s^2$ or $1 km/h = 1/3.6\,m/s$.
+\end{enumerate}
+
+As a result, it is possible to express ``4500.0 kilogram times metre per second squared'' which has the type
+\isa{{\isasymreal}\ {\isacharbrackleft}M\ \isactrlsup {\isachardot}\ L\ \isactrlsup {\isachardot}\ T\isactrlsup
+ {\isacharminus}\isactrlsup {\isadigit{3}} \isactrlsup {\isachardot}\, SI{\isacharbrackright}}. This type means that
+the magnitude $4500$ of the dimension $M \cdot L \cdot T^{- 3}$ is a quantity intended to be measured in the SI-system,
+which means that it actually represents a force measured in Newtons.
+% For short, the above expression gets thy type $(\isasymreal)newton$.
+In the example, the \emph{magnitude} type of the measurement unit is the real numbers ($\isasymreal$). In general,
+however, magnitude types can be arbitrary types from the HOL library, so for example integer numbers (\isa{int}),
+integer numbers representable by 32 bits (\isa{int32}), IEEE-754 floating-point numbers (\isa{float}), or, a vector in
+the three-dimensional space \isa{\isasymreal}$^3$. Thus, our type-system allows to capture both conceptual entities in
+physics as well as implementation issues in concrete physical calculations on a computer.
+
+As mentioned before, it is a main objective of this work to support the quantity calculus of ISQ and the resulting
+equations on derived SI entities (cf. \cite{SI-Brochure}), both from a type checking as well as a proof-checking
+perspective. Our design objectives are not easily reconciled, however, and so some substantial theory engineering is
+required. On the one hand, we want a deep integration of dimensions and units into the Isabelle type system. On the
+other, we need to do normal-form calculations on types, so that, for example, the units $m$ and $ms^{-1}s$ can be
+equated.
+
+Isabelle's type system follows the Curry-style paradigm, which rules out the possibility of direct calculations on
+type-terms (in contrast to Coq-like systems). However, our semantic interpretation of ISQ and SI allows for the
+foundation of the heterogeneous equivalence relation $\cong_{Q}$ in semantic terms. This means that we can relate
+quantities with syntactically different dimension types, yet with same dimension semantics. This paves the way for
+derived rules that do computations of terms, which represent type computations indirectly. This principle is the basis
+for the tactic support, which allows for the dimensional type checking of key definitions of the SI system. Some
+examples are given below.
+
+\begin{isamarkuptext}%
+\isa{\isacommand{theorem}\ metre{\isacharunderscore}definition{\isacharcolon} \newline \ {\isachardoublequoteopen}
+{\isadigit{1}}\ {\isacharasterisk}\isactrlsub Q\ metre\ {\isasymcong}\isactrlsub Q \ {\isacharparenleft}\isactrlbold c\ \isactrlbold {\isacharslash}\ {\isacharparenleft}{\isadigit{2}}{\isadigit{9}}{\isadigit{9}}{\isadigit{7}}{\isadigit{9}}{\isadigit{2}}{\isadigit{4}}{\isadigit{5}}{\isadigit{8}}\ {\isacharasterisk}\isactrlsub Q\ {\isasymone}{\isacharparenright}{\isacharparenright}\isactrlbold {\isasymcdot}second{\isachardoublequoteclose}\ {\isachardoublequoteopen}
+\newline \isacommand{by}\ si{\isacharunderscore}calc\ \ \newline \newline
+\isacommand{theorem}\ kilogram{\isacharunderscore}definition{\isacharcolon} \newline \ {\isachardoublequoteopen}{\isadigit{1}}\ {\isacharasterisk}\isactrlsub Q\ kilogram\ {\isasymcong}\isactrlsub Q\ {\isacharparenleft}\isactrlbold h\ \isactrlbold {\isacharslash}\ {\isacharparenleft}{\isadigit{6}}{\isachardot}{\isadigit{6}}{\isadigit{2}}{\isadigit{6}}{\isadigit{0}}{\isadigit{7}}{\isadigit{0}}{\isadigit{1}}{\isadigit{5}}\ {\isasymcdot}\ {\isadigit{1}}{\isacharslash}{\isacharparenleft}{\isadigit{1}}{\isadigit{0}}{\isacharcircum}{\isadigit{3}}{\isadigit{4}}{\isacharparenright}\ {\isacharasterisk}\isactrlsub Q\ {\isasymone}{\isacharparenright}{\isacharparenright}\isactrlbold {\isasymcdot}metre\isactrlsup {\isacharminus}\isactrlsup {\isasymtwo}\isactrlbold {\isasymcdot}second{\isachardoublequoteclose}\ \newline \isacommand{by}\ si{\isacharunderscore}calc\ \ \ }%
+\end{isamarkuptext}\isamarkuptrue%
+
+These equations are both adapted from the SI Brochure, and give the concrete definitions for the metre and kilogram in
+terms of the physical constants \textbf{c} (speed of light) and \textbf{h} (Planck constant). They are both proved
+using the tactic \textit{si-calc}.
+
+This work has drawn inspiration from some previous formalisations of the ISQ and SI, notably Hayes and Mahoney's
+formalisation in Z~\cite{HayesBrendan95} and Aragon's algebraic structure for physical
+quantities~\cite{Aragon2004-SI}. To the best of our knowledge, our mechanisation represents the most comprehensive
+account of ISQ and SI in a theory prover.
+
+
+% \subsubsection{Previous Attempts.} The work of \cite{HayesBrendan95} represents to our knowledge a
+% first attempt to formalize SI units in Z, thus a similar language of HOL. While our typing
+% representation is more rigourous due to the use of type-classes, this works lacks any attempt
+% to support formal and automated deduction on Si unit equivalences.
+%
+% MORE TO COME.
+
+\chapter{Preliminaries}
+
+\input{session}
+
+% optional bibliography
+\bibliographystyle{abbrv}
+\bibliography{root}
+
+\end{document}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: t
+%%% End:
diff --git a/thys/ROOTS b/thys/ROOTS
--- a/thys/ROOTS
+++ b/thys/ROOTS
@@ -1,563 +1,569 @@
ADS_Functor
+AI_Planning_Languages_Semantics
AODV
AVL-Trees
AWN
Abortable_Linearizable_Modules
Abs_Int_ITP2012
Abstract-Hoare-Logics
Abstract-Rewriting
Abstract_Completeness
Abstract_Soundness
Adaptive_State_Counting
Affine_Arithmetic
Aggregation_Algebras
Akra_Bazzi
Algebraic_Numbers
Algebraic_VCs
Allen_Calculus
Amicable_Numbers
Amortized_Complexity
AnselmGod
Applicative_Lifting
Approximation_Algorithms
Architectural_Design_Patterns
Aristotles_Assertoric_Syllogistic
Arith_Prog_Rel_Primes
ArrowImpossibilityGS
Attack_Trees
Auto2_HOL
Auto2_Imperative_HOL
AutoFocus-Stream
Automated_Stateful_Protocol_Verification
Automatic_Refinement
AxiomaticCategoryTheory
BDD
BNF_CC
BNF_Operations
Banach_Steinhaus
Bell_Numbers_Spivey
Berlekamp_Zassenhaus
Bernoulli
Bertrands_Postulate
Bicategory
BinarySearchTree
Binding_Syntax_Theory
Binomial-Heaps
Binomial-Queues
BirdKMP
Bondy
Boolean_Expression_Checkers
Bounded_Deducibility_Security
Buchi_Complementation
Budan_Fourier
Buffons_Needle
Buildings
BytecodeLogicJmlTypes
C2KA_DistributedSystems
CAVA_Automata
CAVA_LTL_Modelchecker
CCS
CISC-Kernel
CRDT
CYK
CakeML
CakeML_Codegen
Call_Arity
Card_Equiv_Relations
Card_Multisets
Card_Number_Partitions
Card_Partitions
Cartan_FP
Case_Labeling
Catalan_Numbers
Category
Category2
Category3
Cauchy
Cayley_Hamilton
Certification_Monads
Chandy_Lamport
Chord_Segments
Circus
Clean
ClockSynchInst
Closest_Pair_Points
CofGroups
Coinductive
Coinductive_Languages
Collections
Comparison_Sort_Lower_Bound
Compiling-Exceptions-Correctly
Complete_Non_Orders
Completeness
Complex_Geometry
Complx
ComponentDependencies
ConcurrentGC
ConcurrentIMP
Concurrent_Ref_Alg
Concurrent_Revisions
Consensus_Refined
Constructive_Cryptography
Constructor_Funs
Containers
CoreC++
Core_DOM
+Core_SC_DOM
Count_Complex_Roots
CryptHOL
CryptoBasedCompositionalProperties
DFS_Framework
DPT-SAT-Solver
DataRefinementIBP
Datatype_Order_Generator
Decl_Sem_Fun_PL
Decreasing-Diagrams
Decreasing-Diagrams-II
Deep_Learning
Density_Compiler
Dependent_SIFUM_Refinement
Dependent_SIFUM_Type_Systems
Depth-First-Search
Derangements
Deriving
Descartes_Sign_Rule
Dict_Construction
Differential_Dynamic_Logic
Differential_Game_Logic
Dijkstra_Shortest_Path
Diophantine_Eqns_Lin_Hom
Dirichlet_L
Dirichlet_Series
DiscretePricing
Discrete_Summation
DiskPaxos
DynamicArchitectures
Dynamic_Tables
E_Transcendental
Echelon_Form
EdmondsKarp_Maxflow
Efficient-Mergesort
Elliptic_Curves_Group_Law
Encodability_Process_Calculi
Epistemic_Logic
Ergodic_Theory
Error_Function
Euler_MacLaurin
Euler_Partition
Example-Submission
+Extended_Finite_State_Machine_Inference
Extended_Finite_State_Machines
-Extended_Finite_State_Machine_Inference
FFT
FLP
FOL-Fitting
FOL_Harrison
FOL_Seq_Calc1
Factored_Transition_System_Bounding
Falling_Factorial_Sum
Farkas
FeatherweightJava
Featherweight_OCL
Fermat3_4
FileRefinement
FinFun
Finger-Trees
Finite_Automata_HF
First_Order_Terms
First_Welfare_Theorem
Fishburn_Impossibility
Fisher_Yates
Flow_Networks
Floyd_Warshall
Flyspeck-Tame
FocusStreamsCaseStudies
Forcing
Formal_SSA
Formula_Derivatives
Fourier
Free-Boolean-Algebra
Free-Groups
FunWithFunctions
FunWithTilings
Functional-Automata
Functional_Ordered_Resolution_Prover
Furstenberg_Topology
GPU_Kernel_PL
Gabow_SCC
Game_Based_Crypto
Gauss-Jordan-Elim-Fun
Gauss_Jordan
Gauss_Sums
Gaussian_Integers
GenClock
General-Triangle
Generalized_Counting_Sort
Generic_Deriving
Generic_Join
GewirthPGCProof
Girth_Chromatic
GoedelGod
Goedel_HFSet_Semantic
Goedel_HFSet_Semanticless
Goedel_Incompleteness
Goodstein_Lambda
GraphMarkingIBP
Graph_Saturation
Graph_Theory
Green
Groebner_Bases
Groebner_Macaulay
Gromov_Hyperbolicity
Group-Ring-Module
HOL-CSP
HOLCF-Prelude
HRB-Slicing
Heard_Of
Hello_World
HereditarilyFinite
Hermite
Hidden_Markov_Models
Higher_Order_Terms
Hoare_Time
HotelKeyCards
Huffman
Hybrid_Logic
Hybrid_Multi_Lane_Spatial_Logic
Hybrid_Systems_VCs
HyperCTL
IEEE_Floating_Point
IMAP-CRDT
IMO2019
IMP2
IMP2_Binary_Heap
IP_Addresses
Imperative_Insertion_Sort
Impossible_Geometry
Incompleteness
Incredible_Proof_Machine
Inductive_Confidentiality
Inductive_Inference
InfPathElimination
InformationFlowSlicing
InformationFlowSlicing_Inter
Integration
Interval_Arithmetic_Word32
Iptables_Semantics
Irrational_Series_Erdos_Straus
Irrationality_J_Hancl
Isabelle_C
Isabelle_Meta_Model
Jacobson_Basic_Algebra
Jinja
JinjaThreads
JiveDataStoreModel
Jordan_Hoelder
Jordan_Normal_Form
KAD
KAT_and_DRA
KBPs
KD_Tree
Key_Agreement_Strong_Adversaries
Kleene_Algebra
Knuth_Bendix_Order
Knot_Theory
Knuth_Bendix_Order
Knuth_Morris_Pratt
Koenigsberg_Friendship
Kruskal
Kuratowski_Closure_Complement
LLL_Basis_Reduction
LLL_Factorization
LOFT
LTL
LTL_Master_Theorem
LTL_Normal_Form
LTL_to_DRA
LTL_to_GBA
Lam-ml-Normalization
LambdaAuth
LambdaMu
Lambda_Free_EPO
Lambda_Free_KBOs
Lambda_Free_RPOs
Lambert_W
Landau_Symbols
Laplace_Transform
Latin_Square
LatticeProperties
Launchbury
Lazy-Lists-II
Lazy_Case
Lehmer
Lifting_Definition_Option
LightweightJava
LinearQuantifierElim
Linear_Inequalities
Linear_Programming
Linear_Recurrences
Liouville_Numbers
List-Index
List-Infinite
List_Interleaving
List_Inversions
List_Update
LocalLexing
Localization_Ring
Locally-Nameless-Sigma
Lowe_Ontological_Argument
Lower_Semicontinuous
Lp
Lucas_Theorem
MFMC_Countable
MFODL_Monitor_Optimized
MFOTL_Monitor
MSO_Regex_Equivalence
Markov_Models
Marriage
Mason_Stothers
Matrices_for_ODEs
Matrix
Matrix_Tensor
Matroids
Max-Card-Matching
Median_Of_Medians_Selection
Menger
Mersenne_Primes
MiniML
Minimal_SSA
Minkowskis_Theorem
Minsky_Machines
Modal_Logics_for_NTS
Modular_Assembly_Kit_Security
Monad_Memo_DP
Monad_Normalisation
MonoBoolTranAlgebra
MonoidalCategory
Monomorphic_Monad
MuchAdoAboutTwo
Multi_Party_Computation
Multirelations
Myhill-Nerode
Name_Carrying_Type_Inference
Nash_Williams
Nat-Interval-Logic
Native_Word
Nested_Multisets_Ordinals
Network_Security_Policy_Verification
Neumann_Morgenstern_Utility
No_FTL_observers
Nominal2
Noninterference_CSP
Noninterference_Concurrent_Composition
Noninterference_Generic_Unwinding
Noninterference_Inductive_Unwinding
Noninterference_Ipurge_Unwinding
Noninterference_Sequential_Composition
NormByEval
Nullstellensatz
Octonions
OpSets
Open_Induction
Optics
Optimal_BST
Orbit_Stabiliser
Order_Lattice_Props
Ordered_Resolution_Prover
Ordinal
Ordinal_Partitions
Ordinals_and_Cardinals
Ordinary_Differential_Equations
PAC_Checker
PCF
PLM
POPLmark-deBruijn
PSemigroupsConvolution
Pairing_Heap
Paraconsistency
Parity_Game
Partial_Function_MR
Partial_Order_Reduction
Password_Authentication_Protocol
Pell
Perfect-Number-Thm
Perron_Frobenius
+Physical_Quantities
Pi_Calculus
Pi_Transcendental
Planarity_Certificates
Poincare_Bendixson
Poincare_Disc
Polynomial_Factorization
Polynomial_Interpolation
Polynomials
Pop_Refinement
Posix-Lexing
Possibilistic_Noninterference
Power_Sum_Polynomials
Pratt_Certificate
Presburger-Automata
Prim_Dijkstra_Simple
Prime_Distribution_Elementary
Prime_Harmonic_Series
Prime_Number_Theorem
Priority_Queue_Braun
Priority_Search_Trees
Probabilistic_Noninterference
Probabilistic_Prime_Tests
Probabilistic_System_Zoo
Probabilistic_Timed_Automata
Probabilistic_While
Program-Conflict-Analysis
Projective_Geometry
Promela
Proof_Strategy_Language
PropResPI
Propositional_Proof_Systems
Prpu_Maxflow
PseudoHoops
Psi_Calculi
Ptolemys_Theorem
QHLProver
QR_Decomposition
Quantales
Quaternions
Quick_Sort_Cost
RIPEMD-160-SPARK
ROBDD
-Robinson_Arithmetic
RSAPSS
Ramsey-Infinite
Random_BSTs
Random_Graph_Subgraph_Threshold
Randomised_BSTs
Randomised_Social_Choice
Rank_Nullity_Theorem
Real_Impl
Recursion-Addition
Recursion-Theory-I
Refine_Imperative_HOL
Refine_Monadic
RefinementReactive
Regex_Equivalence
Regular-Sets
Regular_Algebras
Relation_Algebra
Relational-Incorrectness-Logic
Relational_Disjoint_Set_Forests
Relational_Paths
Rep_Fin_Groups
Residuated_Lattices
Resolution_FOL
Rewriting_Z
Ribbon_Proofs
Robbins-Conjecture
+Robinson_Arithmetic
Root_Balanced_Tree
Routing
Roy_Floyd_Warshall
SATSolverVerification
+SC_DOM_Components
SDS_Impossibility
SIFPL
SIFUM_Type_Systems
SPARCv8
Safe_Distance
Safe_OCL
Saturation_Framework
Saturation_Framework_Extensions
Secondary_Sylow
Security_Protocol_Refinement
Selection_Heap_Sort
SenSocialChoice
Separata
Separation_Algebra
Separation_Logic_Imperative_HOL
SequentInvertibility
+Shadow_SC_DOM
Shivers-CFA
ShortestPath
Show
Sigma_Commit_Crypto
Signature_Groebner
Simpl
Simple_Firewall
Simplex
Skew_Heap
Skip_Lists
Slicing
Sliding_Window_Algorithm
Smith_Normal_Form
Smooth_Manifolds
Sort_Encodings
Source_Coding_Theorem
Special_Function_Bounds
Splay_Tree
Sqrt_Babylonian
Stable_Matching
Statecharts
Stateful_Protocol_Composition_and_Typing
Stellar_Quorums
Stern_Brocot
Stewart_Apollonius
Stirling_Formula
Stochastic_Matrices
Stone_Algebras
Stone_Kleene_Relation_Algebras
Stone_Relation_Algebras
Store_Buffer_Reduction
Stream-Fusion
Stream_Fusion_Code
Strong_Security
Sturm_Sequences
Sturm_Tarski
Stuttering_Equivalence
Subresultants
Subset_Boolean_Algebras
SumSquares
SuperCalc
Surprise_Paradox
Symmetric_Polynomials
Syntax_Independent_Logic
Szpilrajn
TESL_Language
TLA
Tail_Recursive_Functions
Tarskis_Geometry
Taylor_Models
Timed_Automata
Topology
TortoiseHare
Transcendence_Series_Hancl_Rucki
Transformer_Semantics
Transition_Systems_and_Automata
Transitive-Closure
Transitive-Closure-II
Treaps
Tree-Automata
Tree_Decomposition
Triangle
Trie
Twelvefold_Way
Tycon
Types_Tableaus_and_Goedels_God
UPF
UPF_Firewall
UTP
Universal_Turing_Machine
UpDown_Scheme
Valuation
VectorSpace
VeriComp
Verified-Prover
+Verified_SAT_Based_AI_Planning
VerifyThis2018
VerifyThis2019
Vickrey_Clarke_Groves
VolpanoSmith
WHATandWHERE_Security
WOOT_Strong_Eventual_Consistency
WebAssembly
Weight_Balanced_Trees
Well_Quasi_Orders
Winding_Number_Eval
Word_Lib
WorkerWrapper
XML
ZFC_in_HOL
Zeta_3_Irrational
Zeta_Function
pGCL
diff --git a/thys/SC_DOM_Components/Core_DOM_DOM_Components.thy b/thys/SC_DOM_Components/Core_DOM_DOM_Components.thy
new file mode 100644
--- /dev/null
+++ b/thys/SC_DOM_Components/Core_DOM_DOM_Components.thy
@@ -0,0 +1,2351 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section \<open>Core SC DOM Components\<close>
+theory Core_DOM_DOM_Components
+ imports Core_SC_DOM.Core_DOM
+begin
+
+subsection \<open>Components\<close>
+
+locale l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_root_node_defs get_root_node get_root_node_locs +
+ l_to_tree_order_defs to_tree_order
+ for get_root_node :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and to_tree_order :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+begin
+
+definition a_get_dom_component :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ where
+ "a_get_dom_component ptr = do {
+ root \<leftarrow> get_root_node ptr;
+ to_tree_order root
+ }"
+
+definition a_is_strongly_dom_component_safe ::
+ "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ where
+ "a_is_strongly_dom_component_safe S\<^sub>a\<^sub>r\<^sub>g S\<^sub>r\<^sub>e\<^sub>s\<^sub>u\<^sub>l\<^sub>t h h' = (
+ let removed_pointers = fset (object_ptr_kinds h) - fset (object_ptr_kinds h') in
+ let added_pointers = fset (object_ptr_kinds h') - fset (object_ptr_kinds h) in
+ let arg_components =
+ (\<Union>ptr \<in> (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_dom_component ptr|\<^sub>r) \<inter>
+ fset (object_ptr_kinds h). set |h \<turnstile> a_get_dom_component ptr|\<^sub>r) in
+ let arg_components' =
+ (\<Union>ptr \<in> (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_dom_component ptr|\<^sub>r) \<inter>
+ fset (object_ptr_kinds h'). set |h' \<turnstile> a_get_dom_component ptr|\<^sub>r) in
+ removed_pointers \<subseteq> arg_components \<and>
+ added_pointers \<subseteq> arg_components' \<and>
+ S\<^sub>r\<^sub>e\<^sub>s\<^sub>u\<^sub>l\<^sub>t \<subseteq> arg_components' \<and>
+ (\<forall>outside_ptr \<in> fset (object_ptr_kinds h) \<inter> fset (object_ptr_kinds h') -
+ (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_dom_component ptr|\<^sub>r). preserved (get_M outside_ptr id) h h'))"
+
+definition a_is_weakly_dom_component_safe ::
+ "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ where
+ "a_is_weakly_dom_component_safe S\<^sub>a\<^sub>r\<^sub>g S\<^sub>r\<^sub>e\<^sub>s\<^sub>u\<^sub>l\<^sub>t h h' = (
+ let removed_pointers = fset (object_ptr_kinds h) - fset (object_ptr_kinds h') in
+ let added_pointers = fset (object_ptr_kinds h') - fset (object_ptr_kinds h) in
+ let arg_components =
+ (\<Union>ptr \<in> (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_dom_component ptr|\<^sub>r) \<inter>
+ fset (object_ptr_kinds h). set |h \<turnstile> a_get_dom_component ptr|\<^sub>r) in
+ let arg_components' =
+ (\<Union>ptr \<in> (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_dom_component ptr|\<^sub>r) \<inter>
+ fset (object_ptr_kinds h'). set |h' \<turnstile> a_get_dom_component ptr|\<^sub>r) in
+ removed_pointers \<subseteq> arg_components \<and>
+ S\<^sub>r\<^sub>e\<^sub>s\<^sub>u\<^sub>l\<^sub>t \<subseteq> arg_components' \<union> added_pointers \<and>
+ (\<forall>outside_ptr \<in> fset (object_ptr_kinds h) \<inter> fset (object_ptr_kinds h') -
+ (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_dom_component ptr|\<^sub>r). preserved (get_M outside_ptr id) h h'))"
+
+lemma "a_is_strongly_dom_component_safe S\<^sub>a\<^sub>r\<^sub>g S\<^sub>r\<^sub>e\<^sub>s\<^sub>u\<^sub>l\<^sub>t h h' \<Longrightarrow> a_is_weakly_dom_component_safe S\<^sub>a\<^sub>r\<^sub>g S\<^sub>r\<^sub>e\<^sub>s\<^sub>u\<^sub>l\<^sub>t h h'"
+ by(auto simp add: a_is_strongly_dom_component_safe_def a_is_weakly_dom_component_safe_def Let_def)
+
+definition is_document_component :: "(_) object_ptr list \<Rightarrow> bool"
+ where
+ "is_document_component c = is_document_ptr_kind (hd c)"
+
+definition is_disconnected_component :: "(_) object_ptr list \<Rightarrow> bool"
+ where
+ "is_disconnected_component c = is_node_ptr_kind (hd c)"
+end
+
+global_interpretation l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_root_node get_root_node_locs to_tree_order
+ defines get_dom_component = a_get_dom_component
+ and is_strongly_dom_component_safe = a_is_strongly_dom_component_safe
+ and is_weakly_dom_component_safe = a_is_weakly_dom_component_safe
+ .
+
+
+locale l_get_dom_component_defs =
+ fixes get_dom_component :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ fixes is_strongly_dom_component_safe ::
+ "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ fixes is_weakly_dom_component_safe ::
+ "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+
+locale l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_to_tree_order_wf +
+ l_get_dom_component_defs +
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_get_ancestors +
+ l_get_ancestors_wf +
+ l_get_root_node +
+ l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent +
+ l_get_parent_wf +
+ l_get_element_by +
+ l_to_tree_order_wf_get_root_node_wf +
+ (* l_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M _ _ _ get_child_nodes +
+ l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M _ _ get_child_nodes+
+ l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M _ _ "l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.a_to_tree_order get_child_nodes"
+ for get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog" *)
+ assumes get_dom_component_impl: "get_dom_component = a_get_dom_component"
+ assumes is_strongly_dom_component_safe_impl:
+ "is_strongly_dom_component_safe = a_is_strongly_dom_component_safe"
+ assumes is_weakly_dom_component_safe_impl:
+ "is_weakly_dom_component_safe = a_is_weakly_dom_component_safe"
+begin
+lemmas get_dom_component_def = a_get_dom_component_def[folded get_dom_component_impl]
+lemmas is_strongly_dom_component_safe_def =
+ a_is_strongly_dom_component_safe_def[folded is_strongly_dom_component_safe_impl]
+lemmas is_weakly_dom_component_safe_def =
+ a_is_weakly_dom_component_safe_def[folded is_weakly_dom_component_safe_impl]
+
+lemma get_dom_component_ptr_in_heap:
+ assumes "h \<turnstile> ok (get_dom_component ptr)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms get_root_node_ptr_in_heap
+ by(auto simp add: get_dom_component_def)
+
+lemma get_dom_component_ok:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ shows "h \<turnstile> ok (get_dom_component ptr)"
+ using assms
+ apply(auto simp add: get_dom_component_def a_get_root_node_def intro!: bind_is_OK_pure_I)[1]
+ using get_root_node_ok to_tree_order_ok get_root_node_ptr_in_heap
+ apply blast
+ by (simp add: local.get_root_node_root_in_heap local.to_tree_order_ok)
+
+lemma get_dom_component_ptr:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ shows "ptr \<in> set c"
+proof(insert assms(1) assms(4), induct ptr rule: heap_wellformed_induct_rev )
+ case (step child)
+ then show ?case
+ proof (cases "is_node_ptr_kind child")
+ case True
+ obtain node_ptr where
+ node_ptr: "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = child"
+ using \<open>is_node_ptr_kind child\<close> node_ptr_casts_commute3 by blast
+ have "child |\<in>| object_ptr_kinds h"
+ using \<open>h \<turnstile> get_dom_component child \<rightarrow>\<^sub>r c\<close> get_dom_component_ptr_in_heap by fast
+ with node_ptr have "node_ptr |\<in>| node_ptr_kinds h"
+ by auto
+ then obtain parent_opt where
+ parent: "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r parent_opt"
+ using get_parent_ok \<open>type_wf h\<close> \<open>known_ptrs h\<close>
+ by fast
+ then show ?thesis
+ proof (induct parent_opt)
+ case None
+ then have "h \<turnstile> get_root_node (cast node_ptr) \<rightarrow>\<^sub>r cast node_ptr"
+ by (simp add: local.get_root_node_no_parent)
+ then show ?case
+ using \<open>type_wf h\<close> \<open>known_ptrs h\<close> node_ptr step(2)
+ apply(auto simp add: get_dom_component_def a_get_root_node_def elim!: bind_returns_result_E2)[1]
+ using to_tree_order_ptr_in_result returns_result_eq by fastforce
+ next
+ case (Some parent_ptr)
+ then have "h \<turnstile> get_dom_component parent_ptr \<rightarrow>\<^sub>r c"
+ using step(2) node_ptr \<open>type_wf h\<close> \<open>known_ptrs h\<close> \<open>heap_is_wellformed h\<close>
+ get_root_node_parent_same
+ by(auto simp add: get_dom_component_def elim!: bind_returns_result_E2
+ intro!: bind_pure_returns_result_I)
+ then have "parent_ptr \<in> set c"
+ using step node_ptr Some by blast
+ then show ?case
+ using \<open>type_wf h\<close> \<open>known_ptrs h\<close> \<open>heap_is_wellformed h\<close> step(2) node_ptr Some
+ apply(auto simp add: get_dom_component_def elim!: bind_returns_result_E2)[1]
+ using to_tree_order_parent by blast
+ qed
+ next
+ case False
+ then show ?thesis
+ using \<open>type_wf h\<close> \<open>known_ptrs h\<close> step(2)
+ apply(auto simp add: get_dom_component_def elim!: bind_returns_result_E2)[1]
+ by (metis is_OK_returns_result_I local.get_root_node_not_node_same
+ local.get_root_node_ptr_in_heap local.to_tree_order_ptr_in_result returns_result_eq)
+ qed
+qed
+
+lemma get_dom_component_parent_inside:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "cast node_ptr \<in> set c"
+ assumes "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r Some parent"
+ shows "parent \<in> set c"
+proof -
+ have "parent |\<in>| object_ptr_kinds h"
+ using assms(6) get_parent_parent_in_heap by blast
+
+ obtain root_ptr where root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr" and c: "h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r c"
+ using assms(4)
+ by (metis (no_types, hide_lams) bind_returns_result_E2 get_dom_component_def get_root_node_pure)
+ then have "h \<turnstile> get_root_node (cast node_ptr) \<rightarrow>\<^sub>r root_ptr"
+ using assms(1) assms(2) assms(3) assms(5) to_tree_order_same_root by blast
+ then have "h \<turnstile> get_root_node parent \<rightarrow>\<^sub>r root_ptr"
+ using assms(6) get_root_node_parent_same by blast
+ then have "h \<turnstile> get_dom_component parent \<rightarrow>\<^sub>r c"
+ using c get_dom_component_def by auto
+ then show ?thesis
+ using assms(1) assms(2) assms(3) get_dom_component_ptr by blast
+qed
+
+lemma get_dom_component_subset:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "ptr' \<in> set c"
+ shows "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c"
+proof(insert assms(1) assms(5), induct ptr' rule: heap_wellformed_induct_rev )
+ case (step child)
+ then show ?case
+ proof (cases "is_node_ptr_kind child")
+ case True
+ obtain node_ptr where
+ node_ptr: "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = child"
+ using \<open>is_node_ptr_kind child\<close> node_ptr_casts_commute3 by blast
+ have "child |\<in>| object_ptr_kinds h"
+ using to_tree_order_ptrs_in_heap assms(1) assms(2) assms(3) assms(4) step(2)
+ unfolding get_dom_component_def
+ by (meson bind_returns_result_E2 get_root_node_pure)
+ with node_ptr have "node_ptr |\<in>| node_ptr_kinds h"
+ by auto
+ then obtain parent_opt where
+ parent: "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r parent_opt"
+ using get_parent_ok \<open>type_wf h\<close> \<open>known_ptrs h\<close>
+ by fast
+ then show ?thesis
+ proof (induct parent_opt)
+ case None
+ then have "h \<turnstile> get_root_node child \<rightarrow>\<^sub>r child"
+ using assms(1) get_root_node_no_parent node_ptr by blast
+ then show ?case
+ using \<open>type_wf h\<close> \<open>known_ptrs h\<close> node_ptr step(2) assms(4) assms(1)
+ by (metis (no_types) bind_pure_returns_result_I2 bind_returns_result_E2
+ get_dom_component_def get_root_node_pure is_OK_returns_result_I returns_result_eq
+ to_tree_order_same_root)
+ next
+ case (Some parent_ptr)
+ then have "h \<turnstile> get_dom_component parent_ptr \<rightarrow>\<^sub>r c"
+ using step get_dom_component_parent_inside assms node_ptr by blast
+ then show ?case
+ using Some node_ptr
+ apply(auto simp add: get_dom_component_def elim!: bind_returns_result_E2
+ del: bind_pure_returns_result_I intro!: bind_pure_returns_result_I)[1]
+ using get_root_node_parent_same by blast
+ qed
+ next
+ case False
+ then have "child |\<in>| object_ptr_kinds h"
+ using assms(1) assms(4) step(2)
+ by (metis (no_types, lifting) assms(2) assms(3) bind_returns_result_E2 get_root_node_pure
+ get_dom_component_def to_tree_order_ptrs_in_heap)
+ then have "h \<turnstile> get_root_node child \<rightarrow>\<^sub>r child"
+ using assms(1) False get_root_node_not_node_same by blast
+ then show ?thesis
+ using assms(1) assms(2) assms(3) assms(4) step.prems
+ by (metis (no_types) False \<open>child |\<in>| object_ptr_kinds h\<close> bind_pure_returns_result_I2
+ bind_returns_result_E2 get_dom_component_def get_root_node_ok get_root_node_pure returns_result_eq
+ to_tree_order_node_ptrs)
+ qed
+qed
+
+lemma get_dom_component_to_tree_order_subset:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r nodes"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ shows "set nodes \<subseteq> set c"
+ using assms
+ apply(auto simp add: get_dom_component_def elim!: bind_returns_result_E2)[1]
+ by (meson to_tree_order_subset assms(5) contra_subsetD get_dom_component_ptr)
+
+lemma get_dom_component_to_tree_order:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> to_tree_order ptr' \<rightarrow>\<^sub>r to"
+ assumes "ptr \<in> set to"
+ shows "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c"
+ by (metis (no_types, hide_lams) assms(1) assms(2) assms(3) assms(4) assms(5) assms(6)
+ get_dom_component_ok get_dom_component_subset get_dom_component_to_tree_order_subset
+ is_OK_returns_result_E local.to_tree_order_ptr_in_result local.to_tree_order_ptrs_in_heap
+ select_result_I2 subsetCE)
+
+lemma get_dom_component_root_node_same:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ assumes "x \<in> set c"
+ shows "h \<turnstile> get_root_node x \<rightarrow>\<^sub>r root_ptr"
+proof(insert assms(1) assms(6), induct x rule: heap_wellformed_induct_rev )
+ case (step child)
+ then show ?case
+ proof (cases "is_node_ptr_kind child")
+ case True
+ obtain node_ptr where
+ node_ptr: "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = child"
+ using \<open>is_node_ptr_kind child\<close> node_ptr_casts_commute3 by blast
+ have "child |\<in>| object_ptr_kinds h"
+ using to_tree_order_ptrs_in_heap assms(1) assms(2) assms(3) assms(4) step(2)
+ unfolding get_dom_component_def
+ by (meson bind_returns_result_E2 get_root_node_pure)
+ with node_ptr have "node_ptr |\<in>| node_ptr_kinds h"
+ by auto
+ then obtain parent_opt where
+ parent: "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r parent_opt"
+ using get_parent_ok \<open>type_wf h\<close> \<open>known_ptrs h\<close>
+ by fast
+ then show ?thesis
+ proof (induct parent_opt)
+ case None
+ then have "h \<turnstile> get_root_node child \<rightarrow>\<^sub>r child"
+ using assms(1) get_root_node_no_parent node_ptr by blast
+ then show ?case
+ using \<open>type_wf h\<close> \<open>known_ptrs h\<close> node_ptr step(2) assms(4) assms(1) assms(5)
+ by (metis (no_types) \<open>child |\<in>| object_ptr_kinds h\<close> bind_pure_returns_result_I
+ get_dom_component_def get_dom_component_ptr get_dom_component_subset get_root_node_pure
+ is_OK_returns_result_E returns_result_eq to_tree_order_ok to_tree_order_same_root)
+ next
+ case (Some parent_ptr)
+ then have "h \<turnstile> get_dom_component parent_ptr \<rightarrow>\<^sub>r c"
+ using step get_dom_component_parent_inside assms node_ptr
+ by (meson get_dom_component_subset)
+ then show ?case
+ using Some node_ptr
+ apply(auto simp add: get_dom_component_def elim!: bind_returns_result_E2)[1]
+ using get_root_node_parent_same
+ using \<open>h \<turnstile> get_dom_component parent_ptr \<rightarrow>\<^sub>r c\<close> assms(1) assms(2) assms(3)
+ get_dom_component_ptr step.hyps by blast
+ qed
+ next
+ case False
+ then have "child |\<in>| object_ptr_kinds h"
+ using assms(1) assms(4) step(2)
+ by (metis (no_types, lifting) assms(2) assms(3) bind_returns_result_E2 get_root_node_pure
+ get_dom_component_def to_tree_order_ptrs_in_heap)
+ then have "h \<turnstile> get_root_node child \<rightarrow>\<^sub>r child"
+ using assms(1) False get_root_node_not_node_same by auto
+ then show ?thesis
+ using assms(1) assms(2) assms(3) assms(4) step.prems assms(5)
+ by (metis (no_types, hide_lams) bind_returns_result_E2 get_dom_component_def
+ get_root_node_pure returns_result_eq to_tree_order_same_root)
+ qed
+qed
+
+
+lemma get_dom_component_no_overlap:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c'"
+ shows "set c \<inter> set c' = {} \<or> c = c'"
+proof (rule ccontr, auto)
+ fix x
+ assume 1: "c \<noteq> c'" and 2: "x \<in> set c" and 3: "x \<in> set c'"
+ obtain root_ptr where root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ using assms(4) unfolding get_dom_component_def
+ by (meson bind_is_OK_E is_OK_returns_result_I)
+ moreover obtain root_ptr' where root_ptr': "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr'"
+ using assms(5) unfolding get_dom_component_def
+ by (meson bind_is_OK_E is_OK_returns_result_I)
+ ultimately have "root_ptr \<noteq> root_ptr'"
+ using 1 assms
+ unfolding get_dom_component_def
+ by (meson bind_returns_result_E3 get_root_node_pure returns_result_eq)
+
+ moreover have "h \<turnstile> get_root_node x \<rightarrow>\<^sub>r root_ptr"
+ using 2 root_ptr get_dom_component_root_node_same assms by blast
+ moreover have "h \<turnstile> get_root_node x \<rightarrow>\<^sub>r root_ptr'"
+ using 3 root_ptr' get_dom_component_root_node_same assms by blast
+ ultimately show False
+ using select_result_I2 by force
+qed
+
+lemma get_dom_component_separates_tree_order:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ assumes "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c'"
+ assumes "ptr' \<notin> set c"
+ shows "set to \<inter> set c' = {}"
+proof -
+ have "c \<noteq> c'"
+ using assms get_dom_component_ptr by blast
+ then have "set c \<inter> set c' = {}"
+ using assms get_dom_component_no_overlap by blast
+ moreover have "set to \<subseteq> set c"
+ using assms get_dom_component_to_tree_order_subset by blast
+ ultimately show ?thesis
+ by blast
+qed
+
+lemma get_dom_component_separates_tree_order_general:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> to_tree_order ptr'' \<rightarrow>\<^sub>r to''"
+ assumes "ptr'' \<in> set c"
+ assumes "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c'"
+ assumes "ptr' \<notin> set c"
+ shows "set to'' \<inter> set c' = {}"
+proof -
+ obtain root_ptr where root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ using assms(4)
+ by (metis bind_is_OK_E get_dom_component_def is_OK_returns_result_I)
+ then have c: "h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r c"
+ using assms(4) unfolding get_dom_component_def
+ by (simp add: bind_returns_result_E3)
+ with root_ptr show ?thesis
+ using assms get_dom_component_separates_tree_order get_dom_component_subset
+ by meson
+qed
+end
+
+interpretation i_get_dom_component?: l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name
+ by(auto simp add: l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ get_dom_component_def is_strongly_dom_component_safe_def is_weakly_dom_component_safe_def instances)
+declare l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_child\_nodes\<close>
+
+locale l_get_dom_component_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_child_nodes_is_strongly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ assumes "child \<in> set children"
+ shows "cast child \<in> set c \<longleftrightarrow> ptr' \<in> set c"
+proof
+ assume 1: "cast child \<in> set c"
+ obtain root_ptr where
+ root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ by (metis assms(4) bind_is_OK_E get_dom_component_def is_OK_returns_result_I)
+ have "h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root_ptr"
+ using "1" assms(1) assms(2) assms(3) assms(4) get_dom_component_root_node_same root_ptr
+ by blast
+ then have "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr"
+ using assms(1) assms(2) assms(3) assms(5) assms(6) local.child_parent_dual
+ local.get_root_node_parent_same by blast
+ then have "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c"
+ using "1" assms(1) assms(2) assms(3) assms(4) assms(5) assms(6) local.child_parent_dual
+ local.get_dom_component_parent_inside local.get_dom_component_subset by blast
+ then show "ptr' \<in> set c"
+ using assms(1) assms(2) assms(3) get_dom_component_ptr by blast
+next
+ assume 1: "ptr' \<in> set c"
+ obtain root_ptr where
+ root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ by (metis assms(4) bind_is_OK_E get_dom_component_def is_OK_returns_result_I)
+ have "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr"
+ using "1" assms(1) assms(2) assms(3) assms(4) get_dom_component_root_node_same root_ptr
+ by blast
+ then have "h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root_ptr"
+ using assms(1) assms(2) assms(3) assms(5) assms(6) local.child_parent_dual
+ local.get_root_node_parent_same by blast
+ then have "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c"
+ using "1" assms(1) assms(2) assms(3) assms(4) assms(5) assms(6) local.child_parent_dual
+ local.get_dom_component_parent_inside local.get_dom_component_subset by blast
+ then show "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child \<in> set c"
+ by (smt \<open>h \<turnstile> get_root_node (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r root_ptr\<close> assms(1) assms(2) assms(3)
+ assms(5) assms(6) disjoint_iff_not_equal is_OK_returns_result_E is_OK_returns_result_I
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_dom_component_no_overlap local.child_parent_dual local.get_dom_component_ok
+ local.get_dom_component_parent_inside local.get_dom_component_ptr local.get_root_node_ptr_in_heap
+ local.l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms)
+qed
+
+
+lemma get_child_nodes_get_dom_component:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ shows "cast ` set children \<subseteq> set c"
+ using assms get_child_nodes_is_strongly_dom_component_safe
+ using local.get_dom_component_ptr by auto
+
+
+lemma
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_dom_component_safe {ptr} (cast ` set children) h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by (meson local.get_child_nodes_pure pure_returns_heap_eq)
+ then show ?thesis
+ using assms
+ apply(auto simp add: is_strongly_dom_component_safe_def Let_def preserved_def)[1]
+ by (smt IntI finite_set_in get_child_nodes_is_strongly_dom_component_safe is_OK_returns_result_E
+ is_OK_returns_result_I local.get_child_nodes_ptr_in_heap local.get_dom_component_impl
+ local.get_dom_component_ok local.get_dom_component_ptr select_result_I2)
+qed
+end
+
+interpretation i_get_dom_component_get_child_nodes?: l_get_dom_component_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name first_in_tree_order get_attribute get_attribute_locs
+ by(auto simp add: l_get_dom_component_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_parent\<close>
+
+locale l_get_dom_component_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_parent_is_strongly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> get_parent ptr' \<rightarrow>\<^sub>r Some parent"
+ shows "parent \<in> set c \<longleftrightarrow> cast ptr' \<in> set c"
+ by (meson assms(1) assms(2) assms(3) assms(4) assms(5) is_OK_returns_result_E
+ l_to_tree_order_wf.to_tree_order_parent local.get_dom_component_parent_inside
+ local.get_dom_component_subset local.get_dom_component_to_tree_order_subset
+ local.get_parent_parent_in_heap local.l_to_tree_order_wf_axioms local.to_tree_order_ok
+ local.to_tree_order_ptr_in_result subsetCE)
+
+
+lemma get_parent_is_strongly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r Some parent"
+ assumes "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_dom_component_safe {cast node_ptr} {parent} h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by (meson local.get_parent_pure pure_returns_heap_eq)
+ then show ?thesis
+ using assms
+ apply(auto simp add: is_strongly_dom_component_safe_def Let_def preserved_def)[1]
+ by (metis IntI finite_set_in local.get_dom_component_impl local.get_dom_component_ok
+ local.get_dom_component_parent_inside local.get_dom_component_ptr local.get_parent_parent_in_heap
+ local.known_ptrs_known_ptr local.parent_child_rel_child_in_heap local.parent_child_rel_parent
+ returns_result_select_result)
+qed
+end
+
+interpretation i_get_dom_component_get_parent?: l_get_dom_component_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name first_in_tree_order get_attribute get_attribute_locs
+ by(auto simp add: l_get_dom_component_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_root\_node\<close>
+
+locale l_get_dom_component_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_root_node_is_strongly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root"
+ shows "root \<in> set c \<longleftrightarrow> ptr' \<in> set c"
+proof
+ assume 1: "root \<in> set c"
+ obtain root_ptr where
+ root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ by (metis assms(4) bind_is_OK_E get_dom_component_def is_OK_returns_result_I)
+ have "h \<turnstile> get_root_node root \<rightarrow>\<^sub>r root_ptr"
+ using "1" assms(1) assms(2) assms(3) assms(4) get_dom_component_root_node_same root_ptr
+ by blast
+ moreover have "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr"
+ by (metis (no_types, lifting) calculation assms(1) assms(2) assms(3) assms(5)
+ is_OK_returns_result_E local.get_root_node_root_in_heap local.to_tree_order_ok
+ local.to_tree_order_ptr_in_result local.to_tree_order_same_root select_result_I2)
+ ultimately have "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c"
+ apply(auto simp add: get_dom_component_def)[1]
+ by (smt "1" assms(1) assms(2) assms(3) assms(4) bind_pure_returns_result_I bind_returns_result_E3
+ local.get_dom_component_def local.get_dom_component_subset local.get_root_node_pure)
+ then show "ptr' \<in> set c"
+ using assms(1) assms(2) assms(3) get_dom_component_ptr by blast
+next
+ assume 1: "ptr' \<in> set c"
+ obtain root_ptr where
+ root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ by (metis assms(4) bind_is_OK_E get_dom_component_def is_OK_returns_result_I)
+ have "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr"
+ using "1" assms(1) assms(2) assms(3) assms(4) get_dom_component_root_node_same root_ptr
+ by blast
+ then have "h \<turnstile> get_root_node root \<rightarrow>\<^sub>r root_ptr"
+ by (metis assms(1) assms(2) assms(3) assms(5) is_OK_returns_result_E
+ local.get_root_node_root_in_heap local.to_tree_order_ok local.to_tree_order_ptr_in_result
+ local.to_tree_order_same_root returns_result_eq)
+ then have "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c"
+ using "1" assms(1) assms(2) assms(3) assms(4) local.get_dom_component_subset by blast
+ then show "root \<in> set c"
+ using assms(5) bind_returns_result_E3 local.get_dom_component_def local.to_tree_order_ptr_in_result
+ by fastforce
+qed
+
+lemma get_root_node_is_strongly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_dom_component_safe {ptr} {root} h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by (meson local.get_root_node_pure pure_returns_heap_eq)
+ then show ?thesis
+ using assms
+ apply(auto simp add: is_strongly_dom_component_safe_def Let_def preserved_def)[1]
+ by (metis (no_types, lifting) IntI finite_set_in get_root_node_is_strongly_dom_component_safe_step
+ is_OK_returns_result_I local.get_dom_component_impl local.get_dom_component_ok
+ local.get_dom_component_ptr local.get_root_node_ptr_in_heap returns_result_select_result)
+qed
+end
+
+interpretation i_get_dom_component_get_root_node?: l_get_dom_component_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name first_in_tree_order get_attribute get_attribute_locs
+ by(auto simp add: l_get_dom_component_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_element\_by\_id\<close>
+
+locale l_get_dom_component_get_element_by_id\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_element_by_id_is_strongly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> get_element_by_id ptr' idd \<rightarrow>\<^sub>r Some result"
+ shows "cast result \<in> set c \<longleftrightarrow> ptr' \<in> set c"
+proof
+ assume 1: "cast result \<in> set c"
+ obtain root_ptr where
+ root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ by (metis assms(4) bind_is_OK_E get_dom_component_def is_OK_returns_result_I)
+ then have "h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r c"
+ using \<open>h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c\<close>
+ by (simp add: get_dom_component_def bind_returns_result_E3)
+
+ obtain to' where to': "h \<turnstile> to_tree_order ptr' \<rightarrow>\<^sub>r to'"
+ using \<open>h \<turnstile> get_element_by_id ptr' idd \<rightarrow>\<^sub>r Some result\<close>
+ apply(simp add: get_element_by_id_def first_in_tree_order_def)
+ by (meson bind_is_OK_E is_OK_returns_result_I)
+ then have "cast result \<in> set to'"
+ using \<open>h \<turnstile> get_element_by_id ptr' idd \<rightarrow>\<^sub>r Some result\<close> get_element_by_id_result_in_tree_order
+ by blast
+
+ have "h \<turnstile> get_root_node (cast result) \<rightarrow>\<^sub>r root_ptr"
+ using "1" assms(1) assms(2) assms(3) assms(4) get_dom_component_root_node_same root_ptr
+ by blast
+ then have "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr"
+ using \<open>cast result \<in> set to'\<close> \<open>h \<turnstile> to_tree_order ptr' \<rightarrow>\<^sub>r to'\<close>
+ using "1" assms(1) assms(2) assms(3) assms(4) get_dom_component_ptr get_dom_component_root_node_same
+ get_dom_component_subset get_dom_component_to_tree_order
+ by blast
+ then have "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c"
+ using \<open>h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r c\<close>
+ using get_dom_component_def by auto
+ then show "ptr' \<in> set c"
+ using assms(1) assms(2) assms(3) get_dom_component_ptr by blast
+next
+ assume "ptr' \<in> set c"
+ moreover obtain to' where to': "h \<turnstile> to_tree_order ptr' \<rightarrow>\<^sub>r to'"
+ by (meson assms(1) assms(2) assms(3) assms(4) calculation get_dom_component_ptr_in_heap
+ get_dom_component_subset is_OK_returns_result_E is_OK_returns_result_I to_tree_order_ok)
+ ultimately have "set to' \<subseteq> set c"
+ using assms(1) assms(2) assms(3) assms(4) get_dom_component_subset
+ get_dom_component_to_tree_order_subset
+ by blast
+ moreover have "cast result \<in> set to'"
+ using assms(5) get_element_by_id_result_in_tree_order to' by blast
+ ultimately show "cast result \<in> set c"
+ by blast
+qed
+
+
+lemma get_element_by_id_is_strongly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_element_by_id ptr idd \<rightarrow>\<^sub>r Some result"
+ assumes "h \<turnstile> get_element_by_id ptr idd \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_dom_component_safe {ptr} {cast result} h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by(auto simp add: preserved_def get_element_by_id_def first_in_tree_order_def
+ elim!: bind_returns_heap_E2 intro!: map_filter_M_pure bind_pure_I
+ split: option.splits list.splits)
+ have "ptr |\<in>| object_ptr_kinds h"
+ using assms(4)
+ apply(auto simp add: get_element_by_id_def)[1]
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) bind_is_OK_E is_OK_returns_result_I
+ local.first_in_tree_order_def local.to_tree_order_ptr_in_result local.to_tree_order_ptrs_in_heap)
+ obtain to where to: "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ by (meson \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) is_OK_returns_result_E
+ local.to_tree_order_ok)
+ then have "cast result \<in> set to"
+ using assms(4) local.get_element_by_id_result_in_tree_order by auto
+ obtain c where c: "h \<turnstile> a_get_dom_component ptr \<rightarrow>\<^sub>r c"
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) local.get_dom_component_impl
+ local.get_dom_component_ok by blast
+
+ then show ?thesis
+ using assms \<open>h = h'\<close>
+ apply(auto simp add: is_strongly_dom_component_safe_def Let_def preserved_def get_element_by_id_def
+ first_in_tree_order_def elim!: bind_returns_result_E2 intro!: map_filter_M_pure bind_pure_I
+ split: option.splits list.splits)[1]
+ by (metis (no_types, lifting) Int_iff \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(4) finite_set_in
+ get_element_by_id_is_strongly_dom_component_safe_step local.get_dom_component_impl
+ local.get_dom_component_ptr select_result_I2)
+qed
+end
+
+interpretation i_get_dom_component_get_element_by_id?: l_get_dom_component_get_element_by_id\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name first_in_tree_order get_attribute get_attribute_locs
+ by(auto simp add: l_get_dom_component_get_element_by_id\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_get_element_by_id\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+subsubsection \<open>get\_elements\_by\_class\_name\<close>
+
+locale l_get_dom_component_get_elements_by_class_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_elements_by_class_name_is_strongly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> get_elements_by_class_name ptr' idd \<rightarrow>\<^sub>r results"
+ assumes "result \<in> set results"
+ shows "cast result \<in> set c \<longleftrightarrow> ptr' \<in> set c"
+proof
+ assume 1: "cast result \<in> set c"
+ obtain root_ptr where
+ root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ by (metis assms(4) bind_is_OK_E get_dom_component_def is_OK_returns_result_I)
+ then have "h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r c"
+ using \<open>h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c\<close>
+ by (simp add: get_dom_component_def bind_returns_result_E3)
+
+ obtain to' where to': "h \<turnstile> to_tree_order ptr' \<rightarrow>\<^sub>r to'"
+ using assms(5)
+ apply(simp add: get_elements_by_class_name_def first_in_tree_order_def)
+ by (meson bind_is_OK_E is_OK_returns_result_I)
+ then have "cast result \<in> set to'"
+ using assms get_elements_by_class_name_result_in_tree_order by blast
+
+ have "h \<turnstile> get_root_node (cast result) \<rightarrow>\<^sub>r root_ptr"
+ using "1" assms(1) assms(2) assms(3) assms(4) get_dom_component_root_node_same root_ptr
+ by blast
+ then have "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr"
+ using \<open>cast result \<in> set to'\<close> \<open>h \<turnstile> to_tree_order ptr' \<rightarrow>\<^sub>r to'\<close>
+ using "1" assms(1) assms(2) assms(3) assms(4) get_dom_component_ptr get_dom_component_root_node_same
+ get_dom_component_subset get_dom_component_to_tree_order
+ by blast
+ then have "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c"
+ using \<open>h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r c\<close>
+ using get_dom_component_def by auto
+ then show "ptr' \<in> set c"
+ using assms(1) assms(2) assms(3) get_dom_component_ptr by blast
+next
+ assume "ptr' \<in> set c"
+ moreover obtain to' where to': "h \<turnstile> to_tree_order ptr' \<rightarrow>\<^sub>r to'"
+ by (meson assms(1) assms(2) assms(3) assms(4) calculation get_dom_component_ptr_in_heap
+ get_dom_component_subset is_OK_returns_result_E is_OK_returns_result_I to_tree_order_ok)
+ ultimately have "set to' \<subseteq> set c"
+ using assms(1) assms(2) assms(3) assms(4) get_dom_component_subset
+ get_dom_component_to_tree_order_subset
+ by blast
+ moreover have "cast result \<in> set to'"
+ using assms get_elements_by_class_name_result_in_tree_order to' by blast
+ ultimately show "cast result \<in> set c"
+ by blast
+qed
+
+lemma get_elements_by_class_name_pure [simp]:
+ "pure (get_elements_by_class_name ptr name) h"
+ by(auto simp add: get_elements_by_class_name_def intro!: bind_pure_I map_filter_M_pure
+ split: option.splits)
+
+lemma get_elements_by_class_name_is_strongly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_elements_by_class_name ptr name \<rightarrow>\<^sub>r results"
+ assumes "h \<turnstile> get_elements_by_class_name ptr name \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_dom_component_safe {ptr} (cast ` set results) h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by (meson get_elements_by_class_name_pure pure_returns_heap_eq)
+ have "ptr |\<in>| object_ptr_kinds h"
+ using assms(4)
+ apply(auto simp add: get_elements_by_class_name_def)[1]
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) bind_is_OK_E is_OK_returns_result_I
+ local.first_in_tree_order_def local.to_tree_order_ptr_in_result local.to_tree_order_ptrs_in_heap)
+ obtain to where to: "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ by (meson \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) is_OK_returns_result_E
+ local.to_tree_order_ok)
+ then have "cast ` set results \<subseteq> set to"
+ using assms(4) local.get_elements_by_class_name_result_in_tree_order by auto
+ obtain c where c: "h \<turnstile> a_get_dom_component ptr \<rightarrow>\<^sub>r c"
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) local.get_dom_component_impl
+ local.get_dom_component_ok by blast
+
+ then show ?thesis
+ using assms \<open>h = h'\<close>
+ apply(auto simp add: is_strongly_dom_component_safe_def Let_def preserved_def
+ get_elements_by_class_name_def first_in_tree_order_def elim!: bind_returns_result_E2
+ intro!: map_filter_M_pure bind_pure_I split: option.splits list.splits)[1]
+ by (metis (no_types, lifting) Int_iff \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(4) finite_set_in
+ get_elements_by_class_name_is_strongly_dom_component_safe_step local.get_dom_component_impl
+ local.get_dom_component_ptr select_result_I2)
+qed
+end
+
+interpretation i_get_dom_component_get_elements_by_class_name?:
+ l_get_dom_component_get_elements_by_class_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name first_in_tree_order get_attribute get_attribute_locs
+ by(auto simp add: l_get_dom_component_get_elements_by_class_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_get_elements_by_class_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_elements\_by\_tag\_name\<close>
+
+locale l_get_dom_component_get_elements_by_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_elements_by_tag_name_is_strongly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ assumes "h \<turnstile> get_elements_by_tag_name ptr' idd \<rightarrow>\<^sub>r results"
+ assumes "result \<in> set results"
+ shows "cast result \<in> set c \<longleftrightarrow> ptr' \<in> set c"
+proof
+ assume 1: "cast result \<in> set c"
+ obtain root_ptr where
+ root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ by (metis assms(4) bind_is_OK_E get_dom_component_def is_OK_returns_result_I)
+ then have "h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r c"
+ using \<open>h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c\<close>
+ by (simp add: get_dom_component_def bind_returns_result_E3)
+
+ obtain to' where to': "h \<turnstile> to_tree_order ptr' \<rightarrow>\<^sub>r to'"
+ using assms(5)
+ apply(simp add: get_elements_by_tag_name_def first_in_tree_order_def)
+ by (meson bind_is_OK_E is_OK_returns_result_I)
+ then have "cast result \<in> set to'"
+ using assms get_elements_by_tag_name_result_in_tree_order by blast
+
+ have "h \<turnstile> get_root_node (cast result) \<rightarrow>\<^sub>r root_ptr"
+ using "1" assms(1) assms(2) assms(3) assms(4) get_dom_component_root_node_same root_ptr
+ by blast
+ then have "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root_ptr"
+ using \<open>cast result \<in> set to'\<close> \<open>h \<turnstile> to_tree_order ptr' \<rightarrow>\<^sub>r to'\<close>
+ using "1" assms(1) assms(2) assms(3) assms(4) get_dom_component_ptr
+ get_dom_component_root_node_same get_dom_component_subset get_dom_component_to_tree_order
+ by blast
+ then have "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c"
+ using \<open>h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r c\<close>
+ using get_dom_component_def by auto
+ then show "ptr' \<in> set c"
+ using assms(1) assms(2) assms(3) get_dom_component_ptr by blast
+next
+ assume "ptr' \<in> set c"
+ moreover obtain to' where to': "h \<turnstile> to_tree_order ptr' \<rightarrow>\<^sub>r to'"
+ by (meson assms(1) assms(2) assms(3) assms(4) calculation get_dom_component_ptr_in_heap
+ get_dom_component_subset is_OK_returns_result_E is_OK_returns_result_I to_tree_order_ok)
+ ultimately have "set to' \<subseteq> set c"
+ using assms(1) assms(2) assms(3) assms(4) get_dom_component_subset
+ get_dom_component_to_tree_order_subset
+ by blast
+ moreover have "cast result \<in> set to'"
+ using assms get_elements_by_tag_name_result_in_tree_order to' by blast
+ ultimately show "cast result \<in> set c"
+ by blast
+qed
+
+lemma get_elements_by_tag_name_is_strongly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_elements_by_tag_name ptr name \<rightarrow>\<^sub>r results"
+ assumes "h \<turnstile> get_elements_by_tag_name ptr name \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_dom_component_safe {ptr} (cast ` set results) h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by (meson get_elements_by_tag_name_pure pure_returns_heap_eq)
+ have "ptr |\<in>| object_ptr_kinds h"
+ using assms(4)
+ apply(auto simp add: get_elements_by_tag_name_def)[1]
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) bind_is_OK_E is_OK_returns_result_I
+ local.first_in_tree_order_def local.to_tree_order_ptr_in_result local.to_tree_order_ptrs_in_heap)
+ obtain to where to: "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ by (meson \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) is_OK_returns_result_E
+ local.to_tree_order_ok)
+ then have "cast ` set results \<subseteq> set to"
+ using assms(4) local.get_elements_by_tag_name_result_in_tree_order by auto
+ obtain c where c: "h \<turnstile> a_get_dom_component ptr \<rightarrow>\<^sub>r c"
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) local.get_dom_component_impl
+ local.get_dom_component_ok by blast
+
+ then show ?thesis
+ using assms \<open>h = h'\<close>
+ apply(auto simp add: is_strongly_dom_component_safe_def Let_def preserved_def
+ get_elements_by_class_name_def first_in_tree_order_def elim!: bind_returns_result_E2
+ intro!: map_filter_M_pure bind_pure_I split: option.splits list.splits)[1]
+ by (metis (no_types, lifting) IntI \<open>ptr |\<in>| object_ptr_kinds h\<close> finite_set_in
+ get_elements_by_tag_name_is_strongly_dom_component_safe_step local.get_dom_component_impl
+ local.get_dom_component_ptr select_result_I2)
+qed
+end
+
+interpretation i_get_dom_component_get_elements_by_tag_name?:
+ l_get_dom_component_get_elements_by_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name first_in_tree_order get_attribute get_attribute_locs
+ by(auto simp add: l_get_dom_component_get_elements_by_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_get_elements_by_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>remove\_child\<close>
+
+lemma remove_child_unsafe: "\<not>(\<forall>(h
+ :: ('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap
+ ) h' ptr child. heap_is_wellformed h \<longrightarrow> type_wf h \<longrightarrow> known_ptrs h \<longrightarrow>
+h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h' \<longrightarrow> is_weakly_dom_component_safe {ptr, cast child} {} h h')"
+proof -
+ obtain h document_ptr e1 e2 where h: "Inr ((document_ptr, e1, e2), h) = (Heap (fmempty)
+ :: ('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap
+ ) \<turnstile> (do {
+ document_ptr \<leftarrow> create_document;
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast e1) (cast e2);
+ return (document_ptr, e1, e2)
+ })"
+ by(code_simp, auto simp add: equal_eq List.member_def)+
+ then obtain h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ h': "h \<turnstile> remove_child (cast e1) (cast e2) \<rightarrow>\<^sub>h h'" and
+ "\<not>(is_weakly_dom_component_safe {cast e1, cast e2} {} h h')"
+ apply(code_simp)
+ apply(clarify)
+ by(code_simp, auto simp add: equal_eq List.member_def)+
+ then show ?thesis
+ by auto
+qed
+
+
+subsubsection \<open>adopt\_node\<close>
+
+lemma adopt_node_unsafe: "\<not>(\<forall>(h
+ :: ('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap
+ ) h' document_ptr child. heap_is_wellformed h \<longrightarrow> type_wf h \<longrightarrow> known_ptrs h \<longrightarrow> h \<turnstile> adopt_node document_ptr child \<rightarrow>\<^sub>h h' \<longrightarrow> is_weakly_dom_component_safe {cast document_ptr, cast child} {} h h')"
+proof -
+ obtain h document_ptr document_ptr2 e1 where h: "Inr ((document_ptr, document_ptr2, e1), h) = (Heap (fmempty)
+ :: ('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap
+ ) \<turnstile> (do {
+ document_ptr \<leftarrow> create_document;
+ document_ptr2 \<leftarrow> create_document;
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ adopt_node document_ptr2 (cast e1);
+ return (document_ptr, document_ptr2, e1)
+ })"
+ by(code_simp, auto simp add: equal_eq List.member_def)+
+ then obtain h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ h': "h \<turnstile> adopt_node document_ptr (cast e1) \<rightarrow>\<^sub>h h'" and
+ "\<not>(is_weakly_dom_component_safe {cast document_ptr, cast e1} {} h h')"
+ apply(code_simp)
+ apply(clarify)
+ by(code_simp, auto simp add: equal_eq List.member_def)+
+ then show ?thesis
+ by auto
+qed
+
+
+subsubsection \<open>create\_element\<close>
+
+lemma create_element_not_strongly_dom_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap" and
+ h' and document_ptr and new_element_ptr and tag where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr \<rightarrow>\<^sub>h h'" and
+ "\<not> is_strongly_dom_component_safe {cast document_ptr} {cast new_element_ptr} h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap"
+ let ?P = "create_document"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?document_ptr = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and document_ptr="?document_ptr"])
+ by code_simp+
+qed
+
+
+locale l_get_dom_component_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ to_tree_order get_parent get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs
+ get_ancestors get_ancestors_locs get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id
+ get_elements_by_class_name get_elements_by_tag_name +
+ l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs set_tag_name set_tag_name_locs type_wf create_element known_ptr +
+ l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_disconnected_nodes get_disconnected_nodes_locs +
+ l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_disconnected_nodes set_disconnected_nodes_locs +
+ l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_tag_name set_tag_name_locs +
+ l_new_element_get_disconnected_nodes get_disconnected_nodes get_disconnected_nodes_locs +
+ l_new_element_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs +
+ l_set_tag_name_get_child_nodes type_wf set_tag_name set_tag_name_locs known_ptr
+ get_child_nodes get_child_nodes_locs +
+ l_create_element_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr known_ptrs type_wf get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs heap_is_wellformed parent_child_rel set_tag_name
+ set_tag_name_locs
+ set_disconnected_nodes set_disconnected_nodes_locs create_element
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and to_tree_order :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_dom_component :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and is_strongly_dom_component_safe :: "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ and is_weakly_dom_component_safe :: "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ and get_root_node :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_ancestors :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_ancestors_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_element_by_id :: "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog"
+ and get_elements_by_class_name :: "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr list) prog"
+ and get_elements_by_tag_name :: "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr list) prog"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_tag_name :: "(_) element_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and create_element :: "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+begin
+
+lemma create_element_is_weakly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast document_ptr)|\<^sub>r"
+ assumes "ptr \<noteq> cast |h \<turnstile> create_element document_ptr tag|\<^sub>r"
+ shows "preserved (get_M ptr getter) h h'"
+proof -
+ obtain new_element_ptr h2 h3 disc_nodes where
+ new_element_ptr: "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr" and
+ h2: "h \<turnstile> new_element \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile>set_tag_name new_element_ptr tag \<rightarrow>\<^sub>h h3" and
+ disc_nodes: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_element_ptr # disc_nodes) \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ by(auto simp add: create_element_def
+ elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated])
+ have "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr"
+ using new_element_ptr h2 h3 disc_nodes h'
+ apply(auto simp add: create_element_def intro!: bind_returns_result_I
+ bind_pure_returns_result_I[OF get_disconnected_nodes_pure])[1]
+ apply (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ by (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ have "preserved (get_M ptr getter) h h2"
+ using h2 new_element_ptr
+ apply(rule new_element_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t)
+ using new_element_ptr assms(6) \<open>h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr\<close>
+ by simp
+
+ have "preserved (get_M ptr getter) h2 h3"
+ using set_tag_name_writes h3
+ apply(rule reads_writes_preserved2)
+ apply(auto simp add: set_tag_name_locs_impl a_set_tag_name_locs_def all_args_def)[1]
+ by (metis (no_types, lifting) \<open>h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr\<close> assms(6)
+ get_M_Element_preserved8 select_result_I2)
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using create_element_document_in_heap
+ using assms(4)
+ by blast
+ then
+ have "ptr \<noteq> (cast document_ptr)"
+ using assms(5) assms(1) assms(2) assms(3) local.get_dom_component_ok local.get_dom_component_ptr
+ by auto
+ have "preserved (get_M ptr getter) h3 h'"
+ using set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved2)
+ apply(auto simp add: set_disconnected_nodes_locs_def all_args_def)[1]
+ by (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr\<close> get_M_Mdocument_preserved3)
+
+ show ?thesis
+ using \<open>preserved (get_M ptr getter) h h2\<close> \<open>preserved (get_M ptr getter) h2 h3\<close>
+ \<open>preserved (get_M ptr getter) h3 h'\<close>
+ by(auto simp add: preserved_def)
+qed
+
+
+lemma create_element_is_weakly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r result"
+ assumes "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>h h'"
+ shows "is_weakly_dom_component_safe {cast document_ptr} {cast result} h h'"
+proof -
+
+ obtain new_element_ptr h2 h3 disc_nodes_h3 where
+ new_element_ptr: "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr" and
+ h2: "h \<turnstile> new_element \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile> set_tag_name new_element_ptr tag \<rightarrow>\<^sub>h h3" and
+ disc_nodes_h3: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_element_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'"
+ using assms(5)
+ by(auto simp add: create_element_def
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+ then have "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr"
+ apply(auto simp add: create_element_def intro!: bind_returns_result_I)[1]
+ apply (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ apply (metis is_OK_returns_heap_E is_OK_returns_result_I local.get_disconnected_nodes_pure
+ pure_returns_heap_eq)
+ by (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+
+ have "new_element_ptr \<notin> set |h \<turnstile> element_ptr_kinds_M|\<^sub>r"
+ using new_element_ptr ElementMonad.ptr_kinds_ptr_kinds_M h2
+ using new_element_ptr_not_in_heap by blast
+ then have "cast new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have "cast new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+
+ have object_ptr_kinds_eq_h: "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ using new_element_new_ptr h2 new_element_ptr by blast
+ then have node_ptr_kinds_eq_h: "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h |\<union>| {|new_element_ptr|}"
+ apply(simp add: element_ptr_kinds_def)
+ by force
+ have character_data_ptr_kinds_eq_h: "character_data_ptr_kinds h2 = character_data_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def character_data_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_tag_name_writes h3])
+ using set_tag_name_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+ have "known_ptr (cast new_element_ptr)"
+ using \<open>h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr\<close> local.create_element_known_ptr
+ by blast
+ then
+ have "known_ptrs h2"
+ using known_ptrs_new_ptr object_ptr_kinds_eq_h \<open>known_ptrs h\<close> h2
+ by blast
+ then
+ have "known_ptrs h3"
+ using known_ptrs_preserved object_ptr_kinds_eq_h2 by blast
+ then
+ have "known_ptrs h'"
+ using known_ptrs_preserved object_ptr_kinds_eq_h3 by blast
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_element_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads h2 get_child_nodes_new_element[rotated, OF new_element_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h: "\<And>ptr'. ptr' \<noteq> cast new_element_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []"
+ using new_element_ptr h2 new_element_ptr_in_heap[OF h2 new_element_ptr]
+ new_element_is_element_ptr[OF new_element_ptr] new_element_no_child_nodes
+ by blast
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads h2 get_disconnected_nodes_new_element[OF new_element_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have disconnected_nodes_eq2_h:
+ "\<And>doc_ptr. |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_tag_name_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_tag_name_get_child_nodes)
+ then have children_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_tag_name_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_tag_name_get_disconnected_nodes)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have "type_wf h2"
+ using \<open>type_wf h\<close> new_element_types_preserved h2 by blast
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_tag_name_writes h3]
+ using set_tag_name_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then have "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_eq_h3:
+ "\<And>ptr' children. h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h3: "\<And>ptr'. |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h3:
+ "\<And>doc_ptr disc_nodes. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h3:
+ "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have disc_nodes_document_ptr_h2: "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h2 disc_nodes_h3 by auto
+ then have disc_nodes_document_ptr_h: "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h by auto
+ then have "cast new_element_ptr \<notin> set disc_nodes_h3"
+ using \<open>heap_is_wellformed h\<close>
+ using \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ a_all_ptrs_in_heap_def heap_is_wellformed_def
+ using NodeMonad.ptr_kinds_ptr_kinds_M local.heap_is_wellformed_disc_nodes_in_heap by blast
+
+ have "acyclic (parent_child_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def acyclic_heap_def)
+ also have "parent_child_rel h = parent_child_rel h2"
+ proof(auto simp add: parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h2"
+ by (simp add: object_ptr_kinds_eq_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq_h \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting)
+ \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2_h empty_iff empty_set image_eqI select_result_I2)
+ qed
+ also have "\<dots> = parent_child_rel h3"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h2 children_eq2_h2)
+ also have "\<dots> = parent_child_rel h'"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h3 children_eq2_h3)
+ finally have "a_acyclic_heap h'"
+ by (simp add: acyclic_heap_def)
+
+ have "a_all_ptrs_in_heap h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def)
+ then have "a_all_ptrs_in_heap h2"
+ apply(auto simp add: a_all_ptrs_in_heap_def)[1]
+ apply (metis \<open>known_ptrs h2\<close> \<open>parent_child_rel h = parent_child_rel h2\<close> \<open>type_wf h2\<close> assms
+ funion_iff local.get_child_nodes_ok local.known_ptrs_known_ptr local.parent_child_rel_child_in_heap
+ local.parent_child_rel_child_nodes2 node_ptr_kinds_commutes node_ptr_kinds_eq_h
+ returns_result_select_result)
+ by (metis assms disconnected_nodes_eq2_h document_ptr_kinds_eq_h funion_iff
+ local.get_disconnected_nodes_ok local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_eq_h
+ returns_result_select_result)
+ then have "a_all_ptrs_in_heap h3"
+ by (simp add: children_eq2_h2 disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ local.a_all_ptrs_in_heap_def node_ptr_kinds_eq_h2 object_ptr_kinds_eq_h2)
+ then have "a_all_ptrs_in_heap h'"
+ by (smt \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close> children_eq2_h3
+ disc_nodes_document_ptr_h2 disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 document_ptr_kinds_eq_h3
+ finite_set_in h' is_OK_returns_result_I
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ local.a_all_ptrs_in_heap_def local.get_child_nodes_ptr_in_heap
+ local.l_set_disconnected_nodes_get_disconnected_nodes_axioms node_ptr_kinds_commutes
+ object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 select_result_I2 set_ConsD subset_code(1))
+
+ have "\<And>p. p |\<in>| object_ptr_kinds h \<Longrightarrow> cast new_element_ptr \<notin> set |h \<turnstile> get_child_nodes p|\<^sub>r"
+ using \<open>heap_is_wellformed h\<close> \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ heap_is_wellformed_children_in_heap
+ by (meson NodeMonad.ptr_kinds_ptr_kinds_M a_all_ptrs_in_heap_def assms fset_mp
+ fset_of_list_elem get_child_nodes_ok known_ptrs_known_ptr returns_result_select_result)
+ then have "\<And>p. p |\<in>| object_ptr_kinds h2 \<Longrightarrow> cast new_element_ptr \<notin> set |h2 \<turnstile> get_child_nodes p|\<^sub>r"
+ using children_eq2_h
+ apply(auto simp add: object_ptr_kinds_eq_h)[1]
+ using \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close> apply auto[1]
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>)
+ then have "\<And>p. p |\<in>| object_ptr_kinds h3 \<Longrightarrow> cast new_element_ptr \<notin> set |h3 \<turnstile> get_child_nodes p|\<^sub>r"
+ using object_ptr_kinds_eq_h2 children_eq2_h2 by auto
+ then have new_element_ptr_not_in_any_children:
+ "\<And>p. p |\<in>| object_ptr_kinds h' \<Longrightarrow> cast new_element_ptr \<notin> set |h' \<turnstile> get_child_nodes p|\<^sub>r"
+ using object_ptr_kinds_eq_h3 children_eq2_h3 by auto
+
+ have "a_distinct_lists h"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def)
+ then have "a_distinct_lists h2"
+
+ using \<open>h2 \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ apply(auto simp add: a_distinct_lists_def object_ptr_kinds_eq_h document_ptr_kinds_eq_h
+ disconnected_nodes_eq2_h intro!: distinct_concat_map_I)[1]
+ apply (metis distinct_sorted_list_of_set finite_fset sorted_list_of_set_insert)
+ apply(case_tac "x=cast new_element_ptr")
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply (metis IntI assms empty_iff local.get_child_nodes_ok
+ local.heap_is_wellformed_one_parent local.known_ptrs_known_ptr returns_result_select_result)
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ by (metis \<open>local.a_distinct_lists h\<close> \<open>type_wf h2\<close> disconnected_nodes_eq_h document_ptr_kinds_eq_h
+ local.distinct_lists_no_parent local.get_disconnected_nodes_ok returns_result_select_result)
+
+ then have "a_distinct_lists h3"
+ by(auto simp add: a_distinct_lists_def disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ children_eq2_h2 object_ptr_kinds_eq_h2)
+ then have "a_distinct_lists h'"
+ proof(auto simp add: a_distinct_lists_def disconnected_nodes_eq2_h3 children_eq2_h3
+ object_ptr_kinds_eq_h3 document_ptr_kinds_eq_h3
+ intro!: distinct_concat_map_I)[1]
+ fix x
+ assume "distinct (concat (map (\<lambda>document_ptr. |h3 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and "x |\<in>| document_ptr_kinds h3"
+ then show "distinct |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using document_ptr_kinds_eq_h3 disconnected_nodes_eq_h3 h' set_disconnected_nodes_get_disconnected_nodes
+ by (metis (no_types, lifting) \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set disc_nodes_h3\<close>
+ \<open>a_distinct_lists h3\<close> \<open>type_wf h'\<close> disc_nodes_h3 distinct.simps(2)
+ distinct_lists_disconnected_nodes get_disconnected_nodes_ok returns_result_eq
+ returns_result_select_result)
+ next
+ fix x y xa
+ assume "distinct (concat (map (\<lambda>document_ptr. |h3 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and "x |\<in>| document_ptr_kinds h3"
+ and "y |\<in>| document_ptr_kinds h3"
+ and "x \<noteq> y"
+ and "xa \<in> set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ and "xa \<in> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ moreover have "set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h3 \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ using calculation by(auto dest: distinct_concat_map_E(1))
+ ultimately show "False"
+ apply(-)
+ apply(cases "x = document_ptr")
+ apply (smt NodeMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close> \<open>local.a_all_ptrs_in_heap h\<close>
+ disc_nodes_h3 disconnected_nodes_eq2_h disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ disjoint_iff_not_equal document_ptr_kinds_eq_h document_ptr_kinds_eq_h2 finite_set_in h'
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ local.a_all_ptrs_in_heap_def local.l_set_disconnected_nodes_get_disconnected_nodes_axioms
+ select_result_I2 set_ConsD subsetD)
+ by (smt NodeMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close> \<open>local.a_all_ptrs_in_heap h\<close>
+ disc_nodes_document_ptr_h2 disconnected_nodes_eq2_h disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3
+ disjoint_iff_not_equal document_ptr_kinds_eq_h document_ptr_kinds_eq_h2 finite_set_in h'
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ local.a_all_ptrs_in_heap_def local.l_set_disconnected_nodes_get_disconnected_nodes_axioms
+ select_result_I2 set_ConsD subsetD)
+ next
+ fix x xa xb
+ assume 2: "(\<Union>x\<in>fset (object_ptr_kinds h3). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h3). set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 3: "xa |\<in>| object_ptr_kinds h3"
+ and 4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 5: "xb |\<in>| document_ptr_kinds h3"
+ and 6: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ show "False"
+ using disc_nodes_document_ptr_h disconnected_nodes_eq2_h3
+ apply -
+ apply(cases "xb = document_ptr")
+ apply (metis (no_types, hide_lams) "3" "4" "6"
+ \<open>\<And>p. p |\<in>| object_ptr_kinds h3
+ \<Longrightarrow> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h3 \<turnstile> get_child_nodes p|\<^sub>r\<close>
+ \<open>a_distinct_lists h3\<close> children_eq2_h3 disc_nodes_h3 distinct_lists_no_parent h'
+ select_result_I2 set_ConsD set_disconnected_nodes_get_disconnected_nodes)
+ by (metis "3" "4" "5" "6" \<open>a_distinct_lists h3\<close> \<open>type_wf h3\<close> children_eq2_h3
+ distinct_lists_no_parent get_disconnected_nodes_ok returns_result_select_result)
+ qed
+
+ have "a_owner_document_valid h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def)
+ then have "a_owner_document_valid h'"
+ using disc_nodes_h3 \<open>document_ptr |\<in>| document_ptr_kinds h\<close>
+ apply(auto simp add: a_owner_document_valid_def)[1]
+ apply(auto simp add: object_ptr_kinds_eq_h object_ptr_kinds_eq_h3 )[1]
+ apply(auto simp add: object_ptr_kinds_eq_h2)[1]
+ apply(auto simp add: document_ptr_kinds_eq_h document_ptr_kinds_eq_h3 )[1]
+ apply(auto simp add: document_ptr_kinds_eq_h2)[1]
+ apply(auto simp add: node_ptr_kinds_eq_h node_ptr_kinds_eq_h3 )[1]
+ apply(auto simp add: node_ptr_kinds_eq_h2 node_ptr_kinds_eq_h )[1]
+ apply(auto simp add: children_eq2_h2[symmetric] children_eq2_h3[symmetric]
+ disconnected_nodes_eq2_h disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3)[1]
+ apply (metis (no_types, lifting) document_ptr_kinds_eq_h h' list.set_intros(1)
+ local.set_disconnected_nodes_get_disconnected_nodes select_result_I2)
+ apply(simp add: object_ptr_kinds_eq_h)
+ by(metis (no_types, lifting) NodeMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close> children_eq2_h
+ children_eq2_h2 children_eq2_h3 disconnected_nodes_eq2_h disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3 document_ptr_kinds_eq_h finite_set_in h'
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ list.set_intros(2) local.l_set_disconnected_nodes_get_disconnected_nodes_axioms
+ node_ptr_kinds_commutes select_result_I2)
+
+
+ have "parent_child_rel h = parent_child_rel h'"
+ proof -
+ have "parent_child_rel h = parent_child_rel h2"
+ proof(auto simp add: parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h2"
+ by (simp add: object_ptr_kinds_eq_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq_h \<open>h2 \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting) \<open>h2 \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2_h empty_iff empty_set image_eqI select_result_I2)
+ qed
+ also have "\<dots> = parent_child_rel h3"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h2 children_eq2_h2)
+ also have "\<dots> = parent_child_rel h'"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h3 children_eq2_h3)
+ finally show ?thesis
+ by simp
+ qed
+ have root: "h \<turnstile> get_root_node (cast document_ptr) \<rightarrow>\<^sub>r cast document_ptr"
+ by (simp add: \<open>document_ptr |\<in>| document_ptr_kinds h\<close> local.get_root_node_not_node_same)
+ then
+ have root': "h' \<turnstile> get_root_node (cast document_ptr) \<rightarrow>\<^sub>r cast document_ptr"
+ by (simp add: \<open>document_ptr |\<in>| document_ptr_kinds h\<close> document_ptr_kinds_eq_h
+ local.get_root_node_not_node_same object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3)
+
+ have "heap_is_wellformed h'" and "known_ptrs h'"
+ using create_element_preserves_wellformedness assms
+ by blast+
+
+ have "cast result |\<notin>| object_ptr_kinds h"
+ using \<open>cast new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>
+ by (metis (full_types) ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr\<close> assms(4) returns_result_eq)
+
+ obtain to where to: "h \<turnstile> to_tree_order (cast document_ptr) \<rightarrow>\<^sub>r to"
+ by (meson \<open>document_ptr |\<in>| document_ptr_kinds h\<close> assms(1) assms(2) assms(3)
+ document_ptr_kinds_commutes is_OK_returns_result_E local.to_tree_order_ok)
+ then
+ have "h \<turnstile> a_get_dom_component (cast document_ptr) \<rightarrow>\<^sub>r to"
+ using root
+ by(auto simp add: a_get_dom_component_def)
+ moreover
+ obtain to' where to': "h' \<turnstile> to_tree_order (cast document_ptr) \<rightarrow>\<^sub>r to'"
+ by (meson \<open>heap_is_wellformed h'\<close> \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> is_OK_returns_result_E
+ local.get_root_node_root_in_heap local.to_tree_order_ok root')
+ then
+ have "h' \<turnstile> a_get_dom_component (cast document_ptr) \<rightarrow>\<^sub>r to'"
+ using root'
+ by(auto simp add: a_get_dom_component_def)
+ moreover
+ have "\<And>child. child \<in> set to \<longleftrightarrow> child \<in> set to'"
+ by (metis \<open>heap_is_wellformed h'\<close> \<open>known_ptrs h'\<close> \<open>parent_child_rel h = parent_child_rel h'\<close>
+ \<open>type_wf h'\<close> assms(1) assms(2) assms(3) local.to_tree_order_parent_child_rel to to')
+ ultimately
+ have "set |h \<turnstile> local.a_get_dom_component (cast document_ptr)|\<^sub>r =
+set |h' \<turnstile> local.a_get_dom_component (cast document_ptr)|\<^sub>r"
+ by(auto simp add: a_get_dom_component_def)
+
+ show ?thesis
+ apply(auto simp add: is_weakly_dom_component_safe_def Let_def)[1]
+ using \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close> assms(2) assms(3)
+ children_eq_h local.get_child_nodes_ok local.get_child_nodes_ptr_in_heap local.known_ptrs_known_ptr
+ object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 returns_result_select_result
+ apply (metis is_OK_returns_result_I)
+ apply (metis \<open>h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr\<close> assms(4)
+ element_ptr_kinds_commutes h2 new_element_ptr new_element_ptr_in_heap node_ptr_kinds_eq_h2
+ node_ptr_kinds_eq_h3 returns_result_eq returns_result_heap_def)
+ using \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r result |\<notin>| object_ptr_kinds h\<close> element_ptr_kinds_commutes
+ node_ptr_kinds_commutes apply blast
+ using assms(1) assms(2) assms(3) \<open>h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>h h'\<close>
+ apply(rule create_element_is_weakly_dom_component_safe_step)
+ apply (simp add: local.get_dom_component_impl)
+ using \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>
+ \<open>h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr\<close>
+ by auto
+
+qed
+end
+
+interpretation i_get_dom_component_create_element?: l_get_dom_component_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr heap_is_wellformed parent_child_rel type_wf known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_element_by_id get_elements_by_class_name get_elements_by_tag_name get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs set_tag_name
+ set_tag_name_locs create_element
+ by(auto simp add: l_get_dom_component_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+
+subsubsection \<open>create\_character\_data\<close>
+
+lemma create_character_data_not_strongly_dom_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder},
+'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap" and
+ h' and document_ptr and create_character_datanew_character_data_ptr and tag where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> create_character_data document_ptr tag \<rightarrow>\<^sub>r create_character_datanew_character_data_ptr \<rightarrow>\<^sub>h h'" and
+ "\<not> is_strongly_dom_component_safe {cast document_ptr} {cast create_character_datanew_character_data_ptr} h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap"
+ let ?P = "create_document"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?document_ptr = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and document_ptr="?document_ptr"])
+ by code_simp+
+qed
+
+locale l_get_dom_component_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ to_tree_order get_parent get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs
+ get_ancestors get_ancestors_locs get_disconnected_nodes get_disconnected_nodes_locs
+ get_element_by_id get_elements_by_class_name get_elements_by_tag_name +
+ l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs set_val set_val_locs type_wf create_character_data known_ptr +
+ l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_disconnected_nodes get_disconnected_nodes_locs +
+ l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_disconnected_nodes set_disconnected_nodes_locs +
+ l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_val set_val_locs +
+ l_create_character_data_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs heap_is_wellformed parent_child_rel set_val
+ set_val_locs set_disconnected_nodes set_disconnected_nodes_locs
+ create_character_data known_ptrs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and to_tree_order :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_dom_component :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and is_strongly_dom_component_safe :: "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ and is_weakly_dom_component_safe :: "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ and get_root_node :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_ancestors :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_ancestors_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_element_by_id :: "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog"
+ and get_elements_by_class_name :: "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr list) prog"
+ and get_elements_by_tag_name :: "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr list) prog"
+ and set_val :: "(_) character_data_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_val_locs :: "(_) character_data_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and create_character_data :: "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) character_data_ptr) prog"
+begin
+
+lemma create_character_data_is_weakly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast document_ptr)|\<^sub>r"
+ assumes "ptr \<noteq> cast |h \<turnstile> create_character_data document_ptr text|\<^sub>r"
+ shows "preserved (get_M ptr getter) h h'"
+proof -
+ obtain new_character_data_ptr h2 h3 disc_nodes where
+ new_character_data_ptr: "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr" and
+ h2: "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile> set_val new_character_data_ptr text \<rightarrow>\<^sub>h h3" and
+ disc_nodes: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_character_data_ptr # disc_nodes) \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ by(auto simp add: create_character_data_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated])
+
+ have "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr"
+ using new_character_data_ptr h2 h3 disc_nodes h'
+ apply(auto simp add: create_character_data_def intro!: bind_returns_result_I
+ bind_pure_returns_result_I[OF get_disconnected_nodes_pure])[1]
+ apply (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ by (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ have "preserved (get_M ptr getter) h h2"
+ using h2 new_character_data_ptr
+ apply(rule new_character_data_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t)
+ using new_character_data_ptr assms(6)
+ \<open>h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr\<close>
+ by simp
+
+ have "preserved (get_M ptr getter) h2 h3"
+ using set_val_writes h3
+ apply(rule reads_writes_preserved2)
+ apply(auto simp add: set_val_locs_impl a_set_val_locs_def all_args_def)[1]
+ by (metis (mono_tags) CharacterData_simp11
+ \<open>h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr\<close> assms(4) assms(6)
+ is_OK_returns_heap_I is_OK_returns_result_E returns_result_eq select_result_I2)
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using create_character_data_document_in_heap
+ using assms(4)
+ by blast
+ then
+ have "ptr \<noteq> (cast document_ptr)"
+ using assms(5) assms(1) assms(2) assms(3) local.get_dom_component_ok local.get_dom_component_ptr
+ by auto
+ have "preserved (get_M ptr getter) h3 h'"
+ using set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved2)
+ apply(auto simp add: set_disconnected_nodes_locs_def all_args_def)[1]
+ by (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr\<close> get_M_Mdocument_preserved3)
+
+ show ?thesis
+ using \<open>preserved (get_M ptr getter) h h2\<close> \<open>preserved (get_M ptr getter) h2 h3\<close>
+ \<open>preserved (get_M ptr getter) h3 h'\<close>
+ by(auto simp add: preserved_def)
+qed
+
+lemma create_character_data_is_weakly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r result"
+ assumes "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>h h'"
+ shows "is_weakly_dom_component_safe {cast document_ptr} {cast result} h h'"
+proof -
+
+
+ obtain new_character_data_ptr h2 h3 disc_nodes_h3 where
+ new_character_data_ptr: "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr" and
+ h2: "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile> set_val new_character_data_ptr text \<rightarrow>\<^sub>h h3" and
+ disc_nodes_h3: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_character_data_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'"
+ using assms(5)
+ by(auto simp add: create_character_data_def
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+ then
+ have "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr"
+ apply(auto simp add: create_character_data_def intro!: bind_returns_result_I)[1]
+ apply (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ apply (metis is_OK_returns_heap_E is_OK_returns_result_I local.get_disconnected_nodes_pure
+ pure_returns_heap_eq)
+ by (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+
+ have "new_character_data_ptr \<notin> set |h \<turnstile> character_data_ptr_kinds_M|\<^sub>r"
+ using new_character_data_ptr CharacterDataMonad.ptr_kinds_ptr_kinds_M h2
+ using new_character_data_ptr_not_in_heap by blast
+ then have "cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have "cast new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+
+
+
+ have object_ptr_kinds_eq_h:
+ "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using new_character_data_new_ptr h2 new_character_data_ptr by blast
+ then have node_ptr_kinds_eq_h:
+ "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have character_data_ptr_kinds_eq_h:
+ "character_data_ptr_kinds h2 = character_data_ptr_kinds h |\<union>| {|new_character_data_ptr|}"
+ apply(simp add: character_data_ptr_kinds_def)
+ by force
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_val_writes h3])
+ using set_val_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads h2 get_child_nodes_new_character_data[rotated, OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h:
+ "\<And>ptr'. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have object_ptr_kinds_eq_h:
+ "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using new_character_data_new_ptr h2 new_character_data_ptr by blast
+ then have node_ptr_kinds_eq_h:
+ "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have character_data_ptr_kinds_eq_h:
+ "character_data_ptr_kinds h2 = character_data_ptr_kinds h |\<union>| {|new_character_data_ptr|}"
+ apply(simp add: character_data_ptr_kinds_def)
+ by force
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_val_writes h3])
+ using set_val_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads h2 get_child_nodes_new_character_data[rotated, OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h: "\<And>ptr'. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []"
+ using new_character_data_ptr h2 new_character_data_ptr_in_heap[OF h2 new_character_data_ptr]
+ new_character_data_is_character_data_ptr[OF new_character_data_ptr]
+ new_character_data_no_child_nodes
+ by blast
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads h2
+ get_disconnected_nodes_new_character_data[OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have disconnected_nodes_eq2_h:
+ "\<And>doc_ptr. |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_val_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_val_get_child_nodes)
+ then have children_eq2_h2:
+ "\<And>ptr'. |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_val_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_val_get_disconnected_nodes)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have "type_wf h2"
+ using \<open>type_wf h\<close> new_character_data_types_preserved h2 by blast
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_val_writes h3]
+ using set_val_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then have "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_eq_h3:
+ "\<And>ptr' children. h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h3:
+ " \<And>ptr'. |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h3: "\<And>doc_ptr disc_nodes. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h3: "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have disc_nodes_document_ptr_h2: "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h2 disc_nodes_h3 by auto
+ then have disc_nodes_document_ptr_h: "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h by auto
+ then have "cast new_character_data_ptr \<notin> set disc_nodes_h3"
+ using \<open>heap_is_wellformed h\<close> using \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ a_all_ptrs_in_heap_def heap_is_wellformed_def
+ using NodeMonad.ptr_kinds_ptr_kinds_M local.heap_is_wellformed_disc_nodes_in_heap by blast
+
+ have "parent_child_rel h = parent_child_rel h'"
+ proof -
+ have "parent_child_rel h = parent_child_rel h2"
+ proof(auto simp add: parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h2"
+ by (simp add: object_ptr_kinds_eq_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq_h \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting) \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2_h empty_iff empty_set image_eqI select_result_I2)
+ qed
+ also have "\<dots> = parent_child_rel h3"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h2 children_eq2_h2)
+ also have "\<dots> = parent_child_rel h'"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h3 children_eq2_h3)
+ finally show ?thesis
+ by simp
+ qed
+ have root: "h \<turnstile> get_root_node (cast document_ptr) \<rightarrow>\<^sub>r cast document_ptr"
+ by (simp add: \<open>document_ptr |\<in>| document_ptr_kinds h\<close> local.get_root_node_not_node_same)
+ then
+ have root': "h' \<turnstile> get_root_node (cast document_ptr) \<rightarrow>\<^sub>r cast document_ptr"
+ by (simp add: \<open>document_ptr |\<in>| document_ptr_kinds h\<close> document_ptr_kinds_eq_h
+ local.get_root_node_not_node_same object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3)
+
+
+ have "heap_is_wellformed h'" and "known_ptrs h'"
+ using create_character_data_preserves_wellformedness assms
+ by blast+
+
+ have "cast result |\<notin>| object_ptr_kinds h"
+ using \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>
+ by (metis (full_types) ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr\<close> assms(4) returns_result_eq)
+
+ obtain to where to: "h \<turnstile> to_tree_order (cast document_ptr) \<rightarrow>\<^sub>r to"
+ by (meson \<open>document_ptr |\<in>| document_ptr_kinds h\<close> assms(1) assms(2) assms(3)
+ document_ptr_kinds_commutes is_OK_returns_result_E local.to_tree_order_ok)
+ then
+ have "h \<turnstile> a_get_dom_component (cast document_ptr) \<rightarrow>\<^sub>r to"
+ using root
+ by(auto simp add: a_get_dom_component_def)
+ moreover
+ obtain to' where to': "h' \<turnstile> to_tree_order (cast document_ptr) \<rightarrow>\<^sub>r to'"
+ by (meson \<open>heap_is_wellformed h'\<close> \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> is_OK_returns_result_E
+ local.get_root_node_root_in_heap local.to_tree_order_ok root')
+ then
+ have "h' \<turnstile> a_get_dom_component (cast document_ptr) \<rightarrow>\<^sub>r to'"
+ using root'
+ by(auto simp add: a_get_dom_component_def)
+ moreover
+ have "\<And>child. child \<in> set to \<longleftrightarrow> child \<in> set to'"
+ by (metis \<open>heap_is_wellformed h'\<close> \<open>known_ptrs h'\<close> \<open>parent_child_rel h = parent_child_rel h'\<close>
+ \<open>type_wf h'\<close> assms(1) assms(2) assms(3) local.to_tree_order_parent_child_rel to to')
+ ultimately
+ have "set |h \<turnstile> local.a_get_dom_component (cast document_ptr)|\<^sub>r =
+set |h' \<turnstile> local.a_get_dom_component (cast document_ptr)|\<^sub>r"
+ by(auto simp add: a_get_dom_component_def)
+
+ show ?thesis
+ apply(auto simp add: is_weakly_dom_component_safe_def Let_def)[1]
+ using assms(2) assms(3) children_eq_h local.get_child_nodes_ok
+ local.get_child_nodes_ptr_in_heap local.known_ptrs_known_ptr object_ptr_kinds_eq_h2
+ object_ptr_kinds_eq_h3 returns_result_select_result
+ apply (metis \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ is_OK_returns_result_I)
+
+ apply (metis \<open>h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr\<close> assms(4)
+ character_data_ptr_kinds_commutes h2 new_character_data_ptr new_character_data_ptr_in_heap
+ node_ptr_kinds_eq_h2 node_ptr_kinds_eq_h3 returns_result_eq)
+ using \<open>h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr\<close>
+ \<open>new_character_data_ptr \<notin> set |h \<turnstile> character_data_ptr_kinds_M|\<^sub>r\<close> assms(4) returns_result_eq
+ apply fastforce
+ using assms(2) assms(3) children_eq_h local.get_child_nodes_ok local.get_child_nodes_ptr_in_heap
+ local.known_ptrs_known_ptr object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 returns_result_select_result
+ apply (smt ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>
+ \<open>h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr\<close> assms(1) assms(5)
+ create_character_data_is_weakly_dom_component_safe_step local.get_dom_component_impl select_result_I2)
+ done
+qed
+
+end
+
+interpretation i_get_dom_component_create_character_data?: l_get_dom_component_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr heap_is_wellformed parent_child_rel type_wf known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_element_by_id get_elements_by_class_name get_elements_by_tag_name set_val set_val_locs
+ get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs
+ create_character_data
+ by(auto simp add: l_get_dom_component_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>create\_document\<close>
+
+lemma create_document_unsafe: "\<not>(\<forall>(h
+ :: ('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap
+ ) h' new_document_ptr. heap_is_wellformed h \<longrightarrow> type_wf h \<longrightarrow> known_ptrs h \<longrightarrow>
+h \<turnstile> create_document \<rightarrow>\<^sub>r new_document_ptr \<longrightarrow> h \<turnstile> create_document \<rightarrow>\<^sub>h h' \<longrightarrow>
+is_strongly_dom_component_safe {} {cast new_document_ptr} h h')"
+proof -
+ obtain h document_ptr where h: "Inr (document_ptr, h) = (Heap (fmempty)
+ :: ('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap
+ ) \<turnstile> (do {
+ document_ptr \<leftarrow> create_document;
+ return (document_ptr)
+ })"
+ by(code_simp, auto simp add: equal_eq List.member_def)+
+ then obtain h' new_document_ptr where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ h': "h \<turnstile> create_document \<rightarrow>\<^sub>r new_document_ptr" and
+ h': "h \<turnstile> create_document \<rightarrow>\<^sub>h h'" and
+ "\<not>(is_strongly_dom_component_safe {} {cast new_document_ptr} h h')"
+ by(code_simp, auto simp add: equal_eq List.member_def)+
+ then show ?thesis
+ by blast
+qed
+
+locale l_get_dom_component_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ to_tree_order get_parent get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs
+ get_ancestors get_ancestors_locs get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id
+ get_elements_by_class_name get_elements_by_tag_name +
+ l_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M create_document
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and to_tree_order :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_dom_component :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and is_strongly_dom_component_safe ::
+ "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ and is_weakly_dom_component_safe ::
+ "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ and get_root_node :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_ancestors :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_ancestors_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_element_by_id ::
+ "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog"
+ and get_elements_by_class_name ::
+ "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr list) prog"
+ and get_elements_by_tag_name ::
+ "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr list) prog"
+ and create_document :: "((_) heap, exception, (_) document_ptr) prog"
+begin
+
+lemma create_document_is_weakly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> create_document \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<noteq> cast |h \<turnstile> create_document|\<^sub>r"
+ shows "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'"
+ using assms
+ apply(auto simp add: create_document_def)[1]
+ by (metis assms(4) assms(5) is_OK_returns_heap_I local.create_document_def new_document_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ select_result_I)
+
+lemma create_document_is_weakly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> create_document \<rightarrow>\<^sub>r result"
+ assumes "h \<turnstile> create_document \<rightarrow>\<^sub>h h'"
+ shows "is_weakly_dom_component_safe {} {cast result} h h'"
+proof -
+ have "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast result|}"
+ using assms(4) assms(5) local.create_document_def new_document_new_ptr by auto
+ moreover have "result |\<notin>| document_ptr_kinds h"
+ using assms(4) assms(5) local.create_document_def new_document_ptr_not_in_heap by auto
+ ultimately show ?thesis
+ using assms
+ apply(auto simp add: is_weakly_dom_component_safe_def Let_def local.create_document_def
+ new_document_ptr_not_in_heap)[1]
+ by (metis \<open>result |\<notin>| document_ptr_kinds h\<close> document_ptr_kinds_commutes new_document_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t)
+qed
+end
+
+interpretation i_get_dom_component_create_document?: l_get_dom_component_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr heap_is_wellformed parent_child_rel type_wf known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_element_by_id get_elements_by_class_name get_elements_by_tag_name create_document
+ by(auto simp add: l_get_dom_component_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>insert\_before\<close>
+
+lemma insert_before_unsafe: "\<not>(\<forall>(h
+ :: ('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap
+ ) h' ptr child. heap_is_wellformed h \<longrightarrow> type_wf h \<longrightarrow> known_ptrs h \<longrightarrow>
+h \<turnstile> insert_before ptr child None \<rightarrow>\<^sub>h h' \<longrightarrow> is_weakly_dom_component_safe {ptr, cast child} {} h h')"
+proof -
+ obtain h document_ptr e1 e2 where h: "Inr ((document_ptr, e1, e2), h) = (Heap (fmempty)
+ :: ('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap
+ ) \<turnstile> (do {
+ document_ptr \<leftarrow> create_document;
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ return (document_ptr, e1, e2)
+ })"
+ by(code_simp, auto simp add: equal_eq List.member_def)+
+ then obtain h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ h': "h \<turnstile> insert_before (cast e1) (cast e2) None \<rightarrow>\<^sub>h h'" and
+ "\<not>(is_weakly_dom_component_safe {cast e1, cast e2} {} h h')"
+ by(code_simp, auto simp add: equal_eq List.member_def)+
+ then show ?thesis
+ by auto
+qed
+
+lemma insert_before_unsafe2: "\<not>(\<forall>(h
+ :: ('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap
+ ) h' ptr child ref. heap_is_wellformed h \<longrightarrow> type_wf h \<longrightarrow> known_ptrs h \<longrightarrow>
+h \<turnstile> insert_before ptr child (Some ref) \<rightarrow>\<^sub>h h' \<longrightarrow>
+is_weakly_dom_component_safe {ptr, cast child, cast ref} {} h h')"
+proof -
+ obtain h document_ptr e1 e2 e3 where h: "Inr ((document_ptr, e1, e2, e3), h) = (Heap (fmempty)
+ :: ('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap
+ ) \<turnstile> (do {
+ document_ptr \<leftarrow> create_document;
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ e3 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast e1) (cast e2);
+ return (document_ptr, e1, e2, e3)
+ })"
+ by(code_simp, auto simp add: equal_eq List.member_def)+
+ then obtain h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ h': "h \<turnstile> insert_before (cast e1) (cast e3) (Some (cast e2)) \<rightarrow>\<^sub>h h'" and
+ "\<not>(is_weakly_dom_component_safe {cast e1, cast e3, cast e2} {} h h')"
+ apply(code_simp)
+ apply(clarify)
+ by(code_simp, auto simp add: equal_eq List.member_def)+
+ then show ?thesis
+ by fast
+qed
+
+
+lemma append_child_unsafe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap" and
+ h' and ptr and child where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> append_child ptr child \<rightarrow>\<^sub>h h'" and
+ "\<not> is_weakly_dom_component_safe {ptr, cast child} {} h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap"
+ let ?P = "do {
+ document_ptr \<leftarrow> create_document;
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ return (e1, e2)
+ }"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?e1 = "fst |?h0 \<turnstile> ?P|\<^sub>r"
+ let ?e2 = "snd |?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and ptr="cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ?e1" and child="cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ?e2"])
+ by code_simp+
+qed
+
+
+subsubsection \<open>get\_owner\_document\<close>
+
+lemma get_owner_document_unsafe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap" and
+ h' and ptr and owner_document where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<rightarrow>\<^sub>h h'" and
+ "\<not>is_weakly_dom_component_safe {ptr} {cast owner_document} h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap"
+ let ?P = "do {
+ document_ptr \<leftarrow> create_document;
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ return (document_ptr, e1)
+ }"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?document_ptr = "fst |?h0 \<turnstile> ?P|\<^sub>r"
+ let ?e1 = "snd |?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and ptr="cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ?e1" and owner_document="?document_ptr"])
+ by code_simp+
+qed
+
+end
diff --git a/thys/SC_DOM_Components/Core_DOM_SC_DOM_Components.thy b/thys/SC_DOM_Components/Core_DOM_SC_DOM_Components.thy
new file mode 100644
--- /dev/null
+++ b/thys/SC_DOM_Components/Core_DOM_SC_DOM_Components.thy
@@ -0,0 +1,3758 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section \<open>Core SC DOM Components II\<close>
+theory Core_DOM_SC_DOM_Components
+ imports
+ Core_DOM_DOM_Components
+begin
+declare [[smt_timeout=2400]]
+
+section \<open>Scope Components\<close>
+
+subsection \<open>Definition\<close>
+
+locale l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_disconnected_nodes_defs get_disconnected_nodes get_disconnected_nodes_locs +
+ l_get_owner_document_defs get_owner_document +
+ l_to_tree_order_defs to_tree_order
+ for get_owner_document :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and to_tree_order :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+begin
+definition a_get_scdom_component :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ where
+ "a_get_scdom_component ptr = do {
+ document \<leftarrow> get_owner_document ptr;
+ disc_nodes \<leftarrow> get_disconnected_nodes document;
+ tree_order \<leftarrow> to_tree_order (cast document);
+ disconnected_tree_orders \<leftarrow> map_M (to_tree_order \<circ> cast) disc_nodes;
+ return (tree_order @ (concat disconnected_tree_orders))
+ }"
+
+definition a_is_strongly_scdom_component_safe ::
+ "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ where
+ "a_is_strongly_scdom_component_safe S\<^sub>a\<^sub>r\<^sub>g S\<^sub>r\<^sub>e\<^sub>s\<^sub>u\<^sub>l\<^sub>t h h' = (
+ let removed_pointers = fset (object_ptr_kinds h) - fset (object_ptr_kinds h') in
+ let added_pointers = fset (object_ptr_kinds h') - fset (object_ptr_kinds h) in
+ let arg_components =
+ (\<Union>ptr \<in> (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_scdom_component ptr|\<^sub>r) \<inter>
+ fset (object_ptr_kinds h). set |h \<turnstile> a_get_scdom_component ptr|\<^sub>r) in
+ let arg_components' =
+ (\<Union>ptr \<in> (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_scdom_component ptr|\<^sub>r) \<inter>
+ fset (object_ptr_kinds h'). set |h' \<turnstile> a_get_scdom_component ptr|\<^sub>r) in
+ removed_pointers \<subseteq> arg_components \<and>
+ added_pointers \<subseteq> arg_components' \<and>
+ S\<^sub>r\<^sub>e\<^sub>s\<^sub>u\<^sub>l\<^sub>t \<subseteq> arg_components' \<and>
+ (\<forall>outside_ptr \<in> fset (object_ptr_kinds h) \<inter> fset (object_ptr_kinds h') -
+ (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_scdom_component ptr|\<^sub>r). preserved (get_M outside_ptr id) h h'))"
+
+definition a_is_weakly_scdom_component_safe ::
+ "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ where
+ "a_is_weakly_scdom_component_safe S\<^sub>a\<^sub>r\<^sub>g S\<^sub>r\<^sub>e\<^sub>s\<^sub>u\<^sub>l\<^sub>t h h' = (
+ let removed_pointers = fset (object_ptr_kinds h) - fset (object_ptr_kinds h') in
+ let added_pointers = fset (object_ptr_kinds h') - fset (object_ptr_kinds h) in
+ let arg_components =
+ (\<Union>ptr \<in> (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_scdom_component ptr|\<^sub>r) \<inter>
+ fset (object_ptr_kinds h). set |h \<turnstile> a_get_scdom_component ptr|\<^sub>r) in
+ let arg_components' =
+ (\<Union>ptr \<in> (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_scdom_component ptr|\<^sub>r) \<inter>
+ fset (object_ptr_kinds h'). set |h' \<turnstile> a_get_scdom_component ptr|\<^sub>r) in
+ removed_pointers \<subseteq> arg_components \<and>
+ S\<^sub>r\<^sub>e\<^sub>s\<^sub>u\<^sub>l\<^sub>t \<subseteq> arg_components' \<union> added_pointers \<and>
+ (\<forall>outside_ptr \<in> fset (object_ptr_kinds h) \<inter> fset (object_ptr_kinds h') -
+ (\<Union>ptr \<in> S\<^sub>a\<^sub>r\<^sub>g. set |h \<turnstile> a_get_scdom_component ptr|\<^sub>r). preserved (get_M outside_ptr id) h h'))"
+end
+
+global_interpretation l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_owner_document get_disconnected_nodes
+ get_disconnected_nodes_locs to_tree_order
+ defines get_scdom_component = "l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_scdom_component
+get_owner_document get_disconnected_nodes to_tree_order"
+ and is_strongly_scdom_component_safe = a_is_strongly_scdom_component_safe
+ and is_weakly_scdom_component_safe = a_is_weakly_scdom_component_safe
+ .
+
+locale l_get_scdom_component_defs =
+ fixes get_scdom_component :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ fixes is_strongly_scdom_component_safe ::
+ "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ fixes is_weakly_scdom_component_safe ::
+ "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+
+
+locale l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_scdom_component_defs +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ assumes get_scdom_component_impl: "get_scdom_component = a_get_scdom_component"
+ assumes is_strongly_scdom_component_safe_impl:
+ "is_strongly_scdom_component_safe = a_is_strongly_scdom_component_safe"
+ assumes is_weakly_scdom_component_safe_impl:
+ "is_weakly_scdom_component_safe = a_is_weakly_scdom_component_safe"
+begin
+lemmas get_scdom_component_def = a_get_scdom_component_def[folded get_scdom_component_impl]
+lemmas is_strongly_scdom_component_safe_def =
+ a_is_strongly_scdom_component_safe_def[folded is_strongly_scdom_component_safe_impl]
+lemmas is_weakly_scdom_component_safe_def =
+ a_is_weakly_scdom_component_safe_def[folded is_weakly_scdom_component_safe_impl]
+end
+
+interpretation i_get_scdom_component?: l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe
+ get_owner_document get_disconnected_nodes get_disconnected_nodes_locs to_tree_order
+ by(auto simp add: l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def get_scdom_component_def
+ is_strongly_scdom_component_safe_def is_weakly_scdom_component_safe_def instances)
+declare l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+locale l_get_dom_component_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_heap_is_wellformed +
+ l_get_owner_document +
+ l_get_owner_document_wf +
+ l_get_disconnected_nodes +
+ l_to_tree_order +
+ l_known_ptr +
+ l_known_ptrs +
+ l_get_owner_document_wf_get_root_node_wf +
+ assumes known_ptr_impl: "known_ptr = DocumentClass.known_ptr"
+begin
+
+lemma known_ptr_node_or_document: "known_ptr ptr \<Longrightarrow> is_node_ptr_kind ptr \<or> is_document_ptr_kind ptr"
+ by(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ split: option.splits)
+
+lemma get_scdom_component_ptr_in_heap2:
+ assumes "h \<turnstile> ok (get_scdom_component ptr)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms get_root_node_ptr_in_heap
+ apply(auto simp add: get_scdom_component_def elim!: bind_is_OK_E3 intro!: map_M_pure_I)[1]
+ by (simp add: is_OK_returns_result_I local.get_owner_document_ptr_in_heap)
+
+lemma get_scdom_component_subset_get_dom_component:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ shows "set c \<subseteq> set sc"
+proof -
+ obtain document disc_nodes tree_order disconnected_tree_orders where
+ document: "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r document"
+ and disc_nodes: "h \<turnstile> get_disconnected_nodes document \<rightarrow>\<^sub>r disc_nodes"
+ and tree_order: "h \<turnstile> to_tree_order (cast document) \<rightarrow>\<^sub>r tree_order"
+ and disconnected_tree_orders: "h \<turnstile> map_M (to_tree_order \<circ> cast) disc_nodes \<rightarrow>\<^sub>r disconnected_tree_orders"
+ and sc: "sc = tree_order @ (concat disconnected_tree_orders)"
+ using assms(4)
+ by(auto simp add: get_scdom_component_def elim!: bind_returns_result_E
+ elim!: bind_returns_result_E2[rotated, OF get_owner_document_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF to_tree_order_pure, rotated]
+ )
+
+ obtain root_ptr where root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ and c: "h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r c"
+ using assms(5)
+ by(auto simp add: get_dom_component_def elim!: bind_returns_result_E2[rotated, OF get_root_node_pure, rotated])
+
+ show ?thesis
+ proof (cases "is_document_ptr_kind root_ptr")
+ case True
+ then have "cast document = root_ptr"
+ using get_root_node_document assms(1) assms(2) assms(3) root_ptr document
+ by (metis document_ptr_casts_commute3 returns_result_eq)
+ then have "c = tree_order"
+ using tree_order c
+ by auto
+ then show ?thesis
+ by(simp add: sc)
+ next
+ case False
+ moreover have "root_ptr |\<in>| object_ptr_kinds h"
+ using assms(1) assms(2) assms(3) local.get_root_node_root_in_heap root_ptr by blast
+ ultimately have "is_node_ptr_kind root_ptr"
+ using assms(3) known_ptrs_known_ptr known_ptr_node_or_document
+ by auto
+ then obtain root_node_ptr where root_node_ptr: "root_ptr = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node_ptr"
+ by (metis node_ptr_casts_commute3)
+ then have "h \<turnstile> get_owner_document root_ptr \<rightarrow>\<^sub>r document"
+ using get_root_node_same_owner_document
+ using assms(1) assms(2) assms(3) document root_ptr by blast
+ then have "root_node_ptr \<in> set disc_nodes"
+ using assms(1) assms(2) assms(3) disc_nodes in_disconnected_nodes_no_parent root_node_ptr
+ using local.get_root_node_same_no_parent root_ptr by blast
+ then have "c \<in> set disconnected_tree_orders"
+ using c root_node_ptr
+ using map_M_pure_E[OF disconnected_tree_orders]
+ by (metis (mono_tags, lifting) comp_apply local.to_tree_order_pure select_result_I2)
+ then show ?thesis
+ by(auto simp add: sc)
+ qed
+qed
+
+lemma get_scdom_component_ptrs_same_owner_document:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "ptr' \<in> set sc"
+ assumes "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ shows "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r owner_document"
+proof -
+ obtain document disc_nodes tree_order disconnected_tree_orders where
+ document: "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r document"
+ and disc_nodes: "h \<turnstile> get_disconnected_nodes document \<rightarrow>\<^sub>r disc_nodes"
+ and tree_order: "h \<turnstile> to_tree_order (cast document) \<rightarrow>\<^sub>r tree_order"
+ and disconnected_tree_orders: "h \<turnstile> map_M (to_tree_order \<circ> cast) disc_nodes \<rightarrow>\<^sub>r disconnected_tree_orders"
+ and sc: "sc = tree_order @ (concat disconnected_tree_orders)"
+ using assms(4)
+ by(auto simp add: get_scdom_component_def elim!: bind_returns_result_E
+ elim!: bind_returns_result_E2[rotated, OF get_owner_document_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF to_tree_order_pure, rotated]
+ )
+ show ?thesis
+ proof (cases "ptr' \<in> set tree_order")
+ case True
+ have "owner_document = document"
+ using assms(6) document by fastforce
+ then show ?thesis
+ by (metis (no_types) True assms(1) assms(2) assms(3) cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject document
+ document_ptr_casts_commute3 document_ptr_document_ptr_cast document_ptr_kinds_commutes
+ local.get_owner_document_owner_document_in_heap local.get_root_node_document
+ local.get_root_node_not_node_same local.to_tree_order_same_root node_ptr_no_document_ptr_cast tree_order)
+ next
+ case False
+ then obtain disconnected_tree_order where disconnected_tree_order:
+ "ptr' \<in> set disconnected_tree_order" and "disconnected_tree_order \<in> set disconnected_tree_orders"
+ using sc \<open>ptr' \<in> set sc\<close>
+ by auto
+ obtain root_ptr' where
+ root_ptr': "root_ptr' \<in> set disc_nodes" and
+ "h \<turnstile> to_tree_order (cast root_ptr') \<rightarrow>\<^sub>r disconnected_tree_order"
+ using map_M_pure_E2[OF disconnected_tree_orders \<open>disconnected_tree_order \<in> set disconnected_tree_orders\<close>]
+ by (metis comp_apply local.to_tree_order_pure)
+ have "\<not>(\<exists>parent \<in> fset (object_ptr_kinds h). root_ptr' \<in> set |h \<turnstile> get_child_nodes parent|\<^sub>r)"
+ using disc_nodes
+ by (meson assms(1) assms(2) assms(3) disjoint_iff_not_equal local.get_child_nodes_ok
+ local.heap_is_wellformed_children_disc_nodes_different local.known_ptrs_known_ptr notin_fset
+ returns_result_select_result root_ptr')
+ then
+ have "h \<turnstile> get_parent root_ptr' \<rightarrow>\<^sub>r None"
+ using disc_nodes
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) fmember.rep_eq local.get_parent_child_dual
+ local.get_parent_ok local.get_parent_parent_in_heap local.heap_is_wellformed_disc_nodes_in_heap
+ returns_result_select_result root_ptr' select_result_I2 split_option_ex)
+ then have "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r cast root_ptr'"
+ using \<open>h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_ptr') \<rightarrow>\<^sub>r disconnected_tree_order\<close> assms(1)
+ assms(2) assms(3) disconnected_tree_order local.get_root_node_no_parent
+ local.to_tree_order_get_root_node local.to_tree_order_ptr_in_result
+ by blast
+ then have "h \<turnstile> get_owner_document (cast root_ptr') \<rightarrow>\<^sub>r document"
+ using assms(1) assms(2) assms(3) disc_nodes local.get_owner_document_disconnected_nodes root_ptr'
+ by blast
+
+ then have "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r document"
+ using \<open>h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_ptr'\<close> assms(1) assms(2) assms(3)
+ local.get_root_node_same_owner_document
+ by blast
+ then show ?thesis
+ using assms(6) document returns_result_eq by force
+ qed
+qed
+
+lemma get_scdom_component_ptrs_same_scope_component:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "ptr' \<in> set sc"
+ shows "h \<turnstile> get_scdom_component ptr' \<rightarrow>\<^sub>r sc"
+proof -
+ obtain document disc_nodes tree_order disconnected_tree_orders where
+ document: "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r document"
+ and disc_nodes: "h \<turnstile> get_disconnected_nodes document \<rightarrow>\<^sub>r disc_nodes"
+ and tree_order: "h \<turnstile> to_tree_order (cast document) \<rightarrow>\<^sub>r tree_order"
+ and disconnected_tree_orders: "h \<turnstile> map_M (to_tree_order \<circ> cast) disc_nodes \<rightarrow>\<^sub>r disconnected_tree_orders"
+ and sc: "sc = tree_order @ (concat disconnected_tree_orders)"
+ using assms(4)
+ by(auto simp add: get_scdom_component_def elim!: bind_returns_result_E
+ elim!: bind_returns_result_E2[rotated, OF get_owner_document_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF to_tree_order_pure, rotated]
+ )
+ show ?thesis
+ proof (cases "ptr' \<in> set tree_order")
+ case True
+ then have "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r document"
+ by (metis assms(1) assms(2) assms(3) cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject document
+ document_ptr_casts_commute3 document_ptr_kinds_commutes known_ptr_node_or_document
+ local.get_owner_document_owner_document_in_heap local.get_root_node_document
+ local.get_root_node_not_node_same local.known_ptrs_known_ptr local.to_tree_order_get_root_node
+ local.to_tree_order_ptr_in_result node_ptr_no_document_ptr_cast tree_order)
+ then show ?thesis
+ using disc_nodes tree_order disconnected_tree_orders sc
+ by(auto simp add: get_scdom_component_def intro!: bind_pure_returns_result_I map_M_pure_I)
+ next
+ case False
+ then obtain disconnected_tree_order where disconnected_tree_order:
+ "ptr' \<in> set disconnected_tree_order" and "disconnected_tree_order \<in> set disconnected_tree_orders"
+ using sc \<open>ptr' \<in> set sc\<close>
+ by auto
+ obtain root_ptr' where
+ root_ptr': "root_ptr' \<in> set disc_nodes" and
+ "h \<turnstile> to_tree_order (cast root_ptr') \<rightarrow>\<^sub>r disconnected_tree_order"
+ using map_M_pure_E2[OF disconnected_tree_orders \<open>disconnected_tree_order \<in> set disconnected_tree_orders\<close>]
+ by (metis comp_apply local.to_tree_order_pure)
+ have "\<not>(\<exists>parent \<in> fset (object_ptr_kinds h). root_ptr' \<in> set |h \<turnstile> get_child_nodes parent|\<^sub>r)"
+ using disc_nodes
+ by (meson assms(1) assms(2) assms(3) disjoint_iff_not_equal local.get_child_nodes_ok
+ local.heap_is_wellformed_children_disc_nodes_different local.known_ptrs_known_ptr notin_fset
+ returns_result_select_result root_ptr')
+ then
+ have "h \<turnstile> get_parent root_ptr' \<rightarrow>\<^sub>r None"
+ using disc_nodes
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) fmember.rep_eq
+ local.get_parent_child_dual local.get_parent_ok local.get_parent_parent_in_heap
+ local.heap_is_wellformed_disc_nodes_in_heap returns_result_select_result root_ptr'
+ select_result_I2 split_option_ex)
+ then have "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r cast root_ptr'"
+ using \<open>h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_ptr') \<rightarrow>\<^sub>r disconnected_tree_order\<close> assms(1)
+ assms(2) assms(3) disconnected_tree_order local.get_root_node_no_parent
+ local.to_tree_order_get_root_node local.to_tree_order_ptr_in_result
+ by blast
+ then have "h \<turnstile> get_owner_document (cast root_ptr') \<rightarrow>\<^sub>r document"
+ using assms(1) assms(2) assms(3) disc_nodes local.get_owner_document_disconnected_nodes root_ptr'
+ by blast
+
+ then have "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r document"
+ using \<open>h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_ptr'\<close> assms(1) assms(2) assms(3)
+ local.get_root_node_same_owner_document
+ by blast
+ then show ?thesis
+ using disc_nodes tree_order disconnected_tree_orders sc
+ by(auto simp add: get_scdom_component_def intro!: bind_pure_returns_result_I map_M_pure_I)
+ qed
+qed
+
+lemma get_scdom_component_ok:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ shows "h \<turnstile> ok (get_scdom_component ptr)"
+ using assms
+ apply(auto simp add: get_scdom_component_def intro!: bind_is_OK_pure_I map_M_pure_I map_M_ok_I)[1]
+ using get_owner_document_ok
+ apply blast
+ apply (simp add: local.get_disconnected_nodes_ok local.get_owner_document_owner_document_in_heap)
+ apply (simp add: local.get_owner_document_owner_document_in_heap local.to_tree_order_ok)
+ using local.heap_is_wellformed_disc_nodes_in_heap local.to_tree_order_ok node_ptr_kinds_commutes
+ by blast
+
+lemma get_scdom_component_ptr_in_heap:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "ptr' \<in> set sc"
+ shows "ptr' |\<in>| object_ptr_kinds h"
+ apply(insert assms )
+ apply(auto simp add: get_scdom_component_def elim!: bind_returns_result_E2 intro!: map_M_pure_I)[1]
+ using local.to_tree_order_ptrs_in_heap apply blast
+ by (metis (no_types, lifting) assms(4) assms(5) bind_returns_result_E
+ get_scdom_component_ptrs_same_scope_component is_OK_returns_result_I get_scdom_component_def
+ local.get_owner_document_ptr_in_heap)
+
+lemma get_scdom_component_contains_get_dom_component:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "ptr' \<in> set sc"
+ obtains c where "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c" and "set c \<subseteq> set sc"
+proof -
+ have "h \<turnstile> get_scdom_component ptr' \<rightarrow>\<^sub>r sc"
+ using assms(1) assms(2) assms(3) assms(4) assms(5) get_scdom_component_ptrs_same_scope_component
+ by blast
+ then show ?thesis
+ by (meson assms(1) assms(2) assms(3) assms(5) get_scdom_component_ptr_in_heap
+ get_scdom_component_subset_get_dom_component is_OK_returns_result_E local.get_dom_component_ok that)
+qed
+
+lemma get_scdom_component_owner_document_same:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "ptr' \<in> set sc"
+ obtains owner_document where "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r owner_document" and "cast owner_document \<in> set sc"
+ using assms
+ apply(auto simp add: get_scdom_component_def elim!: bind_returns_result_E2 intro!: map_M_pure_I)[1]
+ apply (metis (no_types, lifting) assms(4) assms(5) document_ptr_casts_commute3
+ document_ptr_document_ptr_cast get_scdom_component_contains_get_dom_component
+ local.get_dom_component_ptr local.get_dom_component_root_node_same local.get_dom_component_to_tree_order
+ local.get_root_node_document local.get_root_node_not_node_same local.to_tree_order_ptr_in_result
+ local.to_tree_order_ptrs_in_heap node_ptr_no_document_ptr_cast)
+ apply(rule map_M_pure_E2)
+ apply(simp)
+ apply(simp)
+ apply(simp)
+ by (smt assms(4) assms(5) comp_apply get_scdom_component_ptr_in_heap is_OK_returns_result_E
+ local.get_owner_document_disconnected_nodes local.get_root_node_ok local.get_root_node_same_owner_document
+ local.to_tree_order_get_root_node local.to_tree_order_ptr_in_result)
+
+lemma get_scdom_component_different_owner_documents:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ assumes "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r owner_document'"
+ assumes "owner_document \<noteq> owner_document'"
+ shows "set |h \<turnstile> get_scdom_component ptr|\<^sub>r \<inter> set |h \<turnstile> get_scdom_component ptr'|\<^sub>r = {}"
+ using assms get_scdom_component_ptrs_same_owner_document
+ by (smt disjoint_iff_not_equal get_scdom_component_ok is_OK_returns_result_I
+ local.get_owner_document_ptr_in_heap returns_result_eq returns_result_select_result)
+
+
+lemma get_scdom_component_ptr:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r c"
+ shows "ptr \<in> set c"
+ using assms
+ by (meson get_scdom_component_ptr_in_heap2 get_scdom_component_subset_get_dom_component
+ is_OK_returns_result_E is_OK_returns_result_I local.get_dom_component_ok local.get_dom_component_ptr
+ subsetD)
+end
+
+locale l_get_dom_component_get_scdom_component = l_get_owner_document_defs + l_heap_is_wellformed_defs +
+ l_type_wf + l_known_ptrs + l_get_scdom_component_defs + l_get_dom_component_defs +
+ assumes get_scdom_component_subset_get_dom_component:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc \<Longrightarrow>
+h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c \<Longrightarrow> set c \<subseteq> set sc"
+ assumes get_scdom_component_ptrs_same_scope_component:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc \<Longrightarrow>
+ptr' \<in> set sc \<Longrightarrow> h \<turnstile> get_scdom_component ptr' \<rightarrow>\<^sub>r sc"
+ assumes get_scdom_component_ptrs_same_owner_document:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc \<Longrightarrow>
+ptr' \<in> set sc \<Longrightarrow> h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<Longrightarrow> h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r owner_document"
+ assumes get_scdom_component_ok:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h \<Longrightarrow>
+h \<turnstile> ok (get_scdom_component ptr)"
+ assumes get_scdom_component_ptr_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc \<Longrightarrow>
+ptr' \<in> set sc \<Longrightarrow> ptr' |\<in>| object_ptr_kinds h"
+ assumes get_scdom_component_contains_get_dom_component:
+ "(\<And>c. h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c \<Longrightarrow> set c \<subseteq> set sc \<Longrightarrow> thesis) \<Longrightarrow> heap_is_wellformed h \<Longrightarrow>
+type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc \<Longrightarrow> ptr' \<in> set sc \<Longrightarrow> thesis"
+ assumes get_scdom_component_owner_document_same:
+ "(\<And>owner_document. h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r owner_document \<Longrightarrow> cast owner_document \<in> set sc \<Longrightarrow> thesis) \<Longrightarrow>
+ heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc \<Longrightarrow>
+ptr' \<in> set sc \<Longrightarrow> thesis"
+ assumes get_scdom_component_different_owner_documents:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<Longrightarrow>
+h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r owner_document' \<Longrightarrow> owner_document \<noteq> owner_document' \<Longrightarrow>
+set |h \<turnstile> get_scdom_component ptr|\<^sub>r \<inter> set |h \<turnstile> get_scdom_component ptr'|\<^sub>r = {}"
+
+interpretation i_get_dom_component_get_scdom_component?: l_get_dom_component_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_owner_document
+ get_disconnected_nodes get_disconnected_nodes_locs to_tree_order heap_is_wellformed parent_child_rel
+ type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors
+ get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name
+ by(auto simp add: l_get_dom_component_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_dom_component_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_get_dom_component_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_dom_component_get_scdom_component_is_l_get_dom_component_get_scdom_component [instances]:
+ "l_get_dom_component_get_scdom_component get_owner_document heap_is_wellformed type_wf known_ptr
+known_ptrs get_scdom_component get_dom_component"
+ apply(auto simp add: l_get_dom_component_get_scdom_component_def l_get_dom_component_get_scdom_component_axioms_def instances)[1]
+ using get_scdom_component_subset_get_dom_component apply fast
+ using get_scdom_component_ptrs_same_scope_component apply fast
+ using get_scdom_component_ptrs_same_owner_document apply fast
+ using get_scdom_component_ok apply fast
+ using get_scdom_component_ptr_in_heap apply fast
+ using get_scdom_component_contains_get_dom_component apply blast
+ using get_scdom_component_owner_document_same apply blast
+ using get_scdom_component_different_owner_documents apply fast
+ done
+
+
+subsubsection \<open>get\_child\_nodes\<close>
+
+locale l_get_scdom_component_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma get_child_nodes_is_strongly_scdom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ assumes "child \<in> set children"
+ shows "cast child \<in> set sc \<longleftrightarrow> ptr' \<in> set sc"
+ apply(auto)[1]
+ apply (meson assms(1) assms(2) assms(3) assms(4) assms(5) assms(6) contra_subsetD
+ get_scdom_component_ptrs_same_scope_component get_scdom_component_subset_get_dom_component
+ is_OK_returns_result_E local.get_child_nodes_is_strongly_dom_component_safe local.get_dom_component_ok
+ local.get_dom_component_ptr local.heap_is_wellformed_children_in_heap node_ptr_kinds_commutes)
+ by (meson assms(1) assms(2) assms(3) assms(4) assms(5) assms(6)
+ get_scdom_component_contains_get_dom_component is_OK_returns_result_E is_OK_returns_result_I
+ get_child_nodes_is_strongly_dom_component_safe local.get_child_nodes_ptr_in_heap
+ local.get_dom_component_ok local.get_dom_component_ptr set_rev_mp)
+
+lemma get_child_nodes_is_strongly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {ptr} (cast ` set children) h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by (meson local.get_child_nodes_pure pure_returns_heap_eq)
+ then show ?thesis
+ using assms
+ apply(auto simp add: is_strongly_scdom_component_safe_def Let_def preserved_def)[1]
+ by (smt Int_absorb2 finite_set_in get_child_nodes_is_strongly_scdom_component_safe_step in_mono
+ is_OK_returns_result_I local.get_child_nodes_ptr_in_heap local.get_dom_component_ok
+ local.get_dom_component_ptr local.get_scdom_component_impl local.get_scdom_component_ok
+ local.get_scdom_component_ptr_in_heap local.get_scdom_component_subset_get_dom_component
+ returns_result_select_result subsetI)
+qed
+end
+
+interpretation i_get_scdom_component_get_child_nodes?: l_get_scdom_component_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe
+ get_dom_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_disconnected_nodes
+ get_disconnected_nodes_locs to_tree_order get_parent get_parent_locs get_child_nodes
+ get_child_nodes_locs get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_element_by_id
+ get_elements_by_class_name get_elements_by_tag_name first_in_tree_order get_attribute get_attribute_locs
+ by(auto simp add: l_get_scdom_component_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_parent\<close>
+
+locale l_get_scdom_component_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_parent_is_strongly_scdom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "h \<turnstile> get_parent ptr' \<rightarrow>\<^sub>r Some parent"
+ shows "parent \<in> set sc \<longleftrightarrow> cast ptr' \<in> set sc"
+ by (meson assms(1) assms(2) assms(3) assms(4) assms(5) contra_subsetD
+ get_scdom_component_contains_get_dom_component local.get_dom_component_ptr
+ local.get_parent_is_strongly_dom_component_safe_step)
+
+lemma get_parent_is_strongly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r Some parent"
+ assumes "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {cast node_ptr} {parent} h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by (meson local.get_parent_pure pure_returns_heap_eq)
+ then show ?thesis
+ using assms
+ apply(auto simp add: is_strongly_scdom_component_safe_def Let_def preserved_def)[1]
+ by (smt IntI finite_set_in in_mono local.get_dom_component_ok local.get_dom_component_ptr
+ local.get_parent_is_strongly_dom_component_safe_step local.get_parent_parent_in_heap
+ local.get_scdom_component_impl local.get_scdom_component_ok local.get_scdom_component_subset_get_dom_component
+ local.to_tree_order_ok local.to_tree_order_parent local.to_tree_order_ptr_in_result
+ local.to_tree_order_ptrs_in_heap returns_result_select_result)
+qed
+end
+
+interpretation i_get_scdom_component_get_parent?: l_get_scdom_component_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_disconnected_nodes
+ get_disconnected_nodes_locs to_tree_order get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_element_by_id
+ get_elements_by_class_name get_elements_by_tag_name first_in_tree_order get_attribute get_attribute_locs
+ by(auto simp add: l_get_scdom_component_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_root\_node\<close>
+
+locale l_get_scdom_component_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_root_node_is_strongly_scdom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r root"
+ shows "root \<in> set sc \<longleftrightarrow> ptr' \<in> set sc"
+ by (meson assms(1) assms(2) assms(3) assms(4) assms(5) contra_subsetD
+ get_scdom_component_contains_get_dom_component local.get_dom_component_ptr
+ local.get_root_node_is_strongly_dom_component_safe_step)
+
+lemma get_root_node_is_strongly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {ptr} {root} h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by (meson local.get_root_node_pure pure_returns_heap_eq)
+ then show ?thesis
+ using assms
+ apply(auto simp add: is_strongly_scdom_component_safe_def Let_def preserved_def)[1]
+ by (smt Int_iff finite_set_in is_OK_returns_result_I local.get_dom_component_ok
+ local.get_dom_component_ptr local.get_root_node_is_strongly_dom_component_safe_step
+ local.get_root_node_ptr_in_heap local.get_scdom_component_impl local.get_scdom_component_ok
+ local.get_scdom_component_subset_get_dom_component returns_result_select_result subset_eq)
+qed
+end
+
+interpretation i_get_scdom_component_get_root_node?: l_get_scdom_component_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_disconnected_nodes
+ get_disconnected_nodes_locs to_tree_order get_parent get_parent_locs get_child_nodes
+ get_child_nodes_locs get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_element_by_id get_elements_by_class_name get_elements_by_tag_name first_in_tree_order
+ get_attribute get_attribute_locs
+ by(auto simp add: l_get_scdom_component_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_element\_by\_id\<close>
+
+locale l_get_scdom_component_get_element_by_id\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component_get_element_by_id\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_element_by_id_is_strongly_scdom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "h \<turnstile> get_element_by_id ptr' idd \<rightarrow>\<^sub>r Some result"
+ shows "cast result \<in> set sc \<longleftrightarrow> ptr' \<in> set sc"
+ by (meson assms(1) assms(2) assms(3) assms(4) assms(5) contra_subsetD
+ get_element_by_id_is_strongly_dom_component_safe_step get_scdom_component_contains_get_dom_component
+ local.get_dom_component_ptr)
+
+lemma get_element_by_id_is_strongly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_element_by_id ptr idd \<rightarrow>\<^sub>r Some result"
+ assumes "h \<turnstile> get_element_by_id ptr idd \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {ptr} {cast result} h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by(auto simp add: preserved_def get_element_by_id_def first_in_tree_order_def
+ elim!: bind_returns_heap_E2 intro!: map_filter_M_pure bind_pure_I
+ split: option.splits list.splits)
+ have "ptr |\<in>| object_ptr_kinds h"
+ using assms(4)
+ apply(auto simp add: get_element_by_id_def)[1]
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) bind_is_OK_E is_OK_returns_result_I
+ local.first_in_tree_order_def local.to_tree_order_ptr_in_result local.to_tree_order_ptrs_in_heap)
+ obtain to where to: "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ by (meson \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) is_OK_returns_result_E
+ local.to_tree_order_ok)
+ then have "cast result \<in> set to"
+ using assms(4) local.get_element_by_id_result_in_tree_order by auto
+ obtain c where c: "h \<turnstile> a_get_scdom_component ptr \<rightarrow>\<^sub>r c"
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) local.get_scdom_component_impl
+ local.get_scdom_component_ok
+ by blast
+
+ then show ?thesis
+ using assms \<open>h = h'\<close>
+ apply(auto simp add: is_strongly_scdom_component_safe_def Let_def preserved_def
+ get_element_by_id_def first_in_tree_order_def elim!: bind_returns_result_E2
+ intro!: map_filter_M_pure bind_pure_I split: option.splits list.splits)[1]
+ by (smt IntI \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(4) finite_set_in
+ get_element_by_id_is_strongly_scdom_component_safe_step local.get_dom_component_ok
+ local.get_dom_component_ptr local.get_scdom_component_impl
+ local.get_scdom_component_subset_get_dom_component returns_result_select_result select_result_I2
+ subsetD)
+qed
+end
+
+interpretation i_get_scdom_component_get_element_by_id?: l_get_scdom_component_get_element_by_id\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_disconnected_nodes
+ get_disconnected_nodes_locs to_tree_order get_parent get_parent_locs get_child_nodes
+ get_child_nodes_locs get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_element_by_id get_elements_by_class_name get_elements_by_tag_name first_in_tree_order
+ get_attribute get_attribute_locs
+ by(auto simp add: l_get_scdom_component_get_element_by_id\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_get_element_by_id\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_elements\_by\_class\_name\<close>
+
+locale l_get_scdom_component_get_elements_by_class_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component_get_elements_by_class_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_elements_by_class_name_is_strongly_scdom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "h \<turnstile> get_elements_by_class_name ptr' idd \<rightarrow>\<^sub>r results"
+ assumes "result \<in> set results"
+ shows "cast result \<in> set sc \<longleftrightarrow> ptr' \<in> set sc"
+ by (meson assms local.get_dom_component_ptr
+ local.get_elements_by_class_name_is_strongly_dom_component_safe_step
+ local.get_scdom_component_contains_get_dom_component subsetD)
+
+
+lemma get_elements_by_class_name_is_strongly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_elements_by_class_name ptr idd \<rightarrow>\<^sub>r results"
+ assumes "h \<turnstile> get_elements_by_class_name ptr idd \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {ptr} (cast ` set results) h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by (meson local.get_elements_by_class_name_pure pure_returns_heap_eq)
+ have "ptr |\<in>| object_ptr_kinds h"
+ using assms(4)
+ apply(auto simp add: get_elements_by_class_name_def)[1]
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) bind_is_OK_E is_OK_returns_result_I
+ local.first_in_tree_order_def local.to_tree_order_ptr_in_result local.to_tree_order_ptrs_in_heap)
+ obtain to where to: "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ by (meson \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) is_OK_returns_result_E
+ local.to_tree_order_ok)
+ then have "cast ` set results \<subseteq> set to"
+ using assms(4) local.get_elements_by_class_name_result_in_tree_order by auto
+ obtain c where c: "h \<turnstile> a_get_scdom_component ptr \<rightarrow>\<^sub>r c"
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) local.get_scdom_component_impl
+ local.get_scdom_component_ok by blast
+
+ then show ?thesis
+ using assms \<open>h = h'\<close>
+ apply(auto simp add: is_strongly_scdom_component_safe_def Let_def preserved_def
+ get_element_by_id_def first_in_tree_order_def elim!: bind_returns_result_E2 intro!: map_filter_M_pure
+ bind_pure_I split: option.splits list.splits)[1]
+ by (smt IntI \<open>ptr |\<in>| object_ptr_kinds h\<close> finite_set_in
+ get_elements_by_class_name_is_strongly_scdom_component_safe_step local.get_dom_component_ok
+ local.get_dom_component_ptr local.get_scdom_component_impl
+ local.get_scdom_component_subset_get_dom_component returns_result_select_result select_result_I2 subsetD)
+qed
+end
+
+interpretation i_get_scdom_component_get_elements_by_class_name?: l_get_scdom_component_get_elements_by_class_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_disconnected_nodes
+ get_disconnected_nodes_locs to_tree_order get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_element_by_id
+ get_elements_by_class_name get_elements_by_tag_name first_in_tree_order get_attribute get_attribute_locs
+ by(auto simp add: l_get_scdom_component_get_elements_by_class_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_get_element_by_id\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_elements\_by\_tag\_name\<close>
+
+locale l_get_scdom_component_get_elements_by_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component_get_elements_by_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_elements_by_tag_name_is_strongly_scdom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "h \<turnstile> get_elements_by_tag_name ptr' idd \<rightarrow>\<^sub>r results"
+ assumes "result \<in> set results"
+ shows "cast result \<in> set sc \<longleftrightarrow> ptr' \<in> set sc"
+ by (meson assms local.get_dom_component_ptr
+ local.get_elements_by_tag_name_is_strongly_dom_component_safe_step
+ local.get_scdom_component_contains_get_dom_component subsetD)
+
+
+lemma get_elements_by_tag_name_is_strongly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_elements_by_tag_name ptr idd \<rightarrow>\<^sub>r results"
+ assumes "h \<turnstile> get_elements_by_tag_name ptr idd \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {ptr} (cast ` set results) h h'"
+proof -
+ have "h = h'"
+ using assms(5)
+ by (meson local.get_elements_by_tag_name_pure pure_returns_heap_eq)
+ have "ptr |\<in>| object_ptr_kinds h"
+ using assms(4)
+ apply(auto simp add: get_elements_by_tag_name_def)[1]
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) bind_is_OK_E is_OK_returns_result_I
+ local.first_in_tree_order_def local.to_tree_order_ptr_in_result local.to_tree_order_ptrs_in_heap)
+ obtain to where to: "h \<turnstile> to_tree_order ptr \<rightarrow>\<^sub>r to"
+ by (meson \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) is_OK_returns_result_E
+ local.to_tree_order_ok)
+ then have "cast ` set results \<subseteq> set to"
+ using assms(4) local.get_elements_by_tag_name_result_in_tree_order by auto
+ obtain c where c: "h \<turnstile> a_get_scdom_component ptr \<rightarrow>\<^sub>r c"
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) local.get_scdom_component_impl
+ local.get_scdom_component_ok by blast
+
+ then show ?thesis
+ using assms \<open>h = h'\<close>
+ apply(auto simp add: is_strongly_scdom_component_safe_def Let_def preserved_def
+ get_element_by_id_def first_in_tree_order_def elim!: bind_returns_result_E2 intro!:
+ map_filter_M_pure bind_pure_I split: option.splits list.splits)[1]
+ by (smt IntI \<open>ptr |\<in>| object_ptr_kinds h\<close> finite_set_in
+ get_elements_by_tag_name_is_strongly_scdom_component_safe_step local.get_dom_component_ok
+ local.get_dom_component_ptr local.get_scdom_component_impl
+ local.get_scdom_component_subset_get_dom_component returns_result_select_result select_result_I2
+ subsetD)
+qed
+end
+
+interpretation i_get_scdom_component_get_elements_by_tag_name?:
+ l_get_scdom_component_get_elements_by_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe
+ get_dom_component is_strongly_dom_component_safe is_weakly_dom_component_safe
+ get_disconnected_nodes get_disconnected_nodes_locs to_tree_order get_parent get_parent_locs
+ get_child_nodes get_child_nodes_locs get_root_node get_root_node_locs get_ancestors
+ get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name
+ first_in_tree_order get_attribute get_attribute_locs
+ by(auto simp add: l_get_scdom_component_get_elements_by_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_get_element_by_id\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>remove\_child\<close>
+
+locale l_get_scdom_component_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_owner_document_wf +
+ l_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs set_child_nodes set_child_nodes_locs
+ get_parent get_parent_locs get_owner_document get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs remove_child remove_child_locs remove type_wf
+ known_ptr known_ptrs heap_is_wellformed parent_child_rel
+begin
+lemma remove_child_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> remove_child ptr' child \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component ptr'|\<^sub>r"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast |h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child)|\<^sub>r)|\<^sub>r"
+ (* assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast child)|\<^sub>r" *)
+ shows "preserved (get_M ptr getter) h h'"
+proof -
+ have "ptr \<noteq> ptr'"
+ using assms(5)
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) assms(4) is_OK_returns_heap_I
+ is_OK_returns_result_E local.get_dom_component_ok local.get_dom_component_ptr
+ local.remove_child_ptr_in_heap select_result_I2)
+
+ obtain owner_document where owner_document: "h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r owner_document"
+ by (meson assms(1) assms(2) assms(3) assms(4) is_OK_returns_result_E local.get_owner_document_ok
+ local.remove_child_child_in_heap node_ptr_kinds_commutes)
+ then
+ obtain c where "h \<turnstile> get_dom_component (cast owner_document) \<rightarrow>\<^sub>r c"
+ using get_dom_component_ok owner_document assms(1) assms(2) assms(3)
+ by (meson document_ptr_kinds_commutes get_owner_document_owner_document_in_heap select_result_I)
+ then
+ have "ptr \<noteq> cast owner_document"
+ using assms(6) assms(1) assms(2) assms(3) local.get_dom_component_ptr owner_document
+ by auto
+
+ show ?thesis
+ using remove_child_writes assms(4)
+ apply(rule reads_writes_preserved2)
+ apply(auto simp add: remove_child_locs_def set_child_nodes_locs_def
+ set_disconnected_nodes_locs_def all_args_def split: option.splits)[1]
+ apply (metis \<open>ptr \<noteq> ptr'\<close> document_ptr_casts_commute3 get_M_Mdocument_preserved3)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close>
+ get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close>
+ get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply (metis \<open>ptr \<noteq> ptr'\<close> element_ptr_casts_commute3 get_M_Element_preserved8)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close>
+ get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close>
+ get_M_Mdocument_preserved3 owner_document select_result_I2)
+ done
+qed
+
+lemma remove_child_is_strongly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> remove_child ptr' child \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<notin> set |h \<turnstile> get_scdom_component ptr'|\<^sub>r"
+ (* assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast |h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child)|\<^sub>r)|\<^sub>r" *)
+ assumes "ptr \<notin> set |h \<turnstile> get_scdom_component (cast child)|\<^sub>r"
+ shows "preserved (get_M ptr getter) h h'"
+proof -
+ obtain sc where sc: "h \<turnstile> get_scdom_component ptr' \<rightarrow>\<^sub>r sc"
+ using get_scdom_component_ok
+ by (meson assms(1) assms(2) assms(3) assms(4) is_OK_returns_heap_I local.remove_child_ptr_in_heap
+ returns_result_select_result)
+
+ have "child |\<in>| node_ptr_kinds h"
+ using assms(4) remove_child_child_in_heap by blast
+ then
+ obtain child_sc where child_sc: "h \<turnstile> get_scdom_component (cast child) \<rightarrow>\<^sub>r child_sc"
+ using get_scdom_component_ok
+ by (meson assms(1) assms(2) assms(3) node_ptr_kinds_commutes select_result_I)
+ then obtain owner_document where owner_document: "h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r owner_document"
+ by (meson \<open>child |\<in>| node_ptr_kinds h\<close> assms(1) assms(2) assms(3) contra_subsetD
+ get_scdom_component_owner_document_same is_OK_returns_result_E
+ get_scdom_component_subset_get_dom_component local.get_dom_component_ok local.get_dom_component_ptr
+ node_ptr_kinds_commutes)
+ then have "h \<turnstile> get_scdom_component (cast owner_document) \<rightarrow>\<^sub>r child_sc"
+ using child_sc
+ by (smt \<open>child |\<in>| node_ptr_kinds h\<close> assms(1) assms(2) assms(3) contra_subsetD
+ get_scdom_component_subset_get_dom_component get_scdom_component_owner_document_same
+ get_scdom_component_ptrs_same_scope_component local.get_dom_component_ok local.get_dom_component_ptr
+ node_ptr_kinds_commutes returns_result_select_result select_result_I2)
+
+ have "ptr \<notin> set |h \<turnstile> get_dom_component ptr'|\<^sub>r"
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) assms(4) assms(5) contra_subsetD
+ get_scdom_component_subset_get_dom_component is_OK_returns_heap_I local.get_dom_component_ok
+ local.remove_child_ptr_in_heap returns_result_select_result sc select_result_I2)
+
+ moreover have "ptr \<notin> set |h \<turnstile> get_scdom_component (cast |h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child)|\<^sub>r)|\<^sub>r"
+ using get_scdom_component_owner_document_same get_scdom_component_ptrs_same_scope_component
+ by (metis (no_types, lifting)
+ \<open>h \<turnstile> get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document) \<rightarrow>\<^sub>r child_sc\<close> assms(6) child_sc
+ owner_document select_result_I2)
+ have "ptr \<notin> set |h \<turnstile> get_dom_component (cast |h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child)|\<^sub>r)|\<^sub>r"
+ using get_scdom_component_owner_document_same
+ by (metis (no_types, lifting)
+ \<open>h \<turnstile> get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document) \<rightarrow>\<^sub>r child_sc\<close>
+ \<open>ptr \<notin> set |h \<turnstile> get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r |h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child)|\<^sub>r)|\<^sub>r\<close>
+ assms(1) assms(2) assms(3) contra_subsetD document_ptr_kinds_commutes get_scdom_component_subset_get_dom_component
+ is_OK_returns_result_E local.get_dom_component_ok local.get_owner_document_owner_document_in_heap owner_document
+ select_result_I2)
+ ultimately show ?thesis
+ using assms(1) assms(2) assms(3) assms(4) remove_child_is_component_unsafe by blast
+qed
+
+
+
+lemma remove_child_is_strongly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {ptr, cast child} {} h h'"
+proof -
+ obtain owner_document children_h h2 disconnected_nodes_h where
+ owner_document: "h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r owner_document" and
+ children_h: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children_h" and
+ child_in_children_h: "child \<in> set children_h" and
+ disconnected_nodes_h: "h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disconnected_nodes_h" and
+ h2: "h \<turnstile> set_disconnected_nodes owner_document (child # disconnected_nodes_h) \<rightarrow>\<^sub>h h2" and
+ h': "h2 \<turnstile> set_child_nodes ptr (remove1 child children_h) \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ apply(auto simp add: remove_child_def elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_child_nodes_pure] split: if_splits)[1]
+ using pure_returns_heap_eq by fastforce
+
+ have object_ptr_kinds_eq3: "object_ptr_kinds h = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF remove_child_writes assms(4)])
+ unfolding remove_child_locs_def
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_eq: "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ unfolding object_ptr_kinds_M_defs by simp
+ then have object_ptr_kinds_eq2: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ using select_result_eq by force
+ then have node_ptr_kinds_eq2: "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by auto
+ then have node_ptr_kinds_eq3: "node_ptr_kinds h = node_ptr_kinds h'"
+ using node_ptr_kinds_M_eq by auto
+ have document_ptr_kinds_eq2: "|h \<turnstile> document_ptr_kinds_M|\<^sub>r = |h' \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq2 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3: "document_ptr_kinds h = document_ptr_kinds h'"
+ using document_ptr_kinds_M_eq by auto
+ have children_eq:
+ "\<And>ptr' children. ptr \<noteq> ptr' \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ apply(rule reads_writes_preserved[OF get_child_nodes_reads remove_child_writes assms(4)])
+ unfolding remove_child_locs_def
+ using set_disconnected_nodes_get_child_nodes set_child_nodes_get_child_nodes_different_pointers
+ by fast
+ then have children_eq2:
+ "\<And>ptr' children. ptr \<noteq> ptr' \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq: "\<And>document_ptr disconnected_nodes. document_ptr \<noteq> owner_document
+ \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disconnected_nodes
+ = h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disconnected_nodes"
+ apply(rule reads_writes_preserved[OF get_disconnected_nodes_reads remove_child_writes assms(4)])
+ unfolding remove_child_locs_def
+ using set_child_nodes_get_disconnected_nodes set_disconnected_nodes_get_disconnected_nodes_different_pointers
+ by (metis (no_types, lifting) Un_iff owner_document select_result_I2)
+ then have disconnected_nodes_eq2:
+ "\<And>document_ptr. document_ptr \<noteq> owner_document
+ \<Longrightarrow> |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children_h"
+ apply(rule reads_writes_separate_forwards[OF get_child_nodes_reads set_disconnected_nodes_writes h2 children_h] )
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+
+ have "known_ptrs h'"
+ using object_ptr_kinds_eq3 known_ptrs_preserved \<open>known_ptrs h\<close> by blast
+
+ have "known_ptr ptr"
+ using assms(3)
+ using children_h get_child_nodes_ptr_in_heap local.known_ptrs_known_ptr by blast
+ have "type_wf h2"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h2]
+ using set_disconnected_nodes_types_preserved assms(2)
+ by(auto simp add: reflp_def transp_def)
+ then have "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_child_nodes_writes h']
+ using set_child_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_h': "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r remove1 child children_h"
+ using assms(4) owner_document h2 disconnected_nodes_h children_h
+ apply(auto simp add: remove_child_def split: if_splits)[1]
+ apply(drule bind_returns_heap_E3)
+ apply(auto split: if_splits)[1]
+ apply(simp)
+ apply(auto split: if_splits)[1]
+ apply(drule bind_returns_heap_E3)
+ apply(auto)[1]
+ apply(simp)
+ apply(drule bind_returns_heap_E3)
+ apply(auto)[1]
+ apply(simp)
+ apply(drule bind_returns_heap_E4)
+ apply(auto)[1]
+ apply simp
+ using \<open>type_wf h2\<close> set_child_nodes_get_child_nodes \<open>known_ptr ptr\<close> h'
+ by blast
+
+ have disconnected_nodes_h2: "h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r child # disconnected_nodes_h"
+ using owner_document assms(4) h2 disconnected_nodes_h
+ apply (auto simp add: remove_child_def split: if_splits)[1]
+ apply(drule bind_returns_heap_E2)
+ apply(auto split: if_splits)[1]
+ apply(simp)
+ by(auto simp add: local.set_disconnected_nodes_get_disconnected_nodes split: if_splits)
+ then have disconnected_nodes_h': "h' \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r child # disconnected_nodes_h"
+ apply(rule reads_writes_separate_forwards[OF get_disconnected_nodes_reads set_child_nodes_writes h'])
+ by (simp add: set_child_nodes_get_disconnected_nodes)
+
+ moreover have "a_acyclic_heap h"
+ using assms(1) by (simp add: heap_is_wellformed_def)
+ have "parent_child_rel h' \<subseteq> parent_child_rel h"
+ proof (standard, safe)
+ fix parent child
+ assume a1: "(parent, child) \<in> parent_child_rel h'"
+ then show "(parent, child) \<in> parent_child_rel h"
+ proof (cases "parent = ptr")
+ case True
+ then show ?thesis
+ using a1 remove_child_removes_parent[OF assms(1) assms(4)] children_h children_h'
+ get_child_nodes_ptr_in_heap
+ apply(auto simp add: parent_child_rel_def object_ptr_kinds_eq )[1]
+ by (metis imageI notin_set_remove1)
+ next
+ case False
+ then show ?thesis
+ using a1
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq3 children_eq2)
+ qed
+ qed
+ then have "a_acyclic_heap h'"
+ using \<open>a_acyclic_heap h\<close> acyclic_heap_def acyclic_subset by blast
+
+ moreover have "a_all_ptrs_in_heap h"
+ using assms(1) by (simp add: heap_is_wellformed_def)
+ then have "a_all_ptrs_in_heap h'"
+ apply(auto simp add: a_all_ptrs_in_heap_def node_ptr_kinds_eq3 disconnected_nodes_eq)[1]
+ apply (metis (no_types, lifting) \<open>type_wf h'\<close> assms local.get_child_nodes_ok local.known_ptrs_known_ptr
+ local.remove_child_children_subset notin_fset object_ptr_kinds_eq3 returns_result_select_result subset_code(1))
+ apply (metis (no_types, lifting) assms(4) disconnected_nodes_eq2 disconnected_nodes_h disconnected_nodes_h'
+ document_ptr_kinds_eq3 finite_set_in local.remove_child_child_in_heap node_ptr_kinds_eq3 select_result_I2
+ set_ConsD subset_code(1))
+ done
+ moreover have "a_owner_document_valid h"
+ using assms(1) by (simp add: heap_is_wellformed_def)
+ then have "a_owner_document_valid h'"
+ apply(auto simp add: a_owner_document_valid_def object_ptr_kinds_eq3 document_ptr_kinds_eq3
+ node_ptr_kinds_eq3)[1]
+ proof -
+ fix node_ptr
+ assume 0: "\<forall>node_ptr\<in>fset (node_ptr_kinds h'). (\<exists>document_ptr. document_ptr |\<in>| document_ptr_kinds h' \<and>
+node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r) \<or> (\<exists>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h' \<and>
+node_ptr \<in> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r)"
+ and 1: "node_ptr |\<in>| node_ptr_kinds h'"
+ and 2: "\<forall>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h' \<longrightarrow> node_ptr \<notin> set |h' \<turnstile> get_child_nodes parent_ptr|\<^sub>r"
+ then show "\<exists>document_ptr. document_ptr |\<in>| document_ptr_kinds h'
+ \<and> node_ptr \<in> set |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ proof (cases "node_ptr = child")
+ case True
+ show ?thesis
+ apply(rule exI[where x=owner_document])
+ using children_eq2 disconnected_nodes_eq2 children_h children_h' disconnected_nodes_h' True
+ by (metis (no_types, lifting) get_disconnected_nodes_ptr_in_heap is_OK_returns_result_I
+ list.set_intros(1) select_result_I2)
+ next
+ case False
+ then show ?thesis
+ using 0 1 2 children_eq2 children_h children_h' disconnected_nodes_eq2 disconnected_nodes_h
+ disconnected_nodes_h'
+ apply(auto simp add: children_eq2 disconnected_nodes_eq2 dest!: select_result_I2)[1]
+ by (metis children_eq2 disconnected_nodes_eq2 finite_set_in in_set_remove1 list.set_intros(2))
+ qed
+ qed
+
+ moreover
+ {
+ have h0: "a_distinct_lists h"
+ using assms(1) by (simp add: heap_is_wellformed_def)
+ moreover have ha1: "(\<Union>x\<in>set |h \<turnstile> object_ptr_kinds_M|\<^sub>r. set |h \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>set |h \<turnstile> document_ptr_kinds_M|\<^sub>r. set |h \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ using \<open>a_distinct_lists h\<close>
+ unfolding a_distinct_lists_def
+ by(auto)
+ have ha2: "ptr |\<in>| object_ptr_kinds h"
+ using children_h get_child_nodes_ptr_in_heap by blast
+ have ha3: "child \<in> set |h \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using child_in_children_h children_h
+ by(simp)
+ have child_not_in: "\<And>document_ptr. document_ptr |\<in>| document_ptr_kinds h
+ \<Longrightarrow> child \<notin> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ using ha1 ha2 ha3
+ apply(simp)
+ using IntI by fastforce
+ moreover have "distinct |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ apply(rule select_result_I)
+ by(auto simp add: object_ptr_kinds_M_defs)
+ moreover have "distinct |h \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ apply(rule select_result_I)
+ by(auto simp add: document_ptr_kinds_M_defs)
+ ultimately have "a_distinct_lists h'"
+ proof(simp (no_asm) add: a_distinct_lists_def, safe)
+ assume 1: "a_distinct_lists h"
+ and 3: "distinct |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+
+ assume 1: "a_distinct_lists h"
+ and 3: "distinct |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ have 4: "distinct (concat ((map (\<lambda>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r) |h \<turnstile> object_ptr_kinds_M|\<^sub>r)))"
+ using 1 by(auto simp add: a_distinct_lists_def)
+ show "distinct (concat (map (\<lambda>ptr. |h' \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h')))))"
+ proof(rule distinct_concat_map_I[OF 3[unfolded object_ptr_kinds_eq2], simplified])
+ fix x
+ assume 5: "x |\<in>| object_ptr_kinds h'"
+ then have 6: "distinct |h \<turnstile> get_child_nodes x|\<^sub>r"
+ using 4 distinct_concat_map_E object_ptr_kinds_eq2 by fastforce
+ obtain children where children: "h \<turnstile> get_child_nodes x \<rightarrow>\<^sub>r children"
+ and distinct_children: "distinct children"
+ by (metis "5" "6" assms get_child_nodes_ok local.known_ptrs_known_ptr
+ object_ptr_kinds_eq3 select_result_I)
+ obtain children' where children': "h' \<turnstile> get_child_nodes x \<rightarrow>\<^sub>r children'"
+ using children children_eq children_h' by fastforce
+ then have "distinct children'"
+ proof (cases "ptr = x")
+ case True
+ then show ?thesis
+ using children distinct_children children_h children_h'
+ by (metis children' distinct_remove1 returns_result_eq)
+ next
+ case False
+ then show ?thesis
+ using children distinct_children children_eq[OF False]
+ using children' distinct_lists_children h0
+ using select_result_I2 by fastforce
+ qed
+
+ then show "distinct |h' \<turnstile> get_child_nodes x|\<^sub>r"
+ using children' by(auto simp add: )
+ next
+ fix x y
+ assume 5: "x |\<in>| object_ptr_kinds h'" and 6: "y |\<in>| object_ptr_kinds h'" and 7: "x \<noteq> y"
+ obtain children_x where children_x: "h \<turnstile> get_child_nodes x \<rightarrow>\<^sub>r children_x"
+ by (metis "5" assms get_child_nodes_ok is_OK_returns_result_E
+ local.known_ptrs_known_ptr object_ptr_kinds_eq3)
+ obtain children_y where children_y: "h \<turnstile> get_child_nodes y \<rightarrow>\<^sub>r children_y"
+ by (metis "6" assms get_child_nodes_ok is_OK_returns_result_E
+ local.known_ptrs_known_ptr object_ptr_kinds_eq3)
+ obtain children_x' where children_x': "h' \<turnstile> get_child_nodes x \<rightarrow>\<^sub>r children_x'"
+ using children_eq children_h' children_x by fastforce
+ obtain children_y' where children_y': "h' \<turnstile> get_child_nodes y \<rightarrow>\<^sub>r children_y'"
+ using children_eq children_h' children_y by fastforce
+ have "distinct (concat (map (\<lambda>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r) |h \<turnstile> object_ptr_kinds_M|\<^sub>r))"
+ using h0 by(auto simp add: a_distinct_lists_def)
+ then have 8: "set children_x \<inter> set children_y = {}"
+ using "7" assms(1) children_x children_y local.heap_is_wellformed_one_parent by blast
+ have "set children_x' \<inter> set children_y' = {}"
+ proof (cases "ptr = x")
+ case True
+ then have "ptr \<noteq> y"
+ by(simp add: 7)
+ have "children_x' = remove1 child children_x"
+ using children_h children_h' children_x children_x' True returns_result_eq by fastforce
+ moreover have "children_y' = children_y"
+ using children_y children_y' children_eq[OF \<open>ptr \<noteq> y\<close>] by auto
+ ultimately show ?thesis
+ using 8 set_remove1_subset by fastforce
+ next
+ case False
+ then show ?thesis
+ proof (cases "ptr = y")
+ case True
+ have "children_y' = remove1 child children_y"
+ using children_h children_h' children_y children_y' True returns_result_eq by fastforce
+ moreover have "children_x' = children_x"
+ using children_x children_x' children_eq[OF \<open>ptr \<noteq> x\<close>] by auto
+ ultimately show ?thesis
+ using 8 set_remove1_subset by fastforce
+ next
+ case False
+ have "children_x' = children_x"
+ using children_x children_x' children_eq[OF \<open>ptr \<noteq> x\<close>] by auto
+ moreover have "children_y' = children_y"
+ using children_y children_y' children_eq[OF \<open>ptr \<noteq> y\<close>] by auto
+ ultimately show ?thesis
+ using 8 by simp
+ qed
+ qed
+ then show "set |h' \<turnstile> get_child_nodes x|\<^sub>r \<inter> set |h' \<turnstile> get_child_nodes y|\<^sub>r = {}"
+ using children_x' children_y'
+ by (metis (no_types, lifting) select_result_I2)
+ qed
+ next
+ assume 2: "distinct |h \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ then have 4: "distinct (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ by simp
+ have 3: "distinct (concat (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h')))))"
+ using h0
+ by(simp add: a_distinct_lists_def document_ptr_kinds_eq3)
+
+ show "distinct (concat (map (\<lambda>document_ptr. |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h')))))"
+ proof(rule distinct_concat_map_I[OF 4[unfolded document_ptr_kinds_eq3]])
+ fix x
+ assume 4: "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ have 5: "distinct |h \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using distinct_lists_disconnected_nodes[OF h0] 4 get_disconnected_nodes_ok
+ by (simp add: assms document_ptr_kinds_eq3 select_result_I)
+ show "distinct |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ proof (cases "x = owner_document")
+ case True
+ have "child \<notin> set |h \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using child_not_in document_ptr_kinds_eq2 "4" by fastforce
+ moreover have "|h' \<turnstile> get_disconnected_nodes x|\<^sub>r = child # |h \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using disconnected_nodes_h' disconnected_nodes_h unfolding True
+ by(simp)
+ ultimately show ?thesis
+ using 5 unfolding True
+ by simp
+ next
+ case False
+ show ?thesis
+ using "5" False disconnected_nodes_eq2 by auto
+ qed
+ next
+ fix x y
+ assume 4: "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ and 5: "y \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))" and "x \<noteq> y"
+ obtain disc_nodes_x where disc_nodes_x: "h \<turnstile> get_disconnected_nodes x \<rightarrow>\<^sub>r disc_nodes_x"
+ using 4 get_disconnected_nodes_ok[OF \<open>type_wf h\<close>, of x] document_ptr_kinds_eq2
+ by auto
+ obtain disc_nodes_y where disc_nodes_y: "h \<turnstile> get_disconnected_nodes y \<rightarrow>\<^sub>r disc_nodes_y"
+ using 5 get_disconnected_nodes_ok[OF \<open>type_wf h\<close>, of y] document_ptr_kinds_eq2
+ by auto
+ obtain disc_nodes_x' where disc_nodes_x': "h' \<turnstile> get_disconnected_nodes x \<rightarrow>\<^sub>r disc_nodes_x'"
+ using 4 get_disconnected_nodes_ok[OF \<open>type_wf h'\<close>, of x] document_ptr_kinds_eq2
+ by auto
+ obtain disc_nodes_y' where disc_nodes_y': "h' \<turnstile> get_disconnected_nodes y \<rightarrow>\<^sub>r disc_nodes_y'"
+ using 5 get_disconnected_nodes_ok[OF \<open>type_wf h'\<close>, of y] document_ptr_kinds_eq2
+ by auto
+ have "distinct
+ (concat (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r) |h \<turnstile> document_ptr_kinds_M|\<^sub>r))"
+ using h0 by (simp add: a_distinct_lists_def)
+ then have 6: "set disc_nodes_x \<inter> set disc_nodes_y = {}"
+ using \<open>x \<noteq> y\<close> assms(1) disc_nodes_x disc_nodes_y local.heap_is_wellformed_one_disc_parent
+ by blast
+
+ have "set disc_nodes_x' \<inter> set disc_nodes_y' = {}"
+ proof (cases "x = owner_document")
+ case True
+ then have "y \<noteq> owner_document"
+ using \<open>x \<noteq> y\<close> by simp
+ then have "disc_nodes_y' = disc_nodes_y"
+ using disconnected_nodes_eq[OF \<open>y \<noteq> owner_document\<close>] disc_nodes_y disc_nodes_y'
+ by auto
+ have "disc_nodes_x' = child # disc_nodes_x"
+ using disconnected_nodes_h' disc_nodes_x disc_nodes_x' True disconnected_nodes_h returns_result_eq
+ by fastforce
+ have "child \<notin> set disc_nodes_y"
+ using child_not_in disc_nodes_y 5
+ using document_ptr_kinds_eq2 by fastforce
+ then show ?thesis
+ apply(unfold \<open>disc_nodes_x' = child # disc_nodes_x\<close> \<open>disc_nodes_y' = disc_nodes_y\<close>)
+ using 6 by auto
+ next
+ case False
+ then show ?thesis
+ proof (cases "y = owner_document")
+ case True
+ then have "disc_nodes_x' = disc_nodes_x"
+ using disconnected_nodes_eq[OF \<open>x \<noteq> owner_document\<close>] disc_nodes_x disc_nodes_x' by auto
+ have "disc_nodes_y' = child # disc_nodes_y"
+ using disconnected_nodes_h' disc_nodes_y disc_nodes_y' True disconnected_nodes_h returns_result_eq
+ by fastforce
+ have "child \<notin> set disc_nodes_x"
+ using child_not_in disc_nodes_x 4
+ using document_ptr_kinds_eq2 by fastforce
+ then show ?thesis
+ apply(unfold \<open>disc_nodes_y' = child # disc_nodes_y\<close> \<open>disc_nodes_x' = disc_nodes_x\<close>)
+ using 6 by auto
+ next
+ case False
+ have "disc_nodes_x' = disc_nodes_x"
+ using disconnected_nodes_eq[OF \<open>x \<noteq> owner_document\<close>] disc_nodes_x disc_nodes_x' by auto
+ have "disc_nodes_y' = disc_nodes_y"
+ using disconnected_nodes_eq[OF \<open>y \<noteq> owner_document\<close>] disc_nodes_y disc_nodes_y' by auto
+ then show ?thesis
+ apply(unfold \<open>disc_nodes_y' = disc_nodes_y\<close> \<open>disc_nodes_x' = disc_nodes_x\<close>)
+ using 6 by auto
+ qed
+ qed
+ then show "set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ using disc_nodes_x' disc_nodes_y' by auto
+ qed
+ next
+ fix x xa xb
+ assume 1: "xa \<in> fset (object_ptr_kinds h')"
+ and 2: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 3: "xb \<in> fset (document_ptr_kinds h')"
+ and 4: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ obtain disc_nodes where disc_nodes: "h \<turnstile> get_disconnected_nodes xb \<rightarrow>\<^sub>r disc_nodes"
+ using 3 get_disconnected_nodes_ok[OF \<open>type_wf h\<close>, of xb] document_ptr_kinds_eq2 by auto
+ obtain disc_nodes' where disc_nodes': "h' \<turnstile> get_disconnected_nodes xb \<rightarrow>\<^sub>r disc_nodes'"
+ using 3 get_disconnected_nodes_ok[OF \<open>type_wf h'\<close>, of xb] document_ptr_kinds_eq2 by auto
+
+ obtain children where children: "h \<turnstile> get_child_nodes xa \<rightarrow>\<^sub>r children"
+ by (metis "1" assms finite_set_in get_child_nodes_ok is_OK_returns_result_E
+ local.known_ptrs_known_ptr object_ptr_kinds_eq3)
+ obtain children' where children': "h' \<turnstile> get_child_nodes xa \<rightarrow>\<^sub>r children'"
+ using children children_eq children_h' by fastforce
+ have "\<And>x. x \<in> set |h \<turnstile> get_child_nodes xa|\<^sub>r \<Longrightarrow> x \<in> set |h \<turnstile> get_disconnected_nodes xb|\<^sub>r \<Longrightarrow> False"
+ using 1 3
+ apply(fold \<open> object_ptr_kinds h = object_ptr_kinds h'\<close>)
+ apply(fold \<open> document_ptr_kinds h = document_ptr_kinds h'\<close>)
+ using children disc_nodes h0 apply(auto simp add: a_distinct_lists_def)[1]
+ by (metis (no_types, lifting) h0 local.distinct_lists_no_parent select_result_I2)
+ then have 5: "\<And>x. x \<in> set children \<Longrightarrow> x \<in> set disc_nodes \<Longrightarrow> False"
+ using children disc_nodes by fastforce
+ have 6: "|h' \<turnstile> get_child_nodes xa|\<^sub>r = children'"
+ using children' by (simp add: )
+ have 7: "|h' \<turnstile> get_disconnected_nodes xb|\<^sub>r = disc_nodes'"
+ using disc_nodes' by (simp add: )
+ have "False"
+ proof (cases "xa = ptr")
+ case True
+ have "distinct children_h"
+ using children_h distinct_lists_children h0 \<open>known_ptr ptr\<close> by blast
+ have "|h' \<turnstile> get_child_nodes ptr|\<^sub>r = remove1 child children_h"
+ using children_h'
+ by(simp add: )
+ have "children = children_h"
+ using True children children_h by auto
+ show ?thesis
+ using disc_nodes' children' 5 2 4 children_h \<open>distinct children_h\<close> disconnected_nodes_h'
+ apply(auto simp add: 6 7
+ \<open>xa = ptr\<close> \<open>|h' \<turnstile> get_child_nodes ptr|\<^sub>r = remove1 child children_h\<close> \<open>children = children_h\<close>)[1]
+ by (metis (no_types, lifting) disc_nodes disconnected_nodes_eq2 disconnected_nodes_h
+ select_result_I2 set_ConsD)
+ next
+ case False
+ have "children' = children"
+ using children' children children_eq[OF False[symmetric]]
+ by auto
+ then show ?thesis
+ proof (cases "xb = owner_document")
+ case True
+ then show ?thesis
+ using disc_nodes disconnected_nodes_h disconnected_nodes_h'
+ using "2" "4" "5" "6" "7" False \<open>children' = children\<close> assms(1) child_in_children_h
+ child_parent_dual children children_h disc_nodes' get_child_nodes_ptr_in_heap
+ list.set_cases list.simps(3) option.simps(1) returns_result_eq set_ConsD
+ by (metis (no_types, hide_lams) assms)
+ next
+ case False
+ then show ?thesis
+ using "2" "4" "5" "6" "7" \<open>children' = children\<close> disc_nodes disc_nodes'
+ disconnected_nodes_eq returns_result_eq
+ by metis
+ qed
+ qed
+ then show "x \<in> {}"
+ by simp
+ qed
+ }
+
+ ultimately have "heap_is_wellformed h'"
+ using heap_is_wellformed_def by blast
+
+ show ?thesis
+ apply(auto simp add: is_strongly_scdom_component_safe_def Let_def object_ptr_kinds_eq3)[1]
+ using assms(1) assms(2) assms(3) assms(4) local.get_scdom_component_impl
+ remove_child_is_strongly_dom_component_safe_step
+ by blast
+qed
+end
+
+interpretation i_get_scdom_component_remove_child?: l_get_scdom_component_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_root_node get_root_node_locs get_ancestors
+ get_ancestors_locs get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id
+ get_elements_by_class_name get_elements_by_tag_name set_child_nodes set_child_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs remove_child remove_child_locs remove
+ by(auto simp add: l_get_scdom_component_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+
+subsubsection \<open>adopt\_node\<close>
+
+locale l_get_scdom_component_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_adopt_node_wf +
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_owner_document_wf +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma adopt_node_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> adopt_node document_ptr node_ptr \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast document_ptr)|\<^sub>r"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast node_ptr)|\<^sub>r"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast |h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)|\<^sub>r)|\<^sub>r"
+ shows "preserved (get_M ptr getter) h h'"
+proof -
+ obtain owner_document where owner_document: "h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr) \<rightarrow>\<^sub>r owner_document"
+ using assms(4) local.adopt_node_def by auto
+ then
+ obtain c where "h \<turnstile> get_dom_component (cast owner_document) \<rightarrow>\<^sub>r c"
+ using get_dom_component_ok assms(1) assms(2) assms(3) get_owner_document_owner_document_in_heap
+ by (meson document_ptr_kinds_commutes select_result_I)
+ then
+ have "ptr \<noteq> cast owner_document"
+ using assms(6) assms(1) assms(2) assms(3) local.get_dom_component_ptr owner_document
+ by (metis (no_types, lifting) assms(7) select_result_I2)
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using adopt_node_document_in_heap assms(1) assms(2) assms(3) assms(4) by auto
+ then
+ have "ptr \<noteq> cast document_ptr"
+ using assms(5)
+ using assms(1) assms(2) assms(3) local.get_dom_component_ptr get_dom_component_ok
+ by (meson document_ptr_kinds_commutes returns_result_select_result)
+
+ have "\<And>parent. |h \<turnstile> get_parent node_ptr|\<^sub>r = Some parent \<Longrightarrow> parent \<noteq> ptr"
+ by (metis assms(1) assms(2) assms(3) assms(6) is_OK_returns_result_I local.get_dom_component_ok
+ local.get_dom_component_parent_inside local.get_dom_component_ptr local.get_owner_document_ptr_in_heap
+ local.get_parent_ok node_ptr_kinds_commutes owner_document returns_result_select_result)
+
+ show ?thesis
+ using adopt_node_writes assms(4)
+ apply(rule reads_writes_preserved2)
+ apply(auto simp add: adopt_node_locs_def remove_child_locs_def set_child_nodes_locs_def set_disconnected_nodes_locs_def all_args_def)[1]
+ apply (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr\<close> get_M_Mdocument_preserved3)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close> get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply(drule \<open>\<And>parent. |h \<turnstile> get_parent node_ptr|\<^sub>r = Some parent \<Longrightarrow> parent \<noteq> ptr\<close>)[1] apply (metis element_ptr_casts_commute3 get_M_Element_preserved8 is_node_ptr_kind_none node_ptr_casts_commute3 option.case_eq_if)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close> get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr\<close> get_M_Mdocument_preserved3)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close> get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr\<close> get_M_Mdocument_preserved3)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close> get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply(drule \<open>\<And>parent. |h \<turnstile> get_parent node_ptr|\<^sub>r = Some parent \<Longrightarrow> parent \<noteq> ptr\<close>)[1] apply (metis document_ptr_casts_commute3 get_M_Mdocument_preserved3)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close> get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr\<close> get_M_Mdocument_preserved3)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close> get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr\<close> get_M_Mdocument_preserved3)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close> get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply(drule \<open>\<And>parent. |h \<turnstile> get_parent node_ptr|\<^sub>r = Some parent \<Longrightarrow> parent \<noteq> ptr\<close>)[1]
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close> get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr\<close> get_M_Mdocument_preserved3)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close> get_M_Mdocument_preserved3 owner_document select_result_I2)
+ done
+qed
+
+lemma adopt_node_is_strongly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> adopt_node document_ptr node_ptr \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<notin> set |h \<turnstile> get_scdom_component (cast document_ptr)|\<^sub>r"
+ assumes "ptr \<notin> set |h \<turnstile> get_scdom_component (cast node_ptr)|\<^sub>r"
+ shows "preserved (get_M ptr getter) h h'"
+proof -
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ by (meson assms(1) assms(2) assms(3) assms(4) is_OK_returns_heap_I local.adopt_node_document_in_heap)
+ then
+ obtain sc where sc: "h \<turnstile> get_scdom_component (cast document_ptr) \<rightarrow>\<^sub>r sc"
+ using get_scdom_component_ok
+ by (meson assms(1) assms(2) assms(3) document_ptr_kinds_commutes returns_result_select_result)
+
+ have "node_ptr |\<in>| node_ptr_kinds h"
+ using assms(4)
+ by (meson is_OK_returns_heap_I local.adopt_node_child_in_heap)
+ then
+ obtain child_sc where child_sc: "h \<turnstile> get_scdom_component (cast node_ptr) \<rightarrow>\<^sub>r child_sc"
+ using get_scdom_component_ok
+ by (meson assms(1) assms(2) assms(3) is_OK_returns_result_E node_ptr_kinds_commutes)
+
+ then obtain owner_document where owner_document: "h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r owner_document"
+ by (meson \<open>node_ptr |\<in>| node_ptr_kinds h\<close> assms(1) assms(2) assms(3) contra_subsetD
+ get_scdom_component_owner_document_same is_OK_returns_result_E
+ get_scdom_component_subset_get_dom_component local.get_dom_component_ok local.get_dom_component_ptr
+ node_ptr_kinds_commutes)
+ then have "h \<turnstile> get_scdom_component (cast owner_document) \<rightarrow>\<^sub>r child_sc"
+ using child_sc
+ by (metis (no_types, lifting) \<open>node_ptr |\<in>| node_ptr_kinds h\<close> assms(1) assms(2) assms(3)
+ get_scdom_component_owner_document_same get_scdom_component_ptrs_same_scope_component
+ get_scdom_component_subset_get_dom_component is_OK_returns_result_E local.get_dom_component_ok
+ local.get_dom_component_ptr node_ptr_kinds_commutes select_result_I2 subset_code(1))
+
+ have "ptr \<notin> set |h \<turnstile> get_dom_component (cast document_ptr)|\<^sub>r"
+ by (metis (no_types, lifting) \<open>document_ptr |\<in>| document_ptr_kinds h\<close> assms(1) assms(2) assms(3)
+ assms(5) contra_subsetD document_ptr_kinds_commutes get_scdom_component_subset_get_dom_component
+ local.get_dom_component_ok returns_result_select_result sc select_result_I2)
+
+ moreover have "ptr \<notin> set |h \<turnstile> get_dom_component (cast node_ptr)|\<^sub>r"
+ by (metis (no_types, lifting) \<open>node_ptr |\<in>| node_ptr_kinds h\<close> assms(1) assms(2) assms(3) assms(6)
+ child_sc contra_subsetD get_scdom_component_subset_get_dom_component local.get_dom_component_ok
+ node_ptr_kinds_commutes returns_result_select_result select_result_I2)
+
+ moreover have "ptr \<notin> set |h \<turnstile> get_scdom_component (cast |h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)|\<^sub>r)|\<^sub>r"
+ using get_scdom_component_owner_document_same get_scdom_component_ptrs_same_scope_component
+ by (metis (no_types, lifting)
+ \<open>h \<turnstile> get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document) \<rightarrow>\<^sub>r child_sc\<close> assms(6) child_sc
+ owner_document select_result_I2)
+ have "ptr \<notin> set |h \<turnstile> get_dom_component (cast |h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)|\<^sub>r)|\<^sub>r"
+ using get_scdom_component_owner_document_same
+ by (metis (no_types, hide_lams)
+ \<open>\<And>thesis. (\<And>owner_document. h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr) \<rightarrow>\<^sub>r owner_document \<Longrightarrow> thesis) \<Longrightarrow> thesis\<close>
+ \<open>h \<turnstile> get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document) \<rightarrow>\<^sub>r child_sc\<close>
+ \<open>ptr \<notin> set |h \<turnstile> get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r |h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)|\<^sub>r)|\<^sub>r\<close>
+ assms(1) assms(2) assms(3) contra_subsetD document_ptr_kinds_commutes get_scdom_component_subset_get_dom_component
+ is_OK_returns_result_E local.get_dom_component_ok local.get_owner_document_owner_document_in_heap owner_document
+ returns_result_eq select_result_I2)
+ ultimately show ?thesis
+ using assms(1) assms(2) assms(3) assms(4) adopt_node_is_component_unsafe
+ by blast
+qed
+
+lemma adopt_node_is_strongly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and type_wf: "type_wf h" and known_ptrs: "known_ptrs h"
+ assumes "h \<turnstile> adopt_node document_ptr child \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {cast document_ptr, cast child} {} h h'"
+proof -
+
+ obtain old_document parent_opt h2 where
+ old_document: "h \<turnstile> get_owner_document (cast child) \<rightarrow>\<^sub>r old_document"
+ and
+ parent_opt: "h \<turnstile> get_parent child \<rightarrow>\<^sub>r parent_opt"
+ and
+ h2: "h \<turnstile> (case parent_opt of Some parent \<Rightarrow> remove_child parent child | None \<Rightarrow> return ()) \<rightarrow>\<^sub>h h2"
+ and
+ h': "h2 \<turnstile> (if document_ptr \<noteq> old_document then do {
+ old_disc_nodes \<leftarrow> get_disconnected_nodes old_document;
+ set_disconnected_nodes old_document (remove1 child old_disc_nodes);
+ disc_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ set_disconnected_nodes document_ptr (child # disc_nodes)
+ } else do {
+ return ()
+ }) \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ by(auto simp add: adopt_node_def elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_parent_pure])
+
+ have object_ptr_kinds_h_eq3: "object_ptr_kinds h = object_ptr_kinds h2"
+ using h2 apply(simp split: option.splits)
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF remove_child_writes])
+ using remove_child_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h:
+ "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ unfolding object_ptr_kinds_M_defs by simp
+ then have object_ptr_kinds_eq_h: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq_h: "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+
+ have wellformed_h2: "heap_is_wellformed h2"
+ using h2 remove_child_heap_is_wellformed_preserved known_ptrs type_wf
+ by (metis (no_types, lifting) assms(1) option.case_eq_if pure_returns_heap_eq return_pure)
+ have "type_wf h2"
+ using h2 remove_child_preserves_type_wf known_ptrs type_wf
+ by (metis (no_types, lifting) assms(1) option.case_eq_if pure_returns_heap_eq return_pure)
+ have "known_ptrs h2"
+ using h2 remove_child_preserves_known_ptrs known_ptrs type_wf
+ by (metis (no_types, lifting) assms(1) option.case_eq_if pure_returns_heap_eq return_pure)
+ have "heap_is_wellformed h' \<and> known_ptrs h' \<and> type_wf h'"
+ proof(cases "document_ptr = old_document")
+ case True
+ then show ?thesis
+ using h' wellformed_h2 \<open>type_wf h2\<close> \<open>known_ptrs h2\<close> by auto
+ next
+ case False
+ then obtain h3 old_disc_nodes disc_nodes_document_ptr_h3 where
+ docs_neq: "document_ptr \<noteq> old_document" and
+ old_disc_nodes: "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r old_disc_nodes" and
+ h3: "h2 \<turnstile> set_disconnected_nodes old_document (remove1 child old_disc_nodes) \<rightarrow>\<^sub>h h3" and
+ disc_nodes_document_ptr_h3:
+ "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_document_ptr_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (child # disc_nodes_document_ptr_h3) \<rightarrow>\<^sub>h h'"
+ using h'
+ by(auto elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+
+ have object_ptr_kinds_h2_eq3: "object_ptr_kinds h2 = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h3])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h2:
+ "\<And>ptrs. h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq_h2: "|h2 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+ then have node_ptr_kinds_eq_h2: "|h2 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ then have node_ptr_kinds_eq3_h2: "node_ptr_kinds h2 = node_ptr_kinds h3"
+ by auto
+ have document_ptr_kinds_eq2_h2: "|h2 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq_h2 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3_h2: "document_ptr_kinds h2 = document_ptr_kinds h3"
+ using object_ptr_kinds_eq_h2 document_ptr_kinds_M_eq by auto
+ have children_eq_h2:
+ "\<And>ptr children. h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h2: "\<And>ptr. |h2 \<turnstile> get_child_nodes ptr|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have object_ptr_kinds_h3_eq3: "object_ptr_kinds h3 = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h3:
+ "\<And>ptrs. h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq_h3: "|h3 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+ then have node_ptr_kinds_eq_h3: "|h3 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ then have node_ptr_kinds_eq3_h3: "node_ptr_kinds h3 = node_ptr_kinds h'"
+ by auto
+ have document_ptr_kinds_eq2_h3: "|h3 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h' \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq_h3 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3_h3: "document_ptr_kinds h3 = document_ptr_kinds h'"
+ using object_ptr_kinds_eq_h3 document_ptr_kinds_M_eq by auto
+ have children_eq_h3:
+ "\<And>ptr children. h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h3: "\<And>ptr. |h3 \<turnstile> get_child_nodes ptr|\<^sub>r = |h' \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. old_document \<noteq> doc_ptr
+ \<Longrightarrow> h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. old_document \<noteq> doc_ptr
+ \<Longrightarrow> |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ obtain disc_nodes_old_document_h2 where disc_nodes_old_document_h2:
+ "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disc_nodes_old_document_h2"
+ using old_disc_nodes by blast
+ then have disc_nodes_old_document_h3:
+ "h3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r remove1 child disc_nodes_old_document_h2"
+ using h3 old_disc_nodes returns_result_eq set_disconnected_nodes_get_disconnected_nodes
+ by fastforce
+ have "distinct disc_nodes_old_document_h2"
+ using disc_nodes_old_document_h2 local.heap_is_wellformed_disconnected_nodes_distinct wellformed_h2
+ by blast
+
+
+ have "type_wf h2"
+ proof (insert h2, induct parent_opt)
+ case None
+ then show ?case
+ using type_wf by simp
+ next
+ case (Some option)
+ then show ?case
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF remove_child_writes]
+ type_wf remove_child_types_preserved
+ by (simp add: reflp_def transp_def)
+ qed
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h3]
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then have "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have "known_ptrs h3"
+ using known_ptrs local.known_ptrs_preserved object_ptr_kinds_h2_eq3 object_ptr_kinds_h_eq3 by blast
+ then have "known_ptrs h'"
+ using local.known_ptrs_preserved object_ptr_kinds_h3_eq3 by blast
+
+ have disconnected_nodes_eq_h3:
+ "\<And>doc_ptr disc_nodes. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h3:
+ "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have disc_nodes_document_ptr_h2:
+ "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_document_ptr_h3"
+ using disconnected_nodes_eq_h2 docs_neq disc_nodes_document_ptr_h3 by auto
+ have disc_nodes_document_ptr_h': "
+ h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r child # disc_nodes_document_ptr_h3"
+ using h' disc_nodes_document_ptr_h3
+ using set_disconnected_nodes_get_disconnected_nodes by blast
+
+ have document_ptr_in_heap: "document_ptr |\<in>| document_ptr_kinds h2"
+ using disc_nodes_document_ptr_h3 document_ptr_kinds_eq2_h2 get_disconnected_nodes_ok assms(1)
+ unfolding heap_is_wellformed_def
+ using disc_nodes_document_ptr_h2 get_disconnected_nodes_ptr_in_heap by blast
+ have old_document_in_heap: "old_document |\<in>| document_ptr_kinds h2"
+ using disc_nodes_old_document_h3 document_ptr_kinds_eq2_h2 get_disconnected_nodes_ok assms(1)
+ unfolding heap_is_wellformed_def
+ using get_disconnected_nodes_ptr_in_heap old_disc_nodes by blast
+
+ have "child \<in> set disc_nodes_old_document_h2"
+ proof (insert parent_opt h2, induct parent_opt)
+ case None
+ then have "h = h2"
+ by(auto)
+ moreover have "a_owner_document_valid h"
+ using assms(1) heap_is_wellformed_def by(simp add: heap_is_wellformed_def)
+ ultimately show ?case
+ using old_document disc_nodes_old_document_h2 None(1) child_parent_dual[OF assms(1)]
+ in_disconnected_nodes_no_parent assms(1) known_ptrs type_wf by blast
+ next
+ case (Some option)
+ then show ?case
+ apply(simp split: option.splits)
+ using assms(1) disc_nodes_old_document_h2 old_document remove_child_in_disconnected_nodes known_ptrs
+ by blast
+ qed
+ have "child \<notin> set (remove1 child disc_nodes_old_document_h2)"
+ using disc_nodes_old_document_h3 h3 known_ptrs wellformed_h2 \<open>distinct disc_nodes_old_document_h2\<close>
+ by auto
+ have "child \<notin> set disc_nodes_document_ptr_h3"
+ proof -
+ have "a_distinct_lists h2"
+ using heap_is_wellformed_def wellformed_h2 by blast
+ then have 0: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ |h2 \<turnstile> document_ptr_kinds_M|\<^sub>r))"
+ by(simp add: a_distinct_lists_def)
+ show ?thesis
+ using distinct_concat_map_E(1)[OF 0] \<open>child \<in> set disc_nodes_old_document_h2\<close>
+ disc_nodes_old_document_h2 disc_nodes_document_ptr_h2
+ by (meson \<open>type_wf h2\<close> docs_neq known_ptrs local.get_owner_document_disconnected_nodes
+ local.known_ptrs_preserved object_ptr_kinds_h_eq3 returns_result_eq wellformed_h2)
+ qed
+
+ have child_in_heap: "child |\<in>| node_ptr_kinds h"
+ using get_owner_document_ptr_in_heap[OF is_OK_returns_result_I[OF old_document]]
+ node_ptr_kinds_commutes by blast
+ have "a_acyclic_heap h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def)
+ have "parent_child_rel h' \<subseteq> parent_child_rel h2"
+ proof
+ fix x
+ assume "x \<in> parent_child_rel h'"
+ then show "x \<in> parent_child_rel h2"
+ using object_ptr_kinds_h2_eq3 object_ptr_kinds_h3_eq3 children_eq2_h2 children_eq2_h3
+ mem_Collect_eq object_ptr_kinds_M_eq_h3 select_result_eq split_cong
+ unfolding parent_child_rel_def
+ by(simp)
+ qed
+ then have "a_acyclic_heap h'"
+ using \<open>a_acyclic_heap h2\<close> acyclic_heap_def acyclic_subset by blast
+
+ moreover have "a_all_ptrs_in_heap h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def)
+ then have "a_all_ptrs_in_heap h3"
+ apply(auto simp add: a_all_ptrs_in_heap_def node_ptr_kinds_eq3_h2 children_eq_h2)[1]
+ apply (simp add: children_eq2_h2 object_ptr_kinds_h2_eq3 subset_code(1))
+ by (metis (no_types, lifting) \<open>child \<in> set disc_nodes_old_document_h2\<close> \<open>type_wf h2\<close>
+ disc_nodes_old_document_h2 disc_nodes_old_document_h3 disconnected_nodes_eq2_h2 document_ptr_kinds_eq3_h2
+ in_set_remove1 local.get_disconnected_nodes_ok local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_eq3_h2
+ returns_result_select_result select_result_I2 wellformed_h2)
+ then have "a_all_ptrs_in_heap h'"
+ apply(auto simp add: a_all_ptrs_in_heap_def node_ptr_kinds_eq3_h3 children_eq_h3)[1]
+ apply (simp add: children_eq2_h3 object_ptr_kinds_h3_eq3 subset_code(1))
+ by (metis (no_types, lifting) \<open>child \<in> set disc_nodes_old_document_h2\<close> disc_nodes_document_ptr_h'
+ disc_nodes_document_ptr_h2 disc_nodes_old_document_h2 disconnected_nodes_eq2_h3 document_ptr_kinds_eq3_h3
+ finite_set_in local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_eq3_h2 node_ptr_kinds_eq3_h3
+ select_result_I2 set_ConsD subset_code(1) wellformed_h2)
+
+ moreover have "a_owner_document_valid h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def)
+ then have "a_owner_document_valid h'"
+ apply(simp add: a_owner_document_valid_def node_ptr_kinds_eq_h2 node_ptr_kinds_eq3_h3
+ object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 document_ptr_kinds_eq2_h2
+ document_ptr_kinds_eq2_h3 children_eq2_h2 children_eq2_h3 )
+ by (smt disc_nodes_document_ptr_h' disc_nodes_document_ptr_h2
+ disc_nodes_old_document_h2 disc_nodes_old_document_h3
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 document_ptr_in_heap
+ document_ptr_kinds_eq3_h2 document_ptr_kinds_eq3_h3 in_set_remove1
+ list.set_intros(1) node_ptr_kinds_eq3_h2 node_ptr_kinds_eq3_h3
+ object_ptr_kinds_h2_eq3 object_ptr_kinds_h3_eq3 select_result_I2
+ set_subset_Cons subset_code(1))
+
+ have a_distinct_lists_h2: "a_distinct_lists h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def)
+ then have "a_distinct_lists h'"
+ apply(auto simp add: a_distinct_lists_def object_ptr_kinds_eq_h3 object_ptr_kinds_eq_h2
+ children_eq2_h2 children_eq2_h3)[1]
+ proof -
+ assume 1: "distinct (concat (map (\<lambda>ptr. |h' \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h')))))"
+ and 2: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h2)))))"
+ and 3: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h2). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ show "distinct (concat (map (\<lambda>document_ptr. |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h')))))"
+ proof(rule distinct_concat_map_I)
+ show "distinct (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ by(auto simp add: document_ptr_kinds_M_def )
+ next
+ fix x
+ assume a1: "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ have 4: "distinct |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using a_distinct_lists_h2 "2" a1 concat_map_all_distinct document_ptr_kinds_eq2_h2
+ document_ptr_kinds_eq2_h3
+ by fastforce
+ then show "distinct |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ proof (cases "old_document \<noteq> x")
+ case True
+ then show ?thesis
+ proof (cases "document_ptr \<noteq> x")
+ case True
+ then show ?thesis
+ using disconnected_nodes_eq2_h2[OF \<open>old_document \<noteq> x\<close>]
+ disconnected_nodes_eq2_h3[OF \<open>document_ptr \<noteq> x\<close>] 4
+ by(auto)
+ next
+ case False
+ then show ?thesis
+ using disc_nodes_document_ptr_h3 disc_nodes_document_ptr_h' 4
+ \<open>child \<notin> set disc_nodes_document_ptr_h3\<close>
+ by(auto simp add: disconnected_nodes_eq2_h2[OF \<open>old_document \<noteq> x\<close>] )
+ qed
+ next
+ case False
+ then show ?thesis
+ by (metis (no_types, hide_lams) \<open>distinct disc_nodes_old_document_h2\<close>
+ disc_nodes_old_document_h3 disconnected_nodes_eq2_h3
+ distinct_remove1 docs_neq select_result_I2)
+ qed
+ next
+ fix x y
+ assume a0: "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ and a1: "y \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ and a2: "x \<noteq> y"
+
+ moreover have 5: "set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ using 2 calculation
+ by (auto simp add: document_ptr_kinds_eq3_h2 document_ptr_kinds_eq3_h3 dest: distinct_concat_map_E(1))
+ ultimately show "set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ proof(cases "old_document = x")
+ case True
+ have "old_document \<noteq> y"
+ using \<open>x \<noteq> y\<close> \<open>old_document = x\<close> by simp
+ have "document_ptr \<noteq> x"
+ using docs_neq \<open>old_document = x\<close> by auto
+ show ?thesis
+ proof(cases "document_ptr = y")
+ case True
+ then show ?thesis
+ using 5 True select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3] \<open>old_document = x\<close>
+ by (metis (no_types, lifting) \<open>child \<notin> set (remove1 child disc_nodes_old_document_h2)\<close>
+ \<open>document_ptr \<noteq> x\<close> disconnected_nodes_eq2_h3 disjoint_iff_not_equal
+ notin_set_remove1 set_ConsD)
+ next
+ case False
+ then show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3]
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 \<open>old_document = x\<close>
+ docs_neq \<open>old_document \<noteq> y\<close>
+ by (metis (no_types, lifting) disjoint_iff_not_equal notin_set_remove1)
+ qed
+ next
+ case False
+ then show ?thesis
+ proof(cases "old_document = y")
+ case True
+ then show ?thesis
+ proof(cases "document_ptr = x")
+ case True
+ show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3]
+ \<open>old_document \<noteq> x\<close> \<open>old_document = y\<close> \<open>document_ptr = x\<close>
+ apply(simp)
+ by (metis (no_types, lifting) \<open>child \<notin> set (remove1 child disc_nodes_old_document_h2)\<close>
+ disconnected_nodes_eq2_h3 disjoint_iff_not_equal notin_set_remove1)
+ next
+ case False
+ then show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3]
+ \<open>old_document \<noteq> x\<close> \<open>old_document = y\<close> \<open>document_ptr \<noteq> x\<close>
+ by (metis (no_types, lifting) disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ disjoint_iff_not_equal docs_neq notin_set_remove1)
+ qed
+ next
+ case False
+ have "set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}"
+ by (metis DocumentMonad.ptr_kinds_M_ok DocumentMonad.ptr_kinds_M_ptr_kinds False
+ \<open>type_wf h2\<close> a1 disc_nodes_old_document_h2 document_ptr_kinds_M_def
+ document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3
+ l_ptr_kinds_M.ptr_kinds_ptr_kinds_M local.get_disconnected_nodes_ok
+ local.heap_is_wellformed_one_disc_parent returns_result_select_result
+ wellformed_h2)
+ then show ?thesis
+ proof(cases "document_ptr = x")
+ case True
+ then have "document_ptr \<noteq> y"
+ using \<open>x \<noteq> y\<close> by auto
+ have "set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}"
+ using \<open>set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}\<close>
+ by blast
+ then show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3]
+ \<open>old_document \<noteq> x\<close> \<open>old_document \<noteq> y\<close> \<open>document_ptr = x\<close> \<open>document_ptr \<noteq> y\<close>
+ \<open>child \<in> set disc_nodes_old_document_h2\<close> disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3
+ \<open>set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}\<close>
+ by(auto)
+ next
+ case False
+ then show ?thesis
+ proof(cases "document_ptr = y")
+ case True
+ have f1: "set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set disc_nodes_document_ptr_h3 = {}"
+ using 2 a1 document_ptr_in_heap document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3
+ \<open>document_ptr \<noteq> x\<close> select_result_I2[OF disc_nodes_document_ptr_h3, symmetric]
+ disconnected_nodes_eq2_h2[OF docs_neq[symmetric], symmetric]
+ by (simp add: "5" True)
+ moreover have f1:
+ "set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes old_document|\<^sub>r = {}"
+ using 2 a1 old_document_in_heap document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3
+ \<open>old_document \<noteq> x\<close>
+ by (metis (no_types, lifting) a0 distinct_concat_map_E(1) document_ptr_kinds_eq3_h2
+ document_ptr_kinds_eq3_h3 finite_fset fmember.rep_eq set_sorted_list_of_set)
+ ultimately show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_old_document_h2] \<open>old_document \<noteq> x\<close>
+ \<open>document_ptr \<noteq> x\<close> \<open>document_ptr = y\<close>
+ \<open>child \<in> set disc_nodes_old_document_h2\<close> disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3
+ by auto
+ next
+ case False
+ then show ?thesis
+ using 5
+ select_result_I2[OF disc_nodes_old_document_h2] \<open>old_document \<noteq> x\<close>
+ \<open>document_ptr \<noteq> x\<close> \<open>document_ptr \<noteq> y\<close>
+ \<open>child \<in> set disc_nodes_old_document_h2\<close>
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ by (metis \<open>set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}\<close>
+ empty_iff inf.idem)
+ qed
+ qed
+ qed
+ qed
+ qed
+ next
+ fix x xa xb
+ assume 0: "distinct (concat (map (\<lambda>ptr. |h' \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h')))))"
+ and 1: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h2)))))"
+ and 2: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h2). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 3: "xa |\<in>| object_ptr_kinds h'"
+ and 4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 5: "xb |\<in>| document_ptr_kinds h'"
+ and 6: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ then show False
+ using \<open>child \<in> set disc_nodes_old_document_h2\<close> disc_nodes_document_ptr_h'
+ disc_nodes_document_ptr_h2 disc_nodes_old_document_h2 disc_nodes_old_document_h3
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 document_ptr_kinds_eq2_h2
+ document_ptr_kinds_eq2_h3 old_document_in_heap
+ apply(auto)[1]
+ apply(cases "xb = old_document")
+ proof -
+ assume a1: "xb = old_document"
+ assume a2: "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disc_nodes_old_document_h2"
+ assume a3: "h3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r remove1 child disc_nodes_old_document_h2"
+ assume a4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ assume "document_ptr_kinds h2 = document_ptr_kinds h'"
+ assume a5: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h'). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ have f6: "old_document |\<in>| document_ptr_kinds h'"
+ using a1 \<open>xb |\<in>| document_ptr_kinds h'\<close> by blast
+ have f7: "|h2 \<turnstile> get_disconnected_nodes old_document|\<^sub>r = disc_nodes_old_document_h2"
+ using a2 by simp
+ have "x \<in> set disc_nodes_old_document_h2"
+ using f6 a3 a1 by (metis (no_types) \<open>type_wf h'\<close> \<open>x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r\<close>
+ disconnected_nodes_eq_h3 docs_neq get_disconnected_nodes_ok returns_result_eq
+ returns_result_select_result set_remove1_subset subsetCE)
+ then have "set |h' \<turnstile> get_child_nodes xa|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes xb|\<^sub>r = {}"
+ using f7 f6 a5 a4 \<open>xa |\<in>| object_ptr_kinds h'\<close>
+ by fastforce
+ then show ?thesis
+ using \<open>x \<in> set disc_nodes_old_document_h2\<close> a1 a4 f7 by blast
+ next
+ assume a1: "xb \<noteq> old_document"
+ assume a2: "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_document_ptr_h3"
+ assume a3: "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disc_nodes_old_document_h2"
+ assume a4: "xa |\<in>| object_ptr_kinds h'"
+ assume a5: "h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r child # disc_nodes_document_ptr_h3"
+ assume a6: "old_document |\<in>| document_ptr_kinds h'"
+ assume a7: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ assume a8: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ assume a9: "document_ptr_kinds h2 = document_ptr_kinds h'"
+ assume a10: "\<And>doc_ptr. old_document \<noteq> doc_ptr
+ \<Longrightarrow> |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ assume a11: "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ assume a12: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h'). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ have f13: "\<And>d. d \<notin> set |h' \<turnstile> document_ptr_kinds_M|\<^sub>r \<or> h2 \<turnstile> ok get_disconnected_nodes d"
+ using a9 \<open>type_wf h2\<close> get_disconnected_nodes_ok
+ by simp
+ then have f14: "|h2 \<turnstile> get_disconnected_nodes old_document|\<^sub>r = disc_nodes_old_document_h2"
+ using a6 a3 by simp
+ have "x \<notin> set |h2 \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ using a12 a8 a4 \<open>xb |\<in>| document_ptr_kinds h'\<close>
+ by (meson UN_I disjoint_iff_not_equal fmember.rep_eq)
+ then have "x = child"
+ using f13 a11 a10 a7 a5 a2 a1
+ by (metis (no_types, lifting) select_result_I2 set_ConsD)
+ then have "child \<notin> set disc_nodes_old_document_h2"
+ using f14 a12 a8 a6 a4
+ by (metis \<open>type_wf h'\<close> adopt_node_removes_child assms type_wf
+ get_child_nodes_ok known_ptrs local.known_ptrs_known_ptr object_ptr_kinds_h2_eq3
+ object_ptr_kinds_h3_eq3 object_ptr_kinds_h_eq3 returns_result_select_result)
+ then show ?thesis
+ using \<open>child \<in> set disc_nodes_old_document_h2\<close> by fastforce
+ qed
+ qed
+ ultimately show ?thesis
+ using \<open>type_wf h'\<close> \<open>known_ptrs h'\<close> \<open>a_owner_document_valid h'\<close> heap_is_wellformed_def by blast
+ qed
+ then have "heap_is_wellformed h'" and "known_ptrs h'" and "type_wf h'"
+ by auto
+
+ have object_ptr_kinds_eq3: "object_ptr_kinds h = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF adopt_node_writes assms(4)])
+ unfolding adopt_node_locs_def
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ remove_child_pointers_preserved
+ by (auto simp add: reflp_def transp_def split: if_splits)
+ show ?thesis
+ apply(auto simp add: is_strongly_scdom_component_safe_def Let_def object_ptr_kinds_eq3 )[1]
+ using adopt_node_is_strongly_dom_component_safe_step get_scdom_component_impl assms by blast
+qed
+end
+
+interpretation i_get_scdom_component_adopt_node?: l_get_scdom_component_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_parent get_parent_locs remove_child
+ remove_child_locs get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs adopt_node adopt_node_locs get_child_nodes get_child_nodes_locs
+ set_child_nodes set_child_nodes_locs remove to_tree_order get_root_node get_root_node_locs
+ get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name
+ by(auto simp add: l_get_scdom_component_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+
+subsubsection \<open>create\_element\<close>
+
+locale l_get_scdom_component_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_dom_component_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_create_element_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma create_element_is_strongly_scdom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<notin> set |h \<turnstile> get_scdom_component (cast document_ptr)|\<^sub>r"
+ assumes "ptr \<noteq> cast |h \<turnstile> create_element document_ptr tag|\<^sub>r"
+ shows "preserved (get_M ptr getter) h h'"
+proof -
+ obtain new_element_ptr h2 h3 disc_nodes where
+ new_element_ptr: "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr" and
+ h2: "h \<turnstile> new_element \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile>set_tag_name new_element_ptr tag \<rightarrow>\<^sub>h h3" and
+ disc_nodes: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_element_ptr # disc_nodes) \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ by(auto simp add: create_element_def elim!: bind_returns_heap_E bind_returns_heap_E2[rotated,
+ OF get_disconnected_nodes_pure, rotated])
+
+ have object_ptr_kinds_eq_h: "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ using new_element_new_ptr h2 new_element_ptr by blast
+ then have node_ptr_kinds_eq_h: "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h |\<union>| {|new_element_ptr|}"
+ apply(simp add: element_ptr_kinds_def)
+ by force
+ have character_data_ptr_kinds_eq_h: "character_data_ptr_kinds h2 = character_data_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def character_data_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h", OF set_tag_name_writes h3])
+ using set_tag_name_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+
+ have "heap_is_wellformed h'"
+ using assms(4)
+ using assms(1) assms(2) assms(3) local.create_element_preserves_wellformedness(1) by blast
+ have "type_wf h'"
+ using assms(1) assms(2) assms(3) assms(4) local.create_element_preserves_wellformedness(2) by blast
+ have "known_ptrs h'"
+ using assms(1) assms(2) assms(3) assms(4) local.create_element_preserves_wellformedness(3) by blast
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_heap_I local.create_element_document_in_heap)
+ then
+ obtain sc where sc: "h \<turnstile> get_scdom_component (cast document_ptr) \<rightarrow>\<^sub>r sc"
+ using get_scdom_component_ok
+ by (meson assms(1) assms(2) assms(3) document_ptr_kinds_commutes returns_result_select_result)
+
+ have "document_ptr |\<in>| document_ptr_kinds h'"
+ using \<open>document_ptr |\<in>| document_ptr_kinds h\<close> document_ptr_kinds_eq_h
+ using document_ptr_kinds_eq_h2 document_ptr_kinds_eq_h3 by blast
+ then
+ obtain sc' where sc': "h' \<turnstile> get_scdom_component (cast document_ptr) \<rightarrow>\<^sub>r sc'"
+ using get_scdom_component_ok
+ by (meson \<open>heap_is_wellformed h'\<close> \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> document_ptr_kinds_commutes
+ returns_result_select_result)
+
+ obtain c where c: "h \<turnstile> get_dom_component (cast document_ptr) \<rightarrow>\<^sub>r c"
+ by (meson \<open>document_ptr |\<in>| document_ptr_kinds h\<close> assms(1) assms(2) assms(3)
+ document_ptr_kinds_commutes is_OK_returns_result_E local.get_dom_component_ok)
+
+ have "set c \<subseteq> set sc"
+ using assms(1) assms(2) assms(3) c get_scdom_component_subset_get_dom_component sc by blast
+
+ have "ptr \<notin> set c"
+ using \<open>set c \<subseteq> set sc\<close> assms(5) sc
+ by auto
+ then
+ show ?thesis
+ using create_element_is_weakly_dom_component_safe
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) assms(4) assms(6) c
+ local.create_element_is_weakly_dom_component_safe_step select_result_I2)
+qed
+
+lemma create_element_is_strongly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r result"
+ assumes "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {cast document_ptr} {cast result} h h'"
+proof -
+ obtain new_element_ptr h2 h3 disc_nodes_h3 where
+ new_element_ptr: "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr" and
+ h2: "h \<turnstile> new_element \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile> set_tag_name new_element_ptr tag \<rightarrow>\<^sub>h h3" and
+ disc_nodes_h3: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_element_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'"
+ using assms(5)
+ by(auto simp add: create_element_def returns_result_heap_def
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+ then have "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr"
+ apply(auto simp add: create_element_def intro!: bind_returns_result_I)[1]
+ apply (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ apply (metis is_OK_returns_heap_E is_OK_returns_result_I local.get_disconnected_nodes_pure pure_returns_heap_eq)
+ by (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ then have "result = new_element_ptr"
+ using assms(4) by auto
+
+
+ have "new_element_ptr \<notin> set |h \<turnstile> element_ptr_kinds_M|\<^sub>r"
+ using new_element_ptr ElementMonad.ptr_kinds_ptr_kinds_M h2
+ using new_element_ptr_not_in_heap by blast
+ then have "cast new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have "cast new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+
+ have object_ptr_kinds_eq_h: "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ using new_element_new_ptr h2 new_element_ptr by blast
+ then have node_ptr_kinds_eq_h: "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h |\<union>| {|new_element_ptr|}"
+ apply(simp add: element_ptr_kinds_def)
+ by force
+ have character_data_ptr_kinds_eq_h: "character_data_ptr_kinds h2 = character_data_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def character_data_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h", OF set_tag_name_writes h3])
+ using set_tag_name_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+ have "known_ptr (cast new_element_ptr)"
+ using \<open>h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr\<close> local.create_element_known_ptr by blast
+ then
+ have "known_ptrs h2"
+ using known_ptrs_new_ptr object_ptr_kinds_eq_h \<open>known_ptrs h\<close> h2
+ by blast
+ then
+ have "known_ptrs h3"
+ using known_ptrs_preserved object_ptr_kinds_eq_h2 by blast
+ then
+ have "known_ptrs h'"
+ using known_ptrs_preserved object_ptr_kinds_eq_h3 by blast
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>ptr' children. ptr' \<noteq> cast new_element_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads h2 get_child_nodes_new_element[rotated, OF new_element_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h: "\<And>ptr'. ptr' \<noteq> cast new_element_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []"
+ using new_element_ptr h2 new_element_ptr_in_heap[OF h2 new_element_ptr]
+ new_element_is_element_ptr[OF new_element_ptr] new_element_no_child_nodes
+ by blast
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads h2 get_disconnected_nodes_new_element[OF new_element_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have disconnected_nodes_eq2_h:
+ "\<And>doc_ptr. |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_tag_name_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_tag_name_get_child_nodes)
+ then have children_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_tag_name_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_tag_name_get_disconnected_nodes)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have "type_wf h2"
+ using \<open>type_wf h\<close> new_element_types_preserved h2 by blast
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_tag_name_writes h3]
+ using set_tag_name_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then have "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_eq_h3:
+ "\<And>ptr' children. h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h3: "\<And>ptr'. |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h3:
+ "\<And>doc_ptr disc_nodes. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h3:
+ "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have disc_nodes_document_ptr_h2: "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h2 disc_nodes_h3 by auto
+ then have disc_nodes_document_ptr_h: "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h by auto
+ then have "cast new_element_ptr \<notin> set disc_nodes_h3"
+ using \<open>heap_is_wellformed h\<close>
+ using \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ a_all_ptrs_in_heap_def heap_is_wellformed_def
+ using NodeMonad.ptr_kinds_ptr_kinds_M local.heap_is_wellformed_disc_nodes_in_heap by blast
+
+
+
+ have "parent_child_rel h = parent_child_rel h'"
+ proof -
+ have "parent_child_rel h = parent_child_rel h2"
+ proof(auto simp add: parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h2"
+ by (simp add: object_ptr_kinds_eq_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq_h \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting)
+ \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2_h empty_iff empty_set image_eqI select_result_I2)
+ qed
+ also have "\<dots> = parent_child_rel h3"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h2 children_eq2_h2)
+ also have "\<dots> = parent_child_rel h'"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h3 children_eq2_h3)
+ finally show ?thesis
+ by simp
+ qed
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h'"
+ by (simp add: \<open>document_ptr |\<in>| document_ptr_kinds h\<close> document_ptr_kinds_eq_h
+ document_ptr_kinds_eq_h2 document_ptr_kinds_eq_h3)
+
+ have "known_ptr (cast document_ptr)"
+ using \<open>document_ptr |\<in>| document_ptr_kinds h\<close> assms(3) document_ptr_kinds_commutes
+ local.known_ptrs_known_ptr by blast
+ have "h \<turnstile> get_owner_document (cast document_ptr) \<rightarrow>\<^sub>r document_ptr"
+ using \<open>known_ptr (cast document_ptr)\<close> \<open>document_ptr |\<in>| document_ptr_kinds h\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, rule conjI)+
+ by(auto simp add: known_ptr_impl known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: bind_pure_returns_result_I split: option.splits)
+ have "h' \<turnstile> get_owner_document (cast document_ptr) \<rightarrow>\<^sub>r document_ptr"
+ using \<open>known_ptr (cast document_ptr)\<close> \<open>document_ptr |\<in>| document_ptr_kinds h'\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, rule conjI)+
+ by(auto simp add: known_ptr_impl known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: bind_pure_returns_result_I split: option.splits)
+
+ obtain to where to: "h \<turnstile> to_tree_order (cast document_ptr) \<rightarrow>\<^sub>r to"
+ by (meson \<open>h \<turnstile> get_owner_document (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr) \<rightarrow>\<^sub>r document_ptr\<close> assms(1)
+ assms(2) assms(3) is_OK_returns_result_E is_OK_returns_result_I local.get_owner_document_ptr_in_heap
+ local.to_tree_order_ok)
+ obtain to' where to': "h' \<turnstile> to_tree_order (cast document_ptr) \<rightarrow>\<^sub>r to'"
+ by (metis \<open>document_ptr |\<in>| document_ptr_kinds h\<close> \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> assms(1) assms(2)
+ assms(3) assms(5) document_ptr_kinds_commutes document_ptr_kinds_eq_h document_ptr_kinds_eq_h2
+ document_ptr_kinds_eq_h3 is_OK_returns_result_E local.create_element_preserves_wellformedness(1)
+ local.to_tree_order_ok)
+ have "set to = set to'"
+ proof safe
+ fix x
+ assume "x \<in> set to"
+ show "x \<in> set to'"
+ using to to'
+ using to_tree_order_parent_child_rel \<open>parent_child_rel h = parent_child_rel h'\<close>
+ by (metis \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> \<open>x \<in> set to\<close> assms(1) assms(2) assms(3) assms(5)
+ local.create_element_preserves_wellformedness(1))
+ next
+ fix x
+ assume "x \<in> set to'"
+ show "x \<in> set to"
+ using to to'
+ using to_tree_order_parent_child_rel \<open>parent_child_rel h = parent_child_rel h'\<close>
+ by (metis \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> \<open>x \<in> set to'\<close> assms(1) assms(2) assms(3) assms(5)
+ local.create_element_preserves_wellformedness(1))
+ qed
+
+ have "h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast new_element_ptr # disc_nodes_h3"
+ using h' local.set_disconnected_nodes_get_disconnected_nodes by auto
+ obtain disc_nodes_h' where disc_nodes_h': "h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h'"
+ and "cast new_element_ptr \<in> set disc_nodes_h'"
+ and "disc_nodes_h' = cast new_element_ptr # disc_nodes_h3"
+ by (simp add: \<open>h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr # disc_nodes_h3\<close>)
+
+ have "\<And>disc_ptr to to'. disc_ptr \<in> set disc_nodes_h3 \<Longrightarrow> h \<turnstile> to_tree_order (cast disc_ptr) \<rightarrow>\<^sub>r to \<Longrightarrow>
+h' \<turnstile> to_tree_order (cast disc_ptr) \<rightarrow>\<^sub>r to' \<Longrightarrow> set to = set to'"
+ proof safe
+ fix disc_ptr to to' x
+ assume "disc_ptr \<in> set disc_nodes_h3"
+ assume "h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to"
+ assume "h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'"
+ assume "x \<in> set to"
+ show "x \<in> set to'"
+ using to_tree_order_parent_child_rel \<open>parent_child_rel h = parent_child_rel h'\<close>
+ by (metis \<open>h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to\<close>
+ \<open>h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'\<close> \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> \<open>x \<in> set to\<close>
+ assms(1) assms(2) assms(3) assms(5) local.create_element_preserves_wellformedness(1))
+ next
+ fix disc_ptr to to' x
+ assume "disc_ptr \<in> set disc_nodes_h3"
+ assume "h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to"
+ assume "h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'"
+ assume "x \<in> set to'"
+ show "x \<in> set to"
+ using to_tree_order_parent_child_rel \<open>parent_child_rel h = parent_child_rel h'\<close>
+ by (metis \<open>h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to\<close>
+ \<open>h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'\<close> \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> \<open>x \<in> set to'\<close>
+ assms(1) assms(2) assms(3) assms(5) local.create_element_preserves_wellformedness(1))
+ qed
+
+ have "heap_is_wellformed h'"
+ using assms(1) assms(2) assms(3) assms(5) local.create_element_preserves_wellformedness(1)
+ by blast
+
+ have "cast new_element_ptr |\<in>| object_ptr_kinds h'"
+ using \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<in> set disc_nodes_h'\<close> \<open>heap_is_wellformed h'\<close> disc_nodes_h'
+ local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_commutes by blast
+ then
+ have "new_element_ptr |\<in>| element_ptr_kinds h'"
+ by simp
+
+ have "\<And>node_ptr. node_ptr \<in> set disc_nodes_h3 \<Longrightarrow> node_ptr |\<in>| node_ptr_kinds h'"
+ by (meson \<open>heap_is_wellformed h'\<close> h' local.heap_is_wellformed_disc_nodes_in_heap
+ local.set_disconnected_nodes_get_disconnected_nodes set_subset_Cons subset_code(1))
+
+ have "h \<turnstile> ok (map_M (to_tree_order \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) disc_nodes_h3)"
+ using assms(1) assms(2) assms(3) to_tree_order_ok
+ apply(auto intro!: map_M_ok_I)[1]
+ using disc_nodes_document_ptr_h local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_commutes
+ by blast
+ then
+ obtain disc_tree_orders where disc_tree_orders:
+ "h \<turnstile> map_M (to_tree_order \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) disc_nodes_h3 \<rightarrow>\<^sub>r disc_tree_orders"
+ by auto
+
+ have "h' \<turnstile> ok (map_M (to_tree_order \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) disc_nodes_h')"
+ apply(auto intro!: map_M_ok_I)[1]
+ apply(simp add: \<open>disc_nodes_h' = cast new_element_ptr # disc_nodes_h3\<close>)
+ using \<open>\<And>node_ptr. node_ptr \<in> set disc_nodes_h3 \<Longrightarrow> node_ptr |\<in>| node_ptr_kinds h'\<close>
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<in> set disc_nodes_h'\<close> \<open>heap_is_wellformed h'\<close> \<open>known_ptrs h'\<close>
+ \<open>type_wf h'\<close> disc_nodes_h' local.heap_is_wellformed_disc_nodes_in_heap local.to_tree_order_ok
+ node_ptr_kinds_commutes by blast
+ then
+ obtain disc_tree_orders' where disc_tree_orders':
+ "h' \<turnstile> map_M (to_tree_order \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) disc_nodes_h' \<rightarrow>\<^sub>r disc_tree_orders'"
+ by auto
+
+ have "h' \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []"
+ using \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close> children_eq_h2
+ children_eq_h3 by auto
+
+ obtain new_tree_order where new_tree_order:
+ "h' \<turnstile> to_tree_order (cast new_element_ptr) \<rightarrow>\<^sub>r new_tree_order" and
+ "new_tree_order \<in> set disc_tree_orders'"
+ using map_M_pure_E[OF disc_tree_orders' \<open>cast new_element_ptr \<in> set disc_nodes_h'\<close>]
+ by auto
+ then have "new_tree_order = [cast new_element_ptr]"
+ using \<open>h' \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto simp add: to_tree_order_def
+ dest!: bind_returns_result_E3[rotated, OF \<open>h' \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []\<close>, rotated])
+
+ obtain foo where foo: "h' \<turnstile> map_M (to_tree_order \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r)
+(cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr # disc_nodes_h3) \<rightarrow>\<^sub>r [cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr] # foo"
+ apply(auto intro!: bind_pure_returns_result_I map_M_pure_I)[1]
+ using \<open>new_tree_order = [cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr]\<close> new_tree_order apply auto[1]
+ by (smt \<open>disc_nodes_h' = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr # disc_nodes_h3\<close>
+ bind_pure_returns_result_I bind_returns_result_E2 comp_apply disc_tree_orders'
+ local.to_tree_order_pure map_M.simps(2) map_M_pure_I return_returns_result returns_result_eq)
+ then have "set (concat foo) = set (concat disc_tree_orders)"
+ apply(auto elim!: bind_returns_result_E2 intro!: map_M_pure_I)[1]
+ apply (smt \<open>\<And>to' toa disc_ptr. \<lbrakk>disc_ptr \<in> set disc_nodes_h3;
+h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r toa; h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'\<rbrakk>
+\<Longrightarrow> set toa = set to'\<close> comp_apply disc_tree_orders local.to_tree_order_pure map_M_pure_E map_M_pure_E2)
+ using \<open>\<And>to' toa disc_ptr. \<lbrakk>disc_ptr \<in> set disc_nodes_h3; h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r toa;
+h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'\<rbrakk> \<Longrightarrow> set toa = set to'\<close> comp_apply
+ disc_tree_orders local.to_tree_order_pure map_M_pure_E map_M_pure_E2
+ by smt
+
+ have "disc_tree_orders' = [cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr] # foo"
+ using foo disc_tree_orders'
+ by (simp add: \<open>disc_nodes_h' = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr # disc_nodes_h3\<close> returns_result_eq)
+
+ have "set (concat disc_tree_orders') = {cast new_element_ptr} \<union> set (concat disc_tree_orders)"
+ apply(auto simp add: \<open>disc_tree_orders' = [cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr] # foo\<close>)[1]
+ using \<open>set (concat foo) = set (concat disc_tree_orders)\<close> by auto
+
+ have "h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr) \<rightarrow>\<^sub>r to' @ concat disc_tree_orders'"
+ using \<open>h' \<turnstile> get_owner_document (cast document_ptr) \<rightarrow>\<^sub>r document_ptr\<close> disc_nodes_h' to' disc_tree_orders'
+ by(auto simp add: a_get_scdom_component_def intro!: bind_pure_returns_result_I map_M_pure_I)
+ then
+ have "set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to' \<union> set (concat disc_tree_orders')"
+ by auto
+ have "h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr) \<rightarrow>\<^sub>r to @ concat disc_tree_orders"
+ using \<open>h \<turnstile> get_owner_document (cast document_ptr) \<rightarrow>\<^sub>r document_ptr\<close> disc_nodes_document_ptr_h
+ to disc_tree_orders
+ by(auto simp add: a_get_scdom_component_def intro!: bind_pure_returns_result_I map_M_pure_I)
+ then
+ have "set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r = set to \<union> set (concat disc_tree_orders)"
+ by auto
+
+ have "{cast new_element_ptr} \<union> set |h \<turnstile> local.a_get_scdom_component (cast document_ptr)|\<^sub>r =
+set |h' \<turnstile> local.a_get_scdom_component (cast document_ptr)|\<^sub>r"
+ proof(safe)
+ show "cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr
+ \<in> set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r"
+ using \<open>h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr) \<rightarrow>\<^sub>r to' @ concat disc_tree_orders'\<close>
+ apply(auto simp add: a_get_scdom_component_def)[1]
+ by (meson \<open>\<And>thesis. (\<And>new_tree_order. \<lbrakk>h' \<turnstile> to_tree_order (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r new_tree_order;
+new_tree_order \<in> set disc_tree_orders'\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis\<close> local.to_tree_order_ptr_in_result)
+ next
+ fix x
+ assume " x \<in> set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r"
+ then
+ show "x \<in> set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r"
+ using \<open>set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to \<union>set (concat disc_tree_orders)\<close>
+ using \<open>set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to' \<union> set (concat disc_tree_orders')\<close>
+ using \<open>set to = set to'\<close>
+ using \<open>set (concat disc_tree_orders') = {cast new_element_ptr} \<union> set (concat disc_tree_orders)\<close>
+ by(auto)
+ next
+ fix x
+ assume " x \<in> set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r"
+ assume "x \<notin> set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r"
+ show "x = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr"
+ using \<open>set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to \<union> set (concat disc_tree_orders)\<close>
+ using \<open>set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to' \<union> set (concat disc_tree_orders')\<close>
+ using \<open>set to = set to'\<close>
+ using \<open>set (concat disc_tree_orders') = {cast new_element_ptr} \<union> set (concat disc_tree_orders)\<close>
+ using \<open>x \<in> set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r\<close>
+ \<open>x \<notin> set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r\<close>
+ by auto
+ qed
+
+
+ have "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ using object_ptr_kinds_eq_h object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 by auto
+ then
+ show ?thesis
+ apply(auto simp add: is_strongly_scdom_component_safe_def Let_def)[1]
+ apply(rule bexI[where x="cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr"])
+ using \<open>{cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr} \<union>
+set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r\<close>
+ apply auto[2]
+ using \<open>set to = set to'\<close> \<open>set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to \<union> set (concat disc_tree_orders)\<close> local.to_tree_order_ptr_in_result to'
+ apply auto[1]
+ using \<open>document_ptr |\<in>| document_ptr_kinds h\<close>
+ apply blast
+ apply(rule bexI[where x="cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr"])
+ using \<open>result = new_element_ptr\<close>
+ \<open>{cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr} \<union> set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r\<close> apply auto[1]
+ apply(auto)[1]
+ using \<open>set to = set to'\<close> \<open>set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to \<union> set (concat disc_tree_orders)\<close> local.to_tree_order_ptr_in_result to' apply auto[1]
+ apply (simp add: \<open>document_ptr |\<in>| document_ptr_kinds h\<close>)
+ using \<open>\<And>thesis. (\<And>new_element_ptr h2 h3 disc_nodes_h3. \<lbrakk>h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr;
+h \<turnstile> new_element \<rightarrow>\<^sub>h h2; h2 \<turnstile> set_tag_name new_element_ptr tag \<rightarrow>\<^sub>h h3;
+h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3;
+h3 \<turnstile> set_disconnected_nodes document_ptr (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis\<close>
+ new_element_ptr new_element_ptr_not_in_heap
+ apply auto[1]
+ using create_element_is_strongly_scdom_component_safe_step
+ by (smt ObjectMonad.ptr_kinds_ptr_kinds_M \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>
+ \<open>result = new_element_ptr\<close> assms(1) assms(2) assms(3) assms(4) assms(5) local.get_scdom_component_impl select_result_I2)
+qed
+end
+
+interpretation i_get_scdom_component_remove_child?: l_get_scdom_component_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs get_scdom_component
+ is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe to_tree_order get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_disconnected_nodes get_disconnected_nodes_locs
+ get_element_by_id get_elements_by_class_name get_elements_by_tag_name set_child_nodes set_child_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs remove_child remove_child_locs remove
+ by(auto simp add: l_get_scdom_component_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>create\_character\_data\<close>
+
+locale l_get_scdom_component_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_dom_component_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_create_character_data_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma create_character_data_is_strongly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<notin> set |h \<turnstile> get_scdom_component (cast document_ptr)|\<^sub>r"
+ assumes "ptr \<noteq> cast |h \<turnstile> create_character_data document_ptr text|\<^sub>r"
+ shows "preserved (get_M ptr getter) h h'"
+proof -
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_heap_I local.create_character_data_document_in_heap)
+ then
+ obtain sc where sc: "h \<turnstile> get_scdom_component (cast document_ptr) \<rightarrow>\<^sub>r sc"
+ using get_scdom_component_ok
+ by (meson assms(1) assms(2) assms(3) document_ptr_kinds_commutes returns_result_select_result)
+
+ obtain c where c: "h \<turnstile> get_dom_component (cast document_ptr) \<rightarrow>\<^sub>r c"
+ by (meson \<open>document_ptr |\<in>| document_ptr_kinds h\<close> assms(1) assms(2) assms(3)
+ document_ptr_kinds_commutes is_OK_returns_result_E local.get_dom_component_ok)
+
+ have "set c \<subseteq> set sc"
+ using assms(1) assms(2) assms(3) c get_scdom_component_subset_get_dom_component sc by blast
+
+ have "ptr \<notin> set c"
+ using \<open>set c \<subseteq> set sc\<close> assms(5) sc
+ by auto
+ then
+ show ?thesis
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) assms(4) assms(6) c
+ local.create_character_data_is_weakly_dom_component_safe_step select_result_I2)
+qed
+
+lemma create_character_data_is_strongly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r result"
+ assumes "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {cast document_ptr} {cast result} h h'"
+proof -
+
+ obtain new_character_data_ptr h2 h3 disc_nodes_h3 where
+ new_character_data_ptr: "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr" and
+ h2: "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile> set_val new_character_data_ptr text \<rightarrow>\<^sub>h h3" and
+ disc_nodes_h3: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_character_data_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'"
+ using assms(5)
+ by(auto simp add: create_character_data_def
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+ then have "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr"
+ apply(auto simp add: create_character_data_def intro!: bind_returns_result_I)[1]
+ apply (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ apply (metis is_OK_returns_heap_E is_OK_returns_result_I local.get_disconnected_nodes_pure
+ pure_returns_heap_eq)
+ by (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ then have "result = new_character_data_ptr"
+ using assms(4) by auto
+
+ have "new_character_data_ptr \<notin> set |h \<turnstile> character_data_ptr_kinds_M|\<^sub>r"
+ using new_character_data_ptr CharacterDataMonad.ptr_kinds_ptr_kinds_M h2
+ using new_character_data_ptr_not_in_heap by blast
+ then have "cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have "cast new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+
+
+
+ have object_ptr_kinds_eq_h:
+ "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using new_character_data_new_ptr h2 new_character_data_ptr by blast
+ then have node_ptr_kinds_eq_h:
+ "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have character_data_ptr_kinds_eq_h:
+ "character_data_ptr_kinds h2 = character_data_ptr_kinds h |\<union>| {|new_character_data_ptr|}"
+ apply(simp add: character_data_ptr_kinds_def)
+ by force
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_val_writes h3])
+ using set_val_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>ptr' children. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads h2 get_child_nodes_new_character_data[rotated, OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h:
+ "\<And>ptr'. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have object_ptr_kinds_eq_h:
+ "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using new_character_data_new_ptr h2 new_character_data_ptr by blast
+ then have node_ptr_kinds_eq_h:
+ "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have character_data_ptr_kinds_eq_h:
+ "character_data_ptr_kinds h2 = character_data_ptr_kinds h |\<union>| {|new_character_data_ptr|}"
+ apply(simp add: character_data_ptr_kinds_def)
+ by force
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_val_writes h3])
+ using set_val_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>ptr' children. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads h2 get_child_nodes_new_character_data[rotated, OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h: "\<And>ptr'. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []"
+ using new_character_data_ptr h2 new_character_data_ptr_in_heap[OF h2 new_character_data_ptr]
+ new_character_data_is_character_data_ptr[OF new_character_data_ptr]
+ new_character_data_no_child_nodes
+ by blast
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads h2
+ get_disconnected_nodes_new_character_data[OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have disconnected_nodes_eq2_h:
+ "\<And>doc_ptr. |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_val_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_val_get_child_nodes)
+ then have children_eq2_h2:
+ "\<And>ptr'. |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_val_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_val_get_disconnected_nodes)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have "type_wf h2"
+ using \<open>type_wf h\<close> new_character_data_types_preserved h2 by blast
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_val_writes h3]
+ using set_val_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then have "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_eq_h3:
+ "\<And>ptr' children. h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h3:
+ " \<And>ptr'. |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h3: "\<And>doc_ptr disc_nodes. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h3: "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have disc_nodes_document_ptr_h2: "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h2 disc_nodes_h3 by auto
+ then have disc_nodes_document_ptr_h: "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h by auto
+ then have "cast new_character_data_ptr \<notin> set disc_nodes_h3"
+ using \<open>heap_is_wellformed h\<close> using \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ a_all_ptrs_in_heap_def heap_is_wellformed_def
+ using NodeMonad.ptr_kinds_ptr_kinds_M local.heap_is_wellformed_disc_nodes_in_heap by blast
+
+
+
+
+
+ have "parent_child_rel h = parent_child_rel h'"
+ proof -
+ have "parent_child_rel h = parent_child_rel h2"
+ proof(auto simp add: parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h2"
+ by (simp add: object_ptr_kinds_eq_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq_h \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting) \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2_h empty_iff empty_set image_eqI select_result_I2)
+ qed
+ also have "\<dots> = parent_child_rel h3"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h2 children_eq2_h2)
+ also have "\<dots> = parent_child_rel h'"
+ by(auto simp add: parent_child_rel_def object_ptr_kinds_eq_h3 children_eq2_h3)
+ finally show ?thesis
+ by simp
+ qed
+
+ have "known_ptr (cast new_character_data_ptr)"
+ using \<open>h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr\<close>
+ create_character_data_known_ptr by blast
+ then
+ have "known_ptrs h2"
+ using known_ptrs_new_ptr object_ptr_kinds_eq_h \<open>known_ptrs h\<close> h2
+ by blast
+ then
+ have "known_ptrs h3"
+ using known_ptrs_preserved object_ptr_kinds_eq_h2 by blast
+ then
+ have "known_ptrs h'"
+ using known_ptrs_preserved object_ptr_kinds_eq_h3 by blast
+
+
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h'"
+ by (simp add: \<open>document_ptr |\<in>| document_ptr_kinds h\<close> document_ptr_kinds_eq_h
+ document_ptr_kinds_eq_h2 document_ptr_kinds_eq_h3)
+
+ have "known_ptr (cast document_ptr)"
+ using \<open>document_ptr |\<in>| document_ptr_kinds h\<close> assms(3) document_ptr_kinds_commutes
+ local.known_ptrs_known_ptr by blast
+ have "h \<turnstile> get_owner_document (cast document_ptr) \<rightarrow>\<^sub>r document_ptr"
+ using \<open>known_ptr (cast document_ptr)\<close> \<open>document_ptr |\<in>| document_ptr_kinds h\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, rule conjI)+
+ by(auto simp add: known_ptr_impl known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ intro!: bind_pure_returns_result_I split: option.splits)
+ have "h' \<turnstile> get_owner_document (cast document_ptr) \<rightarrow>\<^sub>r document_ptr"
+ using \<open>known_ptr (cast document_ptr)\<close> \<open>document_ptr |\<in>| document_ptr_kinds h'\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, rule conjI)+
+ by(auto simp add: known_ptr_impl known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ intro!: bind_pure_returns_result_I split: option.splits)
+
+ obtain to where to: "h \<turnstile> to_tree_order (cast document_ptr) \<rightarrow>\<^sub>r to"
+ by (meson \<open>h \<turnstile> get_owner_document (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr) \<rightarrow>\<^sub>r document_ptr\<close>
+ assms(1) assms(2) assms(3) is_OK_returns_result_E is_OK_returns_result_I
+ local.get_owner_document_ptr_in_heap local.to_tree_order_ok)
+ obtain to' where to': "h' \<turnstile> to_tree_order (cast document_ptr) \<rightarrow>\<^sub>r to'"
+ by (metis \<open>document_ptr |\<in>| document_ptr_kinds h\<close> \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> assms(1) assms(2)
+ assms(3) assms(5) document_ptr_kinds_commutes document_ptr_kinds_eq_h document_ptr_kinds_eq_h2
+ document_ptr_kinds_eq_h3 is_OK_returns_result_E local.create_character_data_preserves_wellformedness(1)
+ local.to_tree_order_ok)
+ have "set to = set to'"
+ proof safe
+ fix x
+ assume "x \<in> set to"
+ show "x \<in> set to'"
+ using to to'
+ using to_tree_order_parent_child_rel \<open>parent_child_rel h = parent_child_rel h'\<close>
+ by (metis \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> \<open>x \<in> set to\<close> assms(1) assms(2) assms(3) assms(5)
+ local.create_character_data_preserves_wellformedness(1))
+ next
+ fix x
+ assume "x \<in> set to'"
+ show "x \<in> set to"
+ using to to'
+ using to_tree_order_parent_child_rel \<open>parent_child_rel h = parent_child_rel h'\<close>
+ by (metis \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> \<open>x \<in> set to'\<close> assms(1) assms(2) assms(3) assms(5)
+ local.create_character_data_preserves_wellformedness(1))
+ qed
+
+ have "h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast new_character_data_ptr # disc_nodes_h3"
+ using h' local.set_disconnected_nodes_get_disconnected_nodes by auto
+ obtain disc_nodes_h' where disc_nodes_h': "h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h'"
+ and "cast new_character_data_ptr \<in> set disc_nodes_h'"
+ and "disc_nodes_h' = cast new_character_data_ptr # disc_nodes_h3"
+ by (simp add: \<open>h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast new_character_data_ptr # disc_nodes_h3\<close>)
+
+ have "\<And>disc_ptr to to'. disc_ptr \<in> set disc_nodes_h3 \<Longrightarrow> h \<turnstile> to_tree_order (cast disc_ptr) \<rightarrow>\<^sub>r to \<Longrightarrow>
+h' \<turnstile> to_tree_order (cast disc_ptr) \<rightarrow>\<^sub>r to' \<Longrightarrow> set to = set to'"
+ proof safe
+ fix disc_ptr to to' x
+ assume "disc_ptr \<in> set disc_nodes_h3"
+ assume "h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to"
+ assume "h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'"
+ assume "x \<in> set to"
+ show "x \<in> set to'"
+ using to_tree_order_parent_child_rel \<open>parent_child_rel h = parent_child_rel h'\<close>
+ by (metis \<open>h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to\<close>
+ \<open>h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'\<close> \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> \<open>x \<in> set to\<close>
+ assms(1) assms(2) assms(3) assms(5) local.create_character_data_preserves_wellformedness(1))
+ next
+ fix disc_ptr to to' x
+ assume "disc_ptr \<in> set disc_nodes_h3"
+ assume "h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to"
+ assume "h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'"
+ assume "x \<in> set to'"
+ show "x \<in> set to"
+ using to_tree_order_parent_child_rel \<open>parent_child_rel h = parent_child_rel h'\<close>
+ by (metis \<open>h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to\<close>
+ \<open>h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'\<close> \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> \<open>x \<in> set to'\<close>
+ assms(1) assms(2) assms(3) assms(5) local.create_character_data_preserves_wellformedness(1))
+ qed
+
+ have "heap_is_wellformed h'"
+ using assms(1) assms(2) assms(3) assms(5) local.create_character_data_preserves_wellformedness(1)
+ by blast
+
+ have "cast new_character_data_ptr |\<in>| object_ptr_kinds h'"
+ using \<open>cast new_character_data_ptr \<in> set disc_nodes_h'\<close> \<open>heap_is_wellformed h'\<close> disc_nodes_h'
+ local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_commutes by blast
+ then
+ have "new_character_data_ptr |\<in>| character_data_ptr_kinds h'"
+ by simp
+
+ have "\<And>node_ptr. node_ptr \<in> set disc_nodes_h3 \<Longrightarrow> node_ptr |\<in>| node_ptr_kinds h'"
+ by (meson \<open>heap_is_wellformed h'\<close> h' local.heap_is_wellformed_disc_nodes_in_heap
+ local.set_disconnected_nodes_get_disconnected_nodes set_subset_Cons subset_code(1))
+
+ have "h \<turnstile> ok (map_M (to_tree_order \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) disc_nodes_h3)"
+ using assms(1) assms(2) assms(3) to_tree_order_ok
+ apply(auto intro!: map_M_ok_I)[1]
+ using disc_nodes_document_ptr_h local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_commutes
+ by blast
+ then
+ obtain disc_tree_orders where disc_tree_orders:
+ "h \<turnstile> map_M (to_tree_order \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) disc_nodes_h3 \<rightarrow>\<^sub>r disc_tree_orders"
+ by auto
+
+ have "h' \<turnstile> ok (map_M (to_tree_order \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) disc_nodes_h')"
+ apply(auto intro!: map_M_ok_I)[1]
+ apply(simp add: \<open>disc_nodes_h' = cast new_character_data_ptr # disc_nodes_h3\<close>)
+ using \<open>\<And>node_ptr. node_ptr \<in> set disc_nodes_h3 \<Longrightarrow> node_ptr |\<in>| node_ptr_kinds h'\<close>
+ \<open>cast new_character_data_ptr \<in> set disc_nodes_h'\<close> \<open>heap_is_wellformed h'\<close> \<open>known_ptrs h'\<close>
+ \<open>type_wf h'\<close> disc_nodes_h' local.heap_is_wellformed_disc_nodes_in_heap local.to_tree_order_ok
+ node_ptr_kinds_commutes by blast
+ then
+ obtain disc_tree_orders' where disc_tree_orders':
+ "h' \<turnstile> map_M (to_tree_order \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) disc_nodes_h' \<rightarrow>\<^sub>r disc_tree_orders'"
+ by auto
+
+ have "h' \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []"
+ using \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close> children_eq_h2 children_eq_h3 by auto
+
+ obtain new_tree_order where new_tree_order:
+ "h' \<turnstile> to_tree_order (cast new_character_data_ptr) \<rightarrow>\<^sub>r new_tree_order" and
+ "new_tree_order \<in> set disc_tree_orders'"
+ using map_M_pure_E[OF disc_tree_orders' \<open>cast new_character_data_ptr \<in> set disc_nodes_h'\<close>]
+ by auto
+ then have "new_tree_order = [cast new_character_data_ptr]"
+ using \<open>h' \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto simp add: to_tree_order_def
+ dest!: bind_returns_result_E3[rotated, OF \<open>h' \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>, rotated])
+
+ obtain foo where foo: "h' \<turnstile> map_M (to_tree_order \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r)
+(cast new_character_data_ptr # disc_nodes_h3) \<rightarrow>\<^sub>r [cast new_character_data_ptr] # foo"
+ apply(auto intro!: bind_pure_returns_result_I map_M_pure_I)[1]
+ using \<open>new_tree_order = [cast new_character_data_ptr]\<close> new_tree_order apply auto[1]
+ using \<open>disc_nodes_h' = cast new_character_data_ptr # disc_nodes_h3\<close> bind_pure_returns_result_I
+ bind_returns_result_E2 comp_apply disc_tree_orders' local.to_tree_order_pure map_M.simps(2)
+ map_M_pure_I return_returns_result returns_result_eq
+ apply simp
+ by (smt \<open>disc_nodes_h' = cast new_character_data_ptr # disc_nodes_h3\<close> bind_pure_returns_result_I
+ bind_returns_result_E2 comp_apply disc_tree_orders' local.to_tree_order_pure map_M.simps(2) map_M_pure_I
+ return_returns_result returns_result_eq)
+ then have "set (concat foo) = set (concat disc_tree_orders)"
+ apply(auto elim!: bind_returns_result_E2 intro!: map_M_pure_I)[1]
+ apply (smt \<open>\<And>to' toa disc_ptr. \<lbrakk>disc_ptr \<in> set disc_nodes_h3;
+h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r toa; h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'\<rbrakk> \<Longrightarrow>
+set toa = set to'\<close> comp_apply disc_tree_orders local.to_tree_order_pure map_M_pure_E map_M_pure_E2)
+ using \<open>\<And>to' toa disc_ptr. \<lbrakk>disc_ptr \<in> set disc_nodes_h3; h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r toa;
+h' \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_ptr) \<rightarrow>\<^sub>r to'\<rbrakk> \<Longrightarrow> set toa = set to'\<close> comp_apply disc_tree_orders
+ local.to_tree_order_pure map_M_pure_E map_M_pure_E2
+ by smt
+
+ have "disc_tree_orders' = [cast new_character_data_ptr] # foo"
+ using foo disc_tree_orders'
+ by (simp add: \<open>disc_nodes_h' = cast new_character_data_ptr # disc_nodes_h3\<close> returns_result_eq)
+
+ have "set (concat disc_tree_orders') = {cast new_character_data_ptr} \<union> set (concat disc_tree_orders)"
+ apply(auto simp add: \<open>disc_tree_orders' = [cast new_character_data_ptr] # foo\<close>)[1]
+ using \<open>set (concat foo) = set (concat disc_tree_orders)\<close> by auto
+
+ have "h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr) \<rightarrow>\<^sub>r to' @ concat disc_tree_orders'"
+ using \<open>h' \<turnstile> get_owner_document (cast document_ptr) \<rightarrow>\<^sub>r document_ptr\<close> disc_nodes_h' to' disc_tree_orders'
+ by(auto simp add: a_get_scdom_component_def intro!: bind_pure_returns_result_I map_M_pure_I)
+ then
+ have "set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r = set to' \<union> set (concat disc_tree_orders')"
+ by auto
+ have "h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr) \<rightarrow>\<^sub>r to @ concat disc_tree_orders"
+ using \<open>h \<turnstile> get_owner_document (cast document_ptr) \<rightarrow>\<^sub>r document_ptr\<close> disc_nodes_document_ptr_h to disc_tree_orders
+ by(auto simp add: a_get_scdom_component_def intro!: bind_pure_returns_result_I map_M_pure_I)
+ then
+ have "set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r = set to \<union> set (concat disc_tree_orders)"
+ by auto
+
+ have "{cast new_character_data_ptr} \<union> set |h \<turnstile> local.a_get_scdom_component (cast document_ptr)|\<^sub>r =
+set |h' \<turnstile> local.a_get_scdom_component (cast document_ptr)|\<^sub>r"
+ proof(safe)
+ show "cast new_character_data_ptr
+ \<in> set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r"
+ using \<open>h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr) \<rightarrow>\<^sub>r to' @ concat disc_tree_orders'\<close>
+ apply(auto simp add: a_get_scdom_component_def)[1]
+ by (meson \<open>\<And>thesis. (\<And>new_tree_order. \<lbrakk>h' \<turnstile> to_tree_order (cast new_character_data_ptr) \<rightarrow>\<^sub>r new_tree_order;
+new_tree_order \<in> set disc_tree_orders'\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis\<close> local.to_tree_order_ptr_in_result)
+ next
+ fix x
+ assume " x \<in> set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r"
+ then
+ show "x \<in> set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r"
+ using \<open>set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to \<union> set (concat disc_tree_orders)\<close>
+ using \<open>set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to' \<union> set (concat disc_tree_orders')\<close>
+ using \<open>set to = set to'\<close>
+ using \<open>set (concat disc_tree_orders') = {cast new_character_data_ptr} \<union> set (concat disc_tree_orders)\<close>
+ by(auto)
+ next
+ fix x
+ assume " x \<in> set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r"
+ assume "x \<notin> set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r"
+ show "x = cast new_character_data_ptr"
+ using \<open>set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to \<union> set (concat disc_tree_orders)\<close>
+ using \<open>set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to' \<union> set (concat disc_tree_orders')\<close>
+ using \<open>set to = set to'\<close>
+ using \<open>set (concat disc_tree_orders') = {cast new_character_data_ptr} \<union> set (concat disc_tree_orders)\<close>
+ using \<open>x \<in> set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r\<close>
+ \<open>x \<notin> set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r\<close>
+ by auto
+ qed
+
+
+ have "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using object_ptr_kinds_eq_h object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 by auto
+ then
+ show ?thesis
+ apply(auto simp add: is_strongly_scdom_component_safe_def Let_def)[1]
+ apply(rule bexI[where x="cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr"])
+ using \<open>{cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr} \<union> set |h \<turnstile> local.a_get_scdom_component
+(cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r = set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r\<close>
+ apply auto[2]
+ using \<open>set to = set to'\<close> \<open>set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to \<union> set (concat disc_tree_orders)\<close> local.to_tree_order_ptr_in_result to'
+ apply auto[1]
+ using \<open>document_ptr |\<in>| document_ptr_kinds h\<close>
+ apply blast
+ apply(rule bexI[where x="cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr"])
+ using \<open>result = new_character_data_ptr\<close> \<open>{cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr} \<union>
+set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set |h' \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r\<close>
+ apply auto[1]
+ apply(auto)[1]
+ using \<open>set to = set to'\<close> \<open>set |h \<turnstile> local.a_get_scdom_component (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr)|\<^sub>r =
+set to \<union> set (concat disc_tree_orders)\<close> local.to_tree_order_ptr_in_result to' apply auto[1]
+ apply (simp add: \<open>document_ptr |\<in>| document_ptr_kinds h\<close>)
+ using \<open>\<And>thesis. (\<And>new_character_data_ptr h2 h3 disc_nodes_h3. \<lbrakk>h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr;
+h \<turnstile> new_character_data \<rightarrow>\<^sub>h h2; h2 \<turnstile> set_val new_character_data_ptr text \<rightarrow>\<^sub>h h3;
+h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3;
+h3 \<turnstile> set_disconnected_nodes document_ptr (cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis\<close>
+ new_character_data_ptr new_character_data_ptr_not_in_heap
+ apply auto[1]
+ using create_character_data_is_strongly_dom_component_safe_step
+ by (smt ObjectMonad.ptr_kinds_ptr_kinds_M \<open>cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>
+ \<open>result = new_character_data_ptr\<close> assms(1) assms(2) assms(3) assms(4) assms(5) local.get_scdom_component_impl select_result_I2)
+qed
+end
+
+interpretation i_get_scdom_component_create_character_data?: l_get_scdom_component_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs get_scdom_component
+ is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe to_tree_order get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name set_val set_val_locs get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs create_character_data
+ by(auto simp add: l_get_scdom_component_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>create\_document\<close>
+
+lemma create_document_not_strongly_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap" and
+ h' and new_document_ptr where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> create_document \<rightarrow>\<^sub>r new_document_ptr \<rightarrow>\<^sub>h h'" and
+ "\<not> is_strongly_scdom_component_safe {} {cast new_document_ptr} h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder}) heap"
+ let ?P = "create_document"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?document_ptr = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1"])
+ by code_simp+
+qed
+
+locale l_get_scdom_component_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_dom_component_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma create_document_is_weakly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> create_document \<rightarrow>\<^sub>r result"
+ assumes "h \<turnstile> create_document \<rightarrow>\<^sub>h h'"
+ shows "is_weakly_scdom_component_safe {} {cast result} h h'"
+proof -
+ have "object_ptr_kinds h' = {|cast result|} |\<union>| object_ptr_kinds h"
+ using assms(4) assms(5) local.create_document_def new_document_new_ptr by blast
+ have "result |\<notin>| document_ptr_kinds h"
+ using assms(4) assms(5) local.create_document_def new_document_ptr_not_in_heap by auto
+ show ?thesis
+ using assms
+ apply(auto simp add: is_weakly_scdom_component_safe_def Let_def)[1]
+ using \<open>object_ptr_kinds h' = {|cast result|} |\<union>| object_ptr_kinds h\<close> apply(auto)[1]
+ apply (simp add: local.create_document_def new_document_ptr_in_heap)
+ using \<open>result |\<notin>| document_ptr_kinds h\<close> apply auto[1]
+
+ apply (metis (no_types, lifting) \<open>result |\<notin>| document_ptr_kinds h\<close> document_ptr_kinds_commutes
+ local.create_document_is_weakly_dom_component_safe_step select_result_I2)
+ done
+qed
+end
+
+interpretation i_get_scdom_component_create_document?: l_get_scdom_component_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe to_tree_order get_parent get_parent_locs
+ get_child_nodes get_child_nodes_locs get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_element_by_id get_elements_by_class_name get_elements_by_tag_name create_document
+ get_disconnected_nodes get_disconnected_nodes_locs
+ by(auto simp add: l_get_scdom_component_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>insert\_before\<close>
+
+locale l_get_dom_component_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_owner_document_wf +
+ l_get_dom_component_get_scdom_component +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_insert_before_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_child_nodes_get_disconnected_nodes +
+ l_remove_child +
+ l_get_root_node_wf +
+ l_set_disconnected_nodes_get_disconnected_nodes_wf +
+ l_set_disconnected_nodes_get_ancestors +
+ l_get_ancestors_wf +
+ l_get_owner_document +
+ l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma insert_before_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> insert_before ptr' child ref \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component ptr'|\<^sub>r"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast child)|\<^sub>r"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast |h \<turnstile> get_owner_document ptr'|\<^sub>r)|\<^sub>r"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast |h \<turnstile> get_owner_document (cast child)|\<^sub>r)|\<^sub>r"
+ shows "preserved (get_M ptr getter) h h'"
+proof -
+ obtain owner_document where owner_document: "h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r owner_document"
+ using assms(4)
+ by(auto simp add: local.adopt_node_def insert_before_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF ensure_pre_insertion_validity_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_owner_document_pure, rotated] bind_returns_heap_E2[rotated, OF next_sibling_pure, rotated] split: if_splits)
+ then
+ obtain c where "h \<turnstile> get_dom_component (cast owner_document) \<rightarrow>\<^sub>r c"
+ using get_dom_component_ok assms(1) assms(2) assms(3) get_owner_document_owner_document_in_heap
+ by (meson document_ptr_kinds_commutes select_result_I)
+ then
+ have "ptr \<noteq> cast owner_document"
+ using assms(6) assms(1) assms(2) assms(3) local.get_dom_component_ptr owner_document
+ by (metis (no_types, lifting) assms(8) select_result_I2)
+
+ obtain owner_document' where owner_document': "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r owner_document'"
+ using assms(4)
+ by(auto simp add: local.adopt_node_def insert_before_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF ensure_pre_insertion_validity_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_owner_document_pure, rotated]
+ bind_returns_heap_E2[rotated, OF next_sibling_pure, rotated] split: if_splits)
+ then
+ obtain c where "h \<turnstile> get_dom_component (cast owner_document') \<rightarrow>\<^sub>r c"
+ using get_dom_component_ok assms(1) assms(2) assms(3) get_owner_document_owner_document_in_heap
+ by (meson document_ptr_kinds_commutes select_result_I)
+ then
+ have "ptr \<noteq> cast owner_document'"
+ using assms(1) assms(2) assms(3) assms(7) local.get_dom_component_ptr owner_document' by auto
+ then
+ have "ptr \<noteq> cast |h \<turnstile> get_owner_document ptr'|\<^sub>r"
+ using owner_document' by auto
+
+ have "ptr \<noteq> ptr'"
+ by (metis (mono_tags, hide_lams) assms(1) assms(2) assms(3) assms(5) assms(7) is_OK_returns_result_I
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_dom_component_ok l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_dom_component_ptr
+ l_get_owner_document.get_owner_document_ptr_in_heap local.l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms
+ local.l_get_owner_document_axioms owner_document' return_returns_result returns_result_select_result)
+ have "\<And>parent. h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some parent \<Longrightarrow> parent \<noteq> ptr"
+ by (meson assms(1) assms(2) assms(3) assms(6) l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_dom_component_ptr
+ local.get_dom_component_ok local.get_dom_component_to_tree_order local.get_parent_parent_in_heap
+ local.l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms local.to_tree_order_ok local.to_tree_order_parent
+ local.to_tree_order_ptr_in_result local.to_tree_order_ptrs_in_heap returns_result_select_result)
+ then
+ have "\<And>parent. |h \<turnstile> get_parent child|\<^sub>r = Some parent \<Longrightarrow> parent \<noteq> ptr"
+ by (metis assms(2) assms(3) assms(4) is_OK_returns_heap_I local.get_parent_ok
+ local.insert_before_child_in_heap select_result_I)
+
+ show ?thesis
+ using insert_before_writes assms(4)
+ apply(rule reads_writes_preserved2)
+ apply(auto simp add: insert_before_locs_def adopt_node_locs_def all_args_def)[1]
+ apply(auto simp add: remove_child_locs_def set_child_nodes_locs_def
+ set_disconnected_nodes_locs_def all_args_def split: if_splits)[1]
+ apply (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r |h \<turnstile> get_owner_document ptr'|\<^sub>r\<close>
+ get_M_Mdocument_preserved3)
+ apply(auto simp add: remove_child_locs_def set_child_nodes_locs_def
+ set_disconnected_nodes_locs_def all_args_def split: if_splits)[1]
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close>
+ get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply(auto simp add: remove_child_locs_def set_child_nodes_locs_def
+ set_disconnected_nodes_locs_def all_args_def split: if_splits)[1]
+ apply (metis \<open>ptr \<noteq> ptr'\<close> document_ptr_casts_commute3 get_M_Mdocument_preserved3)
+ apply(auto split: option.splits)[1]
+ apply (metis \<open>ptr \<noteq> ptr'\<close> element_ptr_casts_commute3 get_M_Element_preserved8)
+ apply(auto simp add: remove_child_locs_def set_child_nodes_locs_def set_disconnected_nodes_locs_def
+ all_args_def split: if_splits)[1]
+ apply (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r |h \<turnstile> get_owner_document ptr'|\<^sub>r\<close> get_M_Mdocument_preserved3)
+ apply(auto simp add: remove_child_locs_def set_child_nodes_locs_def
+ set_disconnected_nodes_locs_def all_args_def split: if_splits)[1]
+ apply (metis (no_types, lifting) \<open>\<And>parent. |h \<turnstile> get_parent child|\<^sub>r = Some parent \<Longrightarrow> parent \<noteq> ptr\<close>
+ element_ptr_casts_commute3 get_M_Element_preserved8 node_ptr_casts_commute option.case_eq_if option.collapse)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close>
+ get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply (metis \<open>\<And>parent. |h \<turnstile> get_parent child|\<^sub>r = Some parent \<Longrightarrow> parent \<noteq> ptr\<close>
+ document_ptr_casts_commute3 get_M_Mdocument_preserved3)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close>
+ get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close>
+ get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply(auto simp add: remove_child_locs_def set_child_nodes_locs_def
+ set_disconnected_nodes_locs_def all_args_def split: if_splits)[1]
+ apply (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r |h \<turnstile> get_owner_document ptr'|\<^sub>r\<close>
+ get_M_Mdocument_preserved3)
+ apply(auto simp add: remove_child_locs_def set_child_nodes_locs_def
+ set_disconnected_nodes_locs_def all_args_def split: if_splits)[1]
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close>
+ get_M_Mdocument_preserved3 owner_document select_result_I2)
+ apply(auto simp add: remove_child_locs_def set_child_nodes_locs_def
+ set_disconnected_nodes_locs_def all_args_def split: if_splits)[1]
+ apply (metis \<open>ptr \<noteq> ptr'\<close> document_ptr_casts_commute3 get_M_Mdocument_preserved3)
+ apply (metis (no_types, lifting) \<open>ptr \<noteq> ptr'\<close> element_ptr_casts_commute3
+ get_M_Element_preserved8 node_ptr_casts_commute option.case_eq_if option.collapse)
+ apply(auto simp add: remove_child_locs_def set_child_nodes_locs_def
+ set_disconnected_nodes_locs_def all_args_def split: if_splits)[1]
+ by (metis \<open>ptr \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r |h \<turnstile> get_owner_document ptr'|\<^sub>r\<close> get_M_Mdocument_preserved3)
+qed
+
+lemma insert_before_is_strongly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> insert_before ptr' child ref \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<notin> set |h \<turnstile> get_scdom_component ptr'|\<^sub>r"
+ assumes "ptr \<notin> set |h \<turnstile> get_scdom_component (cast child)|\<^sub>r"
+ shows "preserved (get_M ptr getter) h h'"
+proof -
+ have "ptr' |\<in>| object_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_heap_I local.insert_before_ptr_in_heap)
+ then
+ obtain sc' where sc': "h \<turnstile> get_scdom_component ptr' \<rightarrow>\<^sub>r sc'"
+ by (meson assms(1) assms(2) assms(3) get_scdom_component_ok is_OK_returns_result_E)
+ moreover
+ obtain c' where c': "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c'"
+ by (meson \<open>ptr' |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) is_OK_returns_result_E
+ local.get_dom_component_ok)
+ ultimately have "set c' \<subseteq> set sc'"
+ using assms(1) assms(2) assms(3) get_scdom_component_subset_get_dom_component by blast
+
+ have "child |\<in>| node_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_heap_I local.insert_before_child_in_heap)
+ then
+ obtain child_sc where child_sc: "h \<turnstile> get_scdom_component (cast child) \<rightarrow>\<^sub>r child_sc"
+ by (meson assms(1) assms(2) assms(3) get_scdom_component_ok is_OK_returns_result_E
+ node_ptr_kinds_commutes)
+ moreover
+ obtain child_c where child_c: "h \<turnstile> get_dom_component (cast child) \<rightarrow>\<^sub>r child_c"
+ by (meson \<open>child |\<in>| node_ptr_kinds h\<close> assms(1) assms(2) assms(3) is_OK_returns_result_E
+ local.get_dom_component_ok node_ptr_kinds_commutes)
+ ultimately have "set child_c \<subseteq> set child_sc"
+ using assms(1) assms(2) assms(3) get_scdom_component_subset_get_dom_component by blast
+
+ obtain ptr'_owner_document where ptr'_owner_document: "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r ptr'_owner_document"
+ by (meson \<open>set c' \<subseteq> set sc'\<close> assms(1) assms(2) assms(3) c' get_scdom_component_owner_document_same
+ local.get_dom_component_ptr sc' subset_code(1))
+ then
+ have "h \<turnstile> get_scdom_component (cast ptr'_owner_document) \<rightarrow>\<^sub>r sc'"
+ by (metis (no_types, lifting) \<open>set c' \<subseteq> set sc'\<close> assms(1) assms(2) assms(3) c'
+ get_scdom_component_owner_document_same get_scdom_component_ptrs_same_scope_component
+ local.get_dom_component_ptr sc' select_result_I2 subset_code(1))
+ moreover
+ obtain ptr'_owner_document_c where ptr'_owner_document_c:
+ "h \<turnstile> get_dom_component (cast ptr'_owner_document) \<rightarrow>\<^sub>r ptr'_owner_document_c"
+ by (meson assms(1) assms(2) assms(3) document_ptr_kinds_commutes is_OK_returns_result_E
+ local.get_dom_component_ok local.get_owner_document_owner_document_in_heap ptr'_owner_document)
+ ultimately have "set ptr'_owner_document_c \<subseteq> set sc'"
+ using assms(1) assms(2) assms(3) get_scdom_component_subset_get_dom_component by blast
+
+ obtain child_owner_document where child_owner_document: "h \<turnstile> get_owner_document (cast child) \<rightarrow>\<^sub>r child_owner_document"
+ by (meson \<open>set child_c \<subseteq> set child_sc\<close> assms(1) assms(2) assms(3) child_c child_sc
+ get_scdom_component_owner_document_same local.get_dom_component_ptr subset_code(1))
+
+ have "child_owner_document |\<in>| document_ptr_kinds h"
+ using assms(1) assms(2) assms(3) child_owner_document local.get_owner_document_owner_document_in_heap
+ by blast
+ then
+ have "h \<turnstile> get_scdom_component (cast child_owner_document) \<rightarrow>\<^sub>r child_sc"
+ using get_scdom_component_ok assms(1) assms(2) assms(3) child_sc
+ by (metis (no_types, lifting) \<open>set child_c \<subseteq> set child_sc\<close> child_c child_owner_document
+ get_scdom_component_owner_document_same get_scdom_component_ptrs_same_scope_component
+ local.get_dom_component_ptr returns_result_eq set_mp)
+ moreover
+ obtain child_owner_document_c where child_owner_document_c:
+ "h \<turnstile> get_dom_component (cast child_owner_document) \<rightarrow>\<^sub>r child_owner_document_c"
+ by (meson assms(1) assms(2) assms(3) child_owner_document document_ptr_kinds_commutes
+ is_OK_returns_result_E local.get_dom_component_ok local.get_owner_document_owner_document_in_heap)
+ ultimately have "set child_owner_document_c \<subseteq> set child_sc"
+ using assms(1) assms(2) assms(3) get_scdom_component_subset_get_dom_component by blast
+
+
+ have "ptr \<notin> set |h \<turnstile> get_dom_component ptr'|\<^sub>r"
+ using \<open>set c' \<subseteq> set sc'\<close> assms(5) c' sc' by auto
+ moreover have "ptr \<notin> set |h \<turnstile> get_dom_component (cast child)|\<^sub>r"
+ using \<open>set child_c \<subseteq> set child_sc\<close> assms(6) child_c child_sc by auto
+ moreover have "ptr \<notin> set |h \<turnstile> get_dom_component (cast |h \<turnstile> get_owner_document ptr'|\<^sub>r)|\<^sub>r"
+ using \<open>set ptr'_owner_document_c \<subseteq> set sc'\<close> assms(5) ptr'_owner_document ptr'_owner_document_c sc'
+ by auto
+ moreover have "ptr \<notin> set |h \<turnstile> get_dom_component (cast |h \<turnstile> get_owner_document (cast child)|\<^sub>r)|\<^sub>r"
+ using \<open>set child_owner_document_c \<subseteq> set child_sc\<close> assms(6) child_owner_document child_owner_document_c
+ child_sc by auto
+
+ ultimately show ?thesis
+ using assms insert_before_is_component_unsafe
+ by blast
+qed
+
+lemma insert_before_is_strongly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> insert_before ptr node child \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe ({ptr, cast node} \<union> (case child of Some ref \<Rightarrow> {cast ref} | None \<Rightarrow> {} )) {} h h'"
+proof -
+ obtain ancestors reference_child owner_document h2 h3 disconnected_nodes_h2 where
+ ancestors: "h \<turnstile> get_ancestors ptr \<rightarrow>\<^sub>r ancestors" and
+ node_not_in_ancestors: "cast node \<notin> set ancestors" and
+ reference_child:
+ "h \<turnstile> (if Some node = child then a_next_sibling node else return child) \<rightarrow>\<^sub>r reference_child" and
+ owner_document: "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document" and
+ h2: "h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h2" and
+ disconnected_nodes_h2: "h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disconnected_nodes_h2" and
+ h3: "h2 \<turnstile> set_disconnected_nodes owner_document (remove1 node disconnected_nodes_h2) \<rightarrow>\<^sub>h h3" and
+ h': "h3 \<turnstile> a_insert_node ptr node reference_child \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ by(auto simp add: insert_before_def a_ensure_pre_insertion_validity_def
+ elim!: bind_returns_heap_E bind_returns_result_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_ancestors_pure, rotated]
+ bind_returns_heap_E2[rotated, OF next_sibling_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_owner_document_pure, rotated]
+ split: if_splits option.splits)
+
+ have object_ptr_kinds_M_eq3_h: "object_ptr_kinds h = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF adopt_node_writes h2])
+ using adopt_node_pointers_preserved
+ apply blast
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h: "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs )
+ then have object_ptr_kinds_M_eq2_h: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq2_h: "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+
+ have "known_ptrs h2"
+ using assms(3) object_ptr_kinds_M_eq3_h known_ptrs_preserved by blast
+
+ have wellformed_h2: "heap_is_wellformed h2"
+ using adopt_node_preserves_wellformedness[OF assms(1) h2] assms(3) assms(2) .
+
+ have object_ptr_kinds_M_eq3_h2: "object_ptr_kinds h2 = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h3])
+ unfolding a_remove_child_locs_def
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h2: "\<And>ptrs. h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_M_eq2_h2: "|h2 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq2_h2: "|h2 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ have document_ptr_kinds_eq2_h2: "|h2 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_M_eq2_h2 document_ptr_kinds_M_eq by auto
+
+ have "known_ptrs h3"
+ using object_ptr_kinds_M_eq3_h2 known_ptrs_preserved \<open>known_ptrs h2\<close> by blast
+
+ have object_ptr_kinds_M_eq3_h': "object_ptr_kinds h3 = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF insert_node_writes h'])
+ unfolding a_remove_child_locs_def
+ using set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h3:
+ "\<And>ptrs. h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_M_eq2_h3:
+ "|h3 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq2_h3: "|h3 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ have document_ptr_kinds_eq2_h3: "|h3 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h' \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_M_eq2_h3 document_ptr_kinds_M_eq by auto
+
+
+ have "object_ptr_kinds h = object_ptr_kinds h'"
+ by (simp add: object_ptr_kinds_M_eq3_h object_ptr_kinds_M_eq3_h' object_ptr_kinds_M_eq3_h2)
+ then
+ show ?thesis
+ using assms
+ apply(auto simp add: is_strongly_scdom_component_safe_def)[1]
+ using insert_before_is_strongly_dom_component_safe_step local.get_scdom_component_impl by blast
+qed
+
+lemma append_child_is_strongly_dom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> append_child ptr' child \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<notin> set |h \<turnstile> get_scdom_component ptr'|\<^sub>r"
+ assumes "ptr \<notin> set |h \<turnstile> get_scdom_component (cast child)|\<^sub>r"
+ shows "preserved (get_M ptr getter) h h'"
+ by (metis assms(1) assms(2) assms(3) assms(4) assms(5) assms(6)
+ insert_before_is_strongly_dom_component_safe_step local.append_child_def)
+
+lemma append_child_is_strongly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> append_child ptr child \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {ptr, cast child} {} h h'"
+ using assms unfolding append_child_def
+ using insert_before_is_strongly_dom_component_safe
+ by fastforce
+end
+
+interpretation i_get_dom_component_insert_before?: l_get_dom_component_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name set_child_nodes set_child_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs
+ get_owner_document remove_child remove_child_locs remove adopt_node adopt_node_locs insert_before
+ insert_before_locs append_child get_scdom_component is_strongly_scdom_component_safe
+ is_weakly_scdom_component_safe
+ by(auto simp add: l_get_dom_component_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_owner\_document\<close>
+
+locale l_get_owner_document_scope_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_owner_document_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component_get_scdom_component +
+ l_get_owner_document_wf_get_root_node_wf
+begin
+lemma get_owner_document_is_strongly_scdom_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r owner_document"
+ shows "cast owner_document \<in> set sc \<longleftrightarrow> ptr' \<in> set sc"
+proof -
+ have "h \<turnstile> get_owner_document (cast owner_document) \<rightarrow>\<^sub>r owner_document"
+ by (metis assms(1) assms(2) assms(3) assms(5) cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject
+ document_ptr_casts_commute3 document_ptr_document_ptr_cast document_ptr_kinds_commutes
+ local.get_owner_document_owner_document_in_heap local.get_root_node_document
+ local.get_root_node_not_node_same node_ptr_no_document_ptr_cast)
+ then show ?thesis
+ using assms
+ using bind_returns_result_E contra_subsetD get_scdom_component_ok
+ get_scdom_component_ptrs_same_scope_component get_scdom_component_subset_get_dom_component
+ is_OK_returns_result_E is_OK_returns_result_I local.get_dom_component_ok local.get_dom_component_ptr
+ local.get_owner_document_ptr_in_heap local.get_owner_document_pure local.get_scdom_component_def
+ pure_returns_heap_eq returns_result_eq
+ by (smt local.get_scdom_component_ptrs_same_owner_document subsetD)
+qed
+
+
+lemma get_owner_document_is_strongly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ assumes "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>h h'"
+ shows "is_strongly_scdom_component_safe {ptr} {cast owner_document} h h'"
+proof -
+ have "h = h'"
+ by (meson assms(5) local.get_owner_document_pure pure_returns_heap_eq)
+ then show ?thesis
+ using assms
+ apply(auto simp add: is_strongly_scdom_component_safe_def Let_def preserved_def)[1]
+ by (smt get_owner_document_is_strongly_scdom_component_safe_step inf.orderE is_OK_returns_result_I
+ local.get_dom_component_ok local.get_dom_component_to_tree_order_subset local.get_owner_document_ptr_in_heap
+ local.get_scdom_component_impl local.get_scdom_component_ok local.get_scdom_component_ptr_in_heap
+ local.get_scdom_component_subset_get_dom_component local.to_tree_order_ok
+ local.to_tree_order_ptr_in_result notin_fset returns_result_select_result subset_eq)
+qed
+end
+
+interpretation i_get_owner_document_scope_component?: l_get_owner_document_scope_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe
+ get_owner_document get_disconnected_nodes get_disconnected_nodes_locs to_tree_order known_ptr
+ known_ptrs type_wf heap_is_wellformed parent_child_rel get_child_nodes get_child_nodes_locs
+ get_parent get_parent_locs get_ancestors get_ancestors_locs get_root_node get_root_node_locs
+ get_dom_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_element_by_id
+ get_elements_by_class_name get_elements_by_tag_name
+ by(auto simp add: l_get_owner_document_scope_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_owner_document_scope_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+end
diff --git a/thys/SC_DOM_Components/ROOT b/thys/SC_DOM_Components/ROOT
new file mode 100644
--- /dev/null
+++ b/thys/SC_DOM_Components/ROOT
@@ -0,0 +1,13 @@
+chapter AFP
+
+session "SC_DOM_Components" (AFP) = "Shadow_SC_DOM" +
+ options [timeout = 1200]
+ theories
+ Core_DOM_DOM_Components
+ Core_DOM_SC_DOM_Components
+ Shadow_DOM_DOM_Components
+ Shadow_DOM_SC_DOM_Components
+ document_files
+ "root.tex"
+ "root.bib"
+ "fancytabs-normal.jpg"
diff --git a/thys/SC_DOM_Components/Shadow_DOM_DOM_Components.thy b/thys/SC_DOM_Components/Shadow_DOM_DOM_Components.thy
new file mode 100644
--- /dev/null
+++ b/thys/SC_DOM_Components/Shadow_DOM_DOM_Components.thy
@@ -0,0 +1,1323 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section \<open>Shadow SC DOM Components\<close>
+theory Shadow_DOM_DOM_Components
+ imports
+ Shadow_SC_DOM.Shadow_DOM
+ Core_DOM_DOM_Components
+begin
+
+declare [[smt_timeout = 1200]]
+
+section \<open>Shadow root components\<close>
+
+
+subsection \<open>get\_component\<close>
+
+global_interpretation l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_root_node get_root_node_locs to_tree_order
+ defines get_dom_component = a_get_dom_component
+ and is_strongly_dom_component_safe = a_is_strongly_dom_component_safe
+ and is_weakly_dom_component_safe = a_is_weakly_dom_component_safe
+ .
+
+interpretation i_get_dom_component?: l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name
+ by(auto simp add: l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ get_dom_component_def is_strongly_dom_component_safe_def is_weakly_dom_component_safe_def instances)
+declare l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+
+
+subsection \<open>attach\_shadow\_root\<close>
+
+locale l_get_dom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ to_tree_order get_parent get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs
+ get_ancestors get_ancestors_locs get_disconnected_nodes get_disconnected_nodes_locs get_element_by_id
+ get_elements_by_class_name get_elements_by_tag_name +
+ l_attach_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr set_shadow_root set_shadow_root_locs set_mode set_mode_locs
+ attach_shadow_root type_wf get_tag_name get_tag_name_locs get_shadow_root get_shadow_root_locs +
+ l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_mode set_mode_locs +
+ l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_shadow_root set_shadow_root_locs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and to_tree_order :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_dom_component :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_root_node :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_ancestors :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_ancestors_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_element_by_id :: "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog"
+ and get_elements_by_class_name :: "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr list) prog"
+ and get_elements_by_tag_name :: "(_) object_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr list) prog"
+ and set_shadow_root :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr option \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_mode :: "(_) shadow_root_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and attach_shadow_root :: "(_) element_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr) prog"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and is_strongly_dom_component_safe :: "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ and is_weakly_dom_component_safe :: "(_) object_ptr set \<Rightarrow> (_) object_ptr set \<Rightarrow> (_) heap \<Rightarrow> (_) heap \<Rightarrow> bool"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+
+lemma attach_shadow_root_is_weakly_dom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<noteq> cast |h \<turnstile> attach_shadow_root element_ptr shadow_root_mode|\<^sub>r"
+ assumes "ptr \<notin> set |h \<turnstile> get_dom_component (cast element_ptr)|\<^sub>r"
+ shows "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'"
+proof -
+ obtain h2 h3 new_shadow_root_ptr where
+ h2: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h2" and
+ new_shadow_root_ptr: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr" and
+ h3: "h2 \<turnstile> set_mode new_shadow_root_ptr shadow_root_mode \<rightarrow>\<^sub>h h3" and
+ h': "h3 \<turnstile> set_shadow_root element_ptr (Some new_shadow_root_ptr) \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ by(auto simp add: attach_shadow_root_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_tag_name_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_shadow_root_pure, rotated] split: if_splits)
+ have "h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ using new_shadow_root_ptr h2 h3 h'
+ using assms(4)
+ by(auto simp add: attach_shadow_root_def intro!: bind_returns_result_I
+ bind_pure_returns_result_I[OF get_tag_name_pure] bind_pure_returns_result_I[OF get_shadow_root_pure]
+ elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_tag_name_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_shadow_root_pure, rotated] split: if_splits)
+ have "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h2"
+ using h2 new_shadow_root_ptr
+ by (metis (no_types, lifting) \<open>h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>r new_shadow_root_ptr\<close>
+ assms(5) new_shadow_root_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t select_result_I2)
+
+ have "ptr \<noteq> cast new_shadow_root_ptr"
+ using \<open>h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>r new_shadow_root_ptr\<close> assms(5)
+ by auto
+
+ have "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h2 h3"
+ using set_mode_writes h3
+ apply(rule reads_writes_preserved2)
+ apply(auto simp add: set_mode_locs_def all_args_def)[1]
+ using \<open>ptr \<noteq> cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_shadow_root_ptr\<close>
+ by (metis get_M_Mshadow_root_preserved3a)
+
+ have "element_ptr |\<in>| element_ptr_kinds h"
+ using \<open>h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>r new_shadow_root_ptr\<close> attach_shadow_root_element_ptr_in_heap
+ by blast
+ have "ptr \<noteq> cast element_ptr"
+ by (metis (no_types, lifting) \<open>element_ptr |\<in>| element_ptr_kinds h\<close> assms(1) assms(2) assms(3)
+ assms(6) element_ptr_kinds_commutes is_OK_returns_result_E l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_dom_component_ok
+ local.get_dom_component_ptr local.l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms node_ptr_kinds_commutes select_result_I2)
+
+ have "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h3 h'"
+ using set_shadow_root_writes h'
+ apply(rule reads_writes_preserved2)
+ apply(auto simp add: set_shadow_root_locs_def all_args_def)[1]
+ by (metis \<open>ptr \<noteq> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr\<close> get_M_Element_preserved8)
+
+ show ?thesis
+ using \<open>preserved (get_M ptr getter) h h2\<close> \<open>preserved (get_M ptr getter) h2 h3\<close> \<open>preserved (get_M ptr getter) h3 h'\<close>
+ by(auto simp add: preserved_def)
+qed
+end
+
+interpretation i_get_dom_component_attach_shadow_root?: l_get_dom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr heap_is_wellformed parent_child_rel type_wf known_ptrs to_tree_order get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_dom_component get_root_node get_root_node_locs
+ get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name
+ set_shadow_root set_shadow_root_locs set_mode set_mode_locs attach_shadow_root get_disconnected_nodes
+ get_disconnected_nodes_locs is_strongly_dom_component_safe is_weakly_dom_component_safe get_tag_name
+ get_tag_name_locs get_shadow_root get_shadow_root_locs
+ by(auto simp add: l_get_dom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsection \<open>get\_shadow\_root\<close>
+
+locale l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_shadow_root +
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_shadow_root_get_child_nodes
+begin
+lemma get_shadow_root_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ shows "set |h \<turnstile> get_dom_component (cast host)|\<^sub>r \<inter> set |h \<turnstile> get_dom_component (cast shadow_root_ptr)|\<^sub>r = {}"
+proof -
+ have "cast host |\<in>| object_ptr_kinds h"
+ using assms(4) get_shadow_root_ptr_in_heap by auto
+ then obtain host_c where host_c: "h \<turnstile> get_dom_component (cast host) \<rightarrow>\<^sub>r host_c"
+ by (meson assms(1) assms(2) assms(3) get_dom_component_ok is_OK_returns_result_E)
+ obtain host_root where host_root: "h \<turnstile> get_root_node (cast host) \<rightarrow>\<^sub>r host_root"
+ by (metis (no_types, lifting) bind_returns_heap_E get_dom_component_def host_c
+ is_OK_returns_result_I pure_def pure_eq_iff)
+
+ have "cast shadow_root_ptr |\<in>| object_ptr_kinds h"
+ using get_shadow_root_shadow_root_ptr_in_heap assms shadow_root_ptr_kinds_commutes
+ using document_ptr_kinds_commutes by blast
+ then obtain shadow_root_ptr_c where shadow_root_ptr_c: "h \<turnstile> get_dom_component (cast shadow_root_ptr) \<rightarrow>\<^sub>r shadow_root_ptr_c"
+ by (meson assms(1) assms(2) assms(3) get_dom_component_ok is_OK_returns_result_E)
+ have "h \<turnstile> get_root_node (cast shadow_root_ptr) \<rightarrow>\<^sub>r cast shadow_root_ptr"
+ using \<open>cast shadow_root_ptr |\<in>| object_ptr_kinds h\<close>
+ by(auto simp add: get_root_node_def get_ancestors_def intro!: bind_pure_returns_result_I
+ split: option.splits)
+
+ have "host_root \<noteq> cast shadow_root_ptr"
+ proof (rule ccontr, simp)
+ assume "host_root = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr"
+
+ have "(cast shadow_root_ptr, host_root) \<in> (parent_child_rel h)\<^sup>*"
+ using \<open>host_root = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr\<close> by auto
+ moreover have "(host_root, cast host) \<in> (parent_child_rel h)\<^sup>*"
+ using get_root_node_parent_child_rel host_root assms
+ by blast
+ moreover have "(cast host, cast shadow_root_ptr) \<in> (a_host_shadow_root_rel h)"
+ using assms(4) apply(auto simp add: a_host_shadow_root_rel_def)[1]
+ by (metis (mono_tags, lifting) get_shadow_root_ptr_in_heap image_eqI is_OK_returns_result_I
+ mem_Collect_eq prod.simps(2) select_result_I2)
+ moreover have " acyclic (parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)"
+ using assms(1)[unfolded heap_is_wellformed_def]
+ by auto
+ ultimately show False
+ using local.parent_child_rel_node_ptr
+ by (metis (no_types, lifting) Un_iff \<open>host_root = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr\<close>
+ acyclic_def in_rtrancl_UnI rtrancl_into_trancl1)
+ qed
+ then have "host_c \<noteq> shadow_root_ptr_c"
+ by (metis \<open>h \<turnstile> get_root_node (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) \<rightarrow>\<^sub>r cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr\<close>
+ assms(1) assms(2) assms(3) get_dom_component_ptr get_dom_component_root_node_same host_c host_root
+ local.get_root_node_parent_child_rel local.get_root_node_same_no_parent_parent_child_rel rtranclE shadow_root_ptr_c)
+ then have "set host_c \<inter> set shadow_root_ptr_c = {}"
+ using assms get_dom_component_no_overlap Shadow_DOM.a_heap_is_wellformed_def host_c shadow_root_ptr_c
+ by blast
+ then show ?thesis
+ using host_c shadow_root_ptr_c
+ by auto
+qed
+end
+
+interpretation i_get_shadow_root_component?: l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf get_shadow_root get_shadow_root_locs get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_tag_name get_tag_name_locs known_ptr
+ heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs
+ get_disconnected_document get_disconnected_document_locs known_ptrs to_tree_order get_parent
+ get_parent_locs get_dom_component is_strongly_dom_component_safe is_weakly_dom_component_safe
+ get_root_node get_root_node_locs get_ancestors get_ancestors_locs get_element_by_id
+ get_elements_by_class_name get_elements_by_tag_name remove_shadow_root remove_shadow_root_locs
+ by(auto simp add: l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsection \<open>get\_host\<close>
+
+locale l_get_host_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_host +
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma get_host_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_host shadow_root_ptr \<rightarrow>\<^sub>r host"
+ shows "set |h \<turnstile> get_dom_component (cast host)|\<^sub>r \<inter> set |h \<turnstile> get_dom_component (cast shadow_root_ptr)|\<^sub>r = {}"
+proof -
+ have "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ using assms(1) assms(2) assms(4) local.shadow_root_host_dual by blast
+ then show ?thesis
+ using assms(1) assms(2) assms(3) local.get_shadow_root_is_component_unsafe by blast
+qed
+end
+
+interpretation i_get_host_component?: l_get_host_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs known_ptr type_wf heap_is_wellformed
+ parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document
+ get_disconnected_document_locs known_ptrs to_tree_order get_parent get_parent_locs get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors
+ get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name remove_shadow_root
+ remove_shadow_root_locs
+ by(auto simp add: l_get_host_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_host_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+
+subsection \<open>get\_root\_node\_si\<close>
+
+locale l_get_dom_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_root_node_si_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma get_root_node_si_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node_si ptr' \<rightarrow>\<^sub>r root"
+ shows "set |h \<turnstile> get_dom_component ptr'|\<^sub>r = set |h \<turnstile> get_dom_component root|\<^sub>r \<or>
+set |h \<turnstile> get_dom_component ptr'|\<^sub>r \<inter> set |h \<turnstile> get_dom_component root|\<^sub>r = {}"
+proof -
+ have "ptr' |\<in>| object_ptr_kinds h"
+ using get_ancestors_si_ptr_in_heap assms(4)
+ by(auto simp add: get_root_node_si_def elim!: bind_returns_result_E2)
+ then
+ obtain c where "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c"
+ by (meson assms(1) assms(2) assms(3) local.get_dom_component_ok select_result_I)
+ moreover
+ have "root |\<in>| object_ptr_kinds h"
+ using get_ancestors_si_ptr assms(4)
+ apply(auto simp add: get_root_node_si_def elim!: bind_returns_result_E2)[1]
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) empty_iff empty_set
+ get_ancestors_si_ptrs_in_heap last_in_set)
+ then
+ obtain c' where "h \<turnstile> get_dom_component root \<rightarrow>\<^sub>r c'"
+ by (meson assms(1) assms(2) assms(3) local.get_dom_component_ok select_result_I)
+ ultimately show ?thesis
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) local.get_dom_component_no_overlap select_result_I2)
+qed
+end
+
+interpretation i_get_dom_component_get_root_node_si?: l_get_dom_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_host get_host_locs get_ancestors_si get_ancestors_si_locs get_root_node_si get_root_node_si_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs get_tag_name
+ get_tag_name_locs heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_document
+ get_disconnected_document_locs to_tree_order get_dom_component is_strongly_dom_component_safe
+ is_weakly_dom_component_safe get_root_node get_root_node_locs get_ancestors get_ancestors_locs
+ get_element_by_id get_elements_by_class_name get_elements_by_tag_name
+ by(auto simp add: l_get_dom_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_dom_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+
+subsection \<open>get\_assigned\_nodes\<close>
+
+lemma get_shadow_root_not_weakly_dom_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and
+ element_ptr and shadow_root_ptr_opt and h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> get_shadow_root element_ptr \<rightarrow>\<^sub>r shadow_root_ptr_opt \<rightarrow>\<^sub>h h'" and
+ "\<not> is_weakly_dom_component_safe {cast element_ptr} (cast ` set_option shadow_root_ptr_opt) h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder},
+'Shadowroot::{equal,linorder}) heap"
+ let ?P = "do {
+ document_ptr \<leftarrow> create_document;
+ html \<leftarrow> create_element document_ptr ''html'';
+ append_child (cast document_ptr) (cast html);
+ head \<leftarrow> create_element document_ptr ''head'';
+ append_child (cast html) (cast head);
+ body \<leftarrow> create_element document_ptr ''body'';
+ append_child (cast html) (cast body);
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast body) (cast e1);
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast e1) (cast e2);
+ s1 \<leftarrow> attach_shadow_root e1 Open;
+ e3 \<leftarrow> create_element document_ptr ''slot'';
+ append_child (cast s1) (cast e3);
+ return e1
+ }"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?e1 = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and element_ptr="?e1"])
+ by code_simp+
+qed
+
+lemma assigned_nodes_not_weakly_dom_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder},
+'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and
+ node_ptr and nodes and h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> assigned_nodes node_ptr \<rightarrow>\<^sub>r nodes \<rightarrow>\<^sub>h h'" and
+ "\<not> is_weakly_dom_component_safe {cast node_ptr} (cast ` set nodes) h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder},
+'Shadowroot::{equal,linorder}) heap"
+ let ?P = "do {
+ document_ptr \<leftarrow> create_document;
+ html \<leftarrow> create_element document_ptr ''html'';
+ append_child (cast document_ptr) (cast html);
+ head \<leftarrow> create_element document_ptr ''head'';
+ append_child (cast html) (cast head);
+ body \<leftarrow> create_element document_ptr ''body'';
+ append_child (cast html) (cast body);
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast body) (cast e1);
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast e1) (cast e2);
+ s1 \<leftarrow> attach_shadow_root e1 Closed;
+ e3 \<leftarrow> create_element document_ptr ''slot'';
+ append_child (cast s1) (cast e3);
+ return e3
+ }"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?e3 = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and node_ptr="?e3"])
+ by code_simp+
+qed
+
+lemma get_composed_root_node_not_weakly_dom_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and
+ ptr and root and h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> get_root_node_si ptr \<rightarrow>\<^sub>r root \<rightarrow>\<^sub>h h'" and
+ "\<not> is_weakly_dom_component_safe {ptr} {root} h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder},
+'Shadowroot::{equal,linorder}) heap"
+ let ?P = "do {
+ document_ptr \<leftarrow> create_document;
+ html \<leftarrow> create_element document_ptr ''html'';
+ append_child (cast document_ptr) (cast html);
+ head \<leftarrow> create_element document_ptr ''head'';
+ append_child (cast html) (cast head);
+ body \<leftarrow> create_element document_ptr ''body'';
+ append_child (cast html) (cast body);
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast body) (cast e1);
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast e1) (cast e2);
+ s1 \<leftarrow> attach_shadow_root e1 Closed;
+ e3 \<leftarrow> create_element document_ptr ''slot'';
+ append_child (cast s1) (cast e3);
+ return e3
+ }"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?e3 = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and ptr="cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ?e3"])
+ by code_simp+
+qed
+
+lemma assigned_slot_not_weakly_dom_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder},
+'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and
+ node_ptr and slot_opt and h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> assigned_slot node_ptr \<rightarrow>\<^sub>r slot_opt \<rightarrow>\<^sub>h h'" and
+ "\<not> is_weakly_dom_component_safe {cast node_ptr} (cast ` set_option slot_opt) h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder},
+ 'Shadowroot::{equal,linorder}) heap"
+ let ?P = "do {
+ document_ptr \<leftarrow> create_document;
+ html \<leftarrow> create_element document_ptr ''html'';
+ append_child (cast document_ptr) (cast html);
+ head \<leftarrow> create_element document_ptr ''head'';
+ append_child (cast html) (cast head);
+ body \<leftarrow> create_element document_ptr ''body'';
+ append_child (cast html) (cast body);
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast body) (cast e1);
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast e1) (cast e2);
+ s1 \<leftarrow> attach_shadow_root e1 Open;
+ e3 \<leftarrow> create_element document_ptr ''slot'';
+ append_child (cast s1) (cast e3);
+ return e2
+ }"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?e2 = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and node_ptr="cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ?e2"])
+ by code_simp+
+qed
+
+locale l_assigned_nodes_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_tag_name +
+ l_get_child_nodes +
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_find_slot\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_assigned_nodes_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_child_wf2 +
+ l_insert_before_wf +
+ l_insert_before_wf2 +
+ l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_append_child_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_disconnected_nodes_get_tag_name +
+ l_set_shadow_root_get_child_nodes +
+ l_set_child_nodes_get_tag_name +
+ l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_shadow_root_get_tag_name +
+ l_set_disconnected_nodes_get_shadow_root +
+ l_set_child_nodes_get_shadow_root +
+ l_remove_shadow_root_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma find_slot_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> find_slot open_flag node_ptr \<rightarrow>\<^sub>r Some slot"
+ shows "set |h \<turnstile> get_dom_component (cast node_ptr)|\<^sub>r \<inter> set |h \<turnstile> get_dom_component (cast slot)|\<^sub>r = {}"
+proof -
+ obtain host shadow_root_ptr to where
+ "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r Some (cast host)" and
+ "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr" and
+ "h \<turnstile> to_tree_order (cast shadow_root_ptr) \<rightarrow>\<^sub>r to" and
+ "cast slot \<in> set to"
+ using assms(4)
+ apply(auto simp add: find_slot_def first_in_tree_order_def elim!: bind_returns_result_E2
+ map_filter_M_pure_E[where y=slot] split: option.splits if_splits list.splits intro!: map_filter_M_pure
+ bind_pure_I)[1]
+ by (metis element_ptr_casts_commute3)+
+
+ have "node_ptr |\<in>| node_ptr_kinds h"
+ using assms(4) find_slot_ptr_in_heap by blast
+ then obtain node_ptr_c where node_ptr_c: "h \<turnstile> get_dom_component (cast node_ptr) \<rightarrow>\<^sub>r node_ptr_c"
+ using assms(1) assms(2) assms(3) get_dom_component_ok is_OK_returns_result_E
+ node_ptr_kinds_commutes[symmetric]
+ by metis
+
+ then have "cast host \<in> set node_ptr_c"
+ using \<open>h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r Some (cast host)\<close> get_dom_component_parent_inside assms(1)
+ assms(2) assms(3) get_dom_component_ptr
+ by blast
+
+ then have "h \<turnstile> get_dom_component (cast host) \<rightarrow>\<^sub>r node_ptr_c"
+ using \<open>h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r Some (cast host)\<close> get_dom_component_subset a_heap_is_wellformed_def
+ assms(1) assms(2) assms(3) node_ptr_c
+ by blast
+
+ moreover have "slot |\<in>| element_ptr_kinds h"
+ using assms(4) find_slot_slot_in_heap by blast
+ then obtain slot_c where slot_c: "h \<turnstile> get_dom_component (cast slot) \<rightarrow>\<^sub>r slot_c"
+ using a_heap_is_wellformed_def assms(1) assms(2) assms(3) get_dom_component_ok is_OK_returns_result_E
+ node_ptr_kinds_commutes[symmetric] element_ptr_kinds_commutes[symmetric]
+ by metis
+ then have "cast shadow_root_ptr \<in> set slot_c"
+ using \<open>h \<turnstile> to_tree_order (cast shadow_root_ptr) \<rightarrow>\<^sub>r to\<close> \<open>cast slot \<in> set to\<close> get_dom_component_to_tree_order
+ assms(1) assms(2) assms(3) get_dom_component_ptr
+ by blast
+ then have "h \<turnstile> get_dom_component (cast shadow_root_ptr) \<rightarrow>\<^sub>r slot_c"
+ using \<open>h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr\<close> get_dom_component_subset assms(1) assms(2)
+ assms(3) slot_c
+ by blast
+
+ ultimately show ?thesis
+ using get_shadow_root_is_component_unsafe assms \<open>h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr\<close>
+ node_ptr_c slot_c
+ by fastforce
+qed
+
+
+lemma assigned_nodes_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> assigned_nodes element_ptr \<rightarrow>\<^sub>r nodes"
+ assumes "node_ptr \<in> set nodes"
+ shows "set |h \<turnstile> get_dom_component (cast element_ptr)|\<^sub>r \<inter> set |h \<turnstile> get_dom_component (cast node_ptr)|\<^sub>r = {}"
+proof -
+ have "h \<turnstile> find_slot False node_ptr \<rightarrow>\<^sub>r Some element_ptr"
+ using assms(4) assms(5)
+ by(auto simp add: assigned_nodes_def elim!: bind_returns_result_E2
+ dest!: filter_M_holds_for_result[where x=node_ptr] intro!: bind_pure_I split: if_splits)
+ then show ?thesis
+ using assms find_slot_is_component_unsafe
+ by blast
+qed
+
+lemma flatten_dom_assigned_nodes_become_children:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> flatten_dom \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> assigned_nodes slot \<rightarrow>\<^sub>r nodes"
+ assumes "nodes \<noteq> []"
+ shows "h' \<turnstile> get_child_nodes (cast slot) \<rightarrow>\<^sub>r nodes"
+proof -
+ obtain tups h2 element_ptrs shadow_root_ptrs where
+ "h \<turnstile> element_ptr_kinds_M \<rightarrow>\<^sub>r element_ptrs" and
+ tups: "h \<turnstile> map_filter_M2 (\<lambda>element_ptr. do {
+ tag \<leftarrow> get_tag_name element_ptr;
+ assigned_nodes \<leftarrow> assigned_nodes element_ptr;
+ (if tag = ''slot'' \<and> assigned_nodes \<noteq> [] then return (Some (element_ptr, assigned_nodes))
+else return None)}) element_ptrs \<rightarrow>\<^sub>r tups" (is "h \<turnstile> map_filter_M2 ?f element_ptrs \<rightarrow>\<^sub>r tups") and
+ h2: "h \<turnstile> forall_M (\<lambda>(slot, assigned_nodes). do {
+ get_child_nodes (cast slot) \<bind> forall_M remove;
+ forall_M (append_child (cast slot)) assigned_nodes
+ }) tups \<rightarrow>\<^sub>h h2" and
+ "h2 \<turnstile> shadow_root_ptr_kinds_M \<rightarrow>\<^sub>r shadow_root_ptrs" and
+ h': "h2 \<turnstile> forall_M (\<lambda>shadow_root_ptr. do {
+ host \<leftarrow> get_host shadow_root_ptr;
+ get_child_nodes (cast host) \<bind> forall_M remove;
+ get_child_nodes (cast shadow_root_ptr) \<bind> forall_M (append_child (cast host));
+ remove_shadow_root host
+ }) shadow_root_ptrs \<rightarrow>\<^sub>h h'"
+ using \<open>h \<turnstile> flatten_dom \<rightarrow>\<^sub>h h'\<close>
+ apply(auto simp add: flatten_dom_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF ElementMonad.ptr_kinds_M_pure, rotated]
+ bind_returns_heap_E2[rotated, OF ShadowRootMonad.ptr_kinds_M_pure, rotated])[1]
+ apply(drule pure_returns_heap_eq)
+ by(auto intro!: map_filter_M2_pure bind_pure_I)
+
+ have all_tups_slot: "\<And>slot assigned_nodes. (slot, assigned_nodes) \<in> set tups \<Longrightarrow>
+h \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using tups
+ apply(induct element_ptrs arbitrary: tups)
+ by(auto elim!: bind_returns_result_E2 split: if_splits intro!: map_filter_M2_pure bind_pure_I)
+
+ have "distinct element_ptrs"
+ using \<open>h \<turnstile> element_ptr_kinds_M \<rightarrow>\<^sub>r element_ptrs\<close>
+ by auto
+ then
+ have "distinct tups"
+ using tups
+ apply(induct element_ptrs arbitrary: tups)
+ by(auto elim!: bind_returns_result_E2 intro!: map_filter_M2_pure bind_pure_I
+ split: option.splits if_splits intro: map_filter_pure_foo[rotated] )
+
+
+ have "slot \<in> set element_ptrs"
+ using assms(5) assigned_nodes_ptr_in_heap \<open>h \<turnstile> element_ptr_kinds_M \<rightarrow>\<^sub>r element_ptrs\<close>
+ by auto
+ then
+ have "(slot, nodes) \<in> set tups"
+ apply(rule map_filter_M2_in_result[OF tups])
+ apply(auto intro!: bind_pure_I)[1]
+ apply(intro bind_pure_returns_result_I)
+ using assms assigned_nodes_slot_is_slot
+ by(auto intro!: bind_pure_returns_result_I)
+
+ have "\<And>slot nodes. (slot, nodes) \<in> set tups \<Longrightarrow> h \<turnstile> assigned_nodes slot \<rightarrow>\<^sub>r nodes"
+ using tups
+ apply(induct element_ptrs arbitrary: tups)
+ by(auto elim!: bind_returns_result_E2 intro!: map_filter_M2_pure bind_pure_I split: if_splits)
+ then
+ have elementwise_eq: "\<And>slot slot' nodes nodes'. (slot, nodes) \<in> set tups \<Longrightarrow>
+(slot', nodes') \<in> set tups \<Longrightarrow> slot = slot' \<Longrightarrow> nodes = nodes'"
+ by (meson returns_result_eq)
+
+ have "\<And>slot nodes. (slot, nodes) \<in> set tups \<Longrightarrow> distinct nodes"
+ using \<open>\<And>slot nodes. (slot, nodes) \<in> set tups \<Longrightarrow> h \<turnstile> assigned_nodes slot \<rightarrow>\<^sub>r nodes\<close> assigned_nodes_distinct
+ using assms(1) by blast
+
+ have "\<And>slot slot' nodes nodes'. (slot, nodes) \<in> set tups \<Longrightarrow> (slot', nodes') \<in> set tups \<Longrightarrow> slot \<noteq> slot' \<Longrightarrow> set nodes \<inter> set nodes' = {}"
+ using \<open>\<And>slot nodes. (slot, nodes) \<in> set tups \<Longrightarrow> h \<turnstile> assigned_nodes slot \<rightarrow>\<^sub>r nodes\<close>
+ assigned_nodes_different_ptr assms(1) assms(2) assms(3) by blast
+
+ have "h \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using \<open>(slot, nodes) \<in> set tups\<close> all_tups_slot by blast
+ then have "h2 \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using h2
+ proof(induct tups arbitrary: h, simp)
+ case (Cons x xs)
+ obtain xc ha hb slot' nodes' where
+ "x = (slot', nodes')" and
+ "h \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot') \<rightarrow>\<^sub>r xc" and
+ ha: "h \<turnstile> forall_M remove xc \<rightarrow>\<^sub>h ha" and
+ hb: "ha \<turnstile> forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot')) nodes' \<rightarrow>\<^sub>h hb" and
+ remainder: "hb \<turnstile> forall_M (\<lambda>(slot, assigned_nodes). Heap_Error_Monad.bind
+(get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot))
+(\<lambda>x. Heap_Error_Monad.bind (forall_M remove x)
+(\<lambda>_. forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot)) assigned_nodes))) xs \<rightarrow>\<^sub>h h2"
+ using Cons(3)
+ by (auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ bind_returns_result_E bind_returns_result_E2[rotated, OF get_child_nodes_pure, rotated] split: prod.splits)
+
+ have "ha \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using \<open>h \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''\<close> ha
+ proof(induct xc arbitrary: h, simp)
+ case (Cons a yc)
+ obtain hb1 where
+ hb1: "h \<turnstile> remove a \<rightarrow>\<^sub>h hb1" and
+ hba: "hb1 \<turnstile> forall_M remove yc \<rightarrow>\<^sub>h ha"
+ using Cons
+ by (auto elim!: bind_returns_heap_E)
+ have "hb1 \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using \<open>h \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''\<close> hb1
+ by(auto simp add: CD.remove_child_locs_def set_child_nodes_get_tag_name
+ set_disconnected_nodes_get_tag_name dest!: reads_writes_separate_forwards[OF get_tag_name_reads
+ CD.remove_writes])
+ then show ?case
+ using hba Cons(1) by simp
+ qed
+ then
+ have "hb \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using hb
+ proof (induct nodes' arbitrary: ha, simp)
+ case (Cons a nodes')
+ obtain ha1 where
+ ha1: "ha \<turnstile> append_child (cast slot') a \<rightarrow>\<^sub>h ha1" and
+ hb: "ha1 \<turnstile> forall_M (append_child (cast slot')) nodes' \<rightarrow>\<^sub>h hb"
+ using Cons
+ by (auto elim!: bind_returns_heap_E)
+ have "ha1 \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using \<open>ha \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''\<close> ha1
+ by(auto simp add: append_child_def insert_before_locs_def adopt_node_locs_def
+ CD.adopt_node_locs_def CD.remove_child_locs_def set_child_nodes_get_tag_name
+ set_disconnected_nodes_get_tag_name dest!: reads_writes_separate_forwards[OF get_tag_name_reads
+ insert_before_writes] split: if_splits)
+ then show ?case
+ using ha1 hb Cons(1)
+ by simp
+ qed
+ then
+ show ?case
+ using Cons(1) remainder by simp
+ qed
+
+ have "h2 \<turnstile> get_child_nodes (cast slot) \<rightarrow>\<^sub>r nodes \<and> heap_is_wellformed h2 \<and> type_wf h2 \<and> known_ptrs h2"
+ using \<open>(slot, nodes) \<in> set tups\<close>
+ using h2 assms(1) assms(2) assms(3) \<open>distinct tups\<close> all_tups_slot elementwise_eq
+ using \<open>\<And>slot slot' assigned_nodes nodes'. (slot, assigned_nodes) \<in> set tups \<Longrightarrow>
+(slot', nodes') \<in> set tups \<Longrightarrow> slot \<noteq> slot' \<Longrightarrow> set assigned_nodes \<inter> set nodes' = {}\<close>
+ using \<open>\<And>slot assigned_nodes. (slot, assigned_nodes) \<in> set tups \<Longrightarrow> distinct assigned_nodes\<close>
+ proof(induct tups arbitrary: h, simp)
+ case (Cons x xs)
+ obtain xc ha hb slot' nodes' where
+ "x = (slot', nodes')" and
+ "h \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot') \<rightarrow>\<^sub>r xc" and
+ ha: "h \<turnstile> forall_M remove xc \<rightarrow>\<^sub>h ha" and
+ hb: "ha \<turnstile> forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot')) nodes' \<rightarrow>\<^sub>h hb" and
+ remainder: "hb \<turnstile> forall_M (\<lambda>(slot, assigned_nodes). Heap_Error_Monad.bind
+(get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot)) (\<lambda>x. Heap_Error_Monad.bind (forall_M remove x)
+(\<lambda>_. forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot)) assigned_nodes))) xs \<rightarrow>\<^sub>h h2"
+ using Cons(3)
+ by (auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ bind_returns_result_E bind_returns_result_E2[rotated, OF get_child_nodes_pure, rotated]
+ split: prod.splits)
+
+ have "\<And>slot assigned_nodes. (slot, assigned_nodes) \<in> set xs \<Longrightarrow> h \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using Cons by auto
+
+ have "heap_is_wellformed ha" and "type_wf ha" and "known_ptrs ha"
+ using Cons(4) Cons(5) Cons(6) \<open>h \<turnstile> forall_M remove xc \<rightarrow>\<^sub>h ha\<close>
+ apply(induct xc arbitrary: h)
+ apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ simp add: CD.remove_def split: option.splits)[1]
+ apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ simp add: CD.remove_def split: option.splits)[1]
+ apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ simp add: CD.remove_def split: option.splits)[1]
+ apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ simp add: CD.remove_def split: option.splits)[1]
+ using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs
+ apply metis
+ apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ simp add: CD.remove_def split: option.splits)[1]
+ using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs
+ apply metis
+ apply(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ simp add: CD.remove_def split: option.splits)[1]
+ using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf remove_child_preserves_known_ptrs
+ apply metis
+ done
+ then
+ have "heap_is_wellformed hb" and "type_wf hb" and "known_ptrs hb"
+ using \<open>ha \<turnstile> forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot')) nodes' \<rightarrow>\<^sub>h hb\<close>
+ apply(induct nodes' arbitrary: ha)
+ apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1]
+ apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1]
+ apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1]
+ apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1]
+ using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs
+ apply metis
+ apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1]
+ using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs
+ apply metis
+ apply(auto elim!: bind_returns_heap_E simp add: append_child_def)[1]
+ using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs
+ apply metis
+ done
+
+ {
+ fix slot assigned_nodes
+ assume "(slot, assigned_nodes) \<in> set xs"
+ then have "h \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using \<open>\<And>slot assigned_nodes. (slot, assigned_nodes) \<in> set xs \<Longrightarrow> h \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''\<close>
+ by auto
+ then have "ha \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using \<open>h \<turnstile> forall_M remove xc \<rightarrow>\<^sub>h ha\<close>
+ apply(induct xc arbitrary: h)
+ by(auto simp add: CD.remove_child_locs_def set_child_nodes_get_tag_name set_disconnected_nodes_get_tag_name
+ dest!: reads_writes_separate_forwards[OF get_tag_name_reads CD.remove_writes]
+ elim!: bind_returns_heap_E)
+ then have "hb \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using \<open>ha \<turnstile> forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot')) nodes' \<rightarrow>\<^sub>h hb\<close>
+ apply(induct nodes' arbitrary: ha)
+ by(auto simp add: append_child_def insert_before_locs_def adopt_node_locs_def CD.adopt_node_locs_def
+ CD.remove_child_locs_def set_child_nodes_get_tag_name set_disconnected_nodes_get_tag_name
+ dest!: reads_writes_separate_forwards[OF get_tag_name_reads insert_before_writes]
+ elim!: bind_returns_heap_E
+ split: if_splits)
+ } note tag_names_same = this
+
+ show ?case
+ proof(cases "slot' = slot")
+ case True
+ then
+ have "nodes' = nodes"
+ using Cons.prems(1) Cons.prems(8) \<open>x = (slot', nodes')\<close>
+ by (metis list.set_intros(1))
+ then
+ have "(slot, nodes) \<notin> set xs"
+ using Cons.prems(6) True \<open>x = (slot', nodes')\<close> by auto
+
+ have "ha \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r []"
+ using remove_for_all_empty_children Cons.prems(3) Cons.prems(4) Cons.prems(5)
+ True \<open>h \<turnstile> forall_M remove xc \<rightarrow>\<^sub>h ha\<close>
+ using \<open>h \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot') \<rightarrow>\<^sub>r xc\<close>
+ by blast
+ then
+ have "hb \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes"
+ using append_child_for_all_on_no_children[OF \<open>heap_is_wellformed hb\<close> \<open>type_wf hb\<close> \<open>known_ptrs hb\<close>]
+ True \<open>nodes' = nodes\<close>
+ using \<open>ha \<turnstile> forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot')) nodes' \<rightarrow>\<^sub>h hb\<close>
+ using \<open>(slot, nodes) \<in> set tups\<close> \<open>\<And>slot assigned_nodes. (slot, assigned_nodes) \<in> set tups \<Longrightarrow>
+distinct assigned_nodes\<close> \<open>heap_is_wellformed ha\<close> \<open>known_ptrs ha\<close> \<open>type_wf ha\<close> local.append_child_for_all_on_no_children
+ by blast
+ with \<open>heap_is_wellformed hb\<close> and \<open>type_wf hb\<close> and \<open>known_ptrs hb\<close>
+ show ?thesis
+ using \<open>(slot, nodes) \<notin> set xs\<close> remainder
+ using \<open>\<And>slot slot' assigned_nodes nodes'. (slot, assigned_nodes) \<in> set (x#xs) \<Longrightarrow>
+(slot', nodes') \<in> set (x#xs) \<Longrightarrow> slot = slot' \<Longrightarrow> assigned_nodes = nodes'\<close>
+ using \<open>(slot, nodes) \<in> set (x # xs)\<close>
+ using \<open>\<And>slot slot' assigned_nodes nodes'. (slot, assigned_nodes) \<in> set (x#xs) \<Longrightarrow>
+(slot', nodes') \<in> set (x#xs) \<Longrightarrow> slot \<noteq> slot' \<Longrightarrow> set assigned_nodes \<inter> set nodes' = {}\<close>
+ proof(induct xs arbitrary: hb, simp)
+ case (Cons y ys)
+ obtain yc hba hbb slot'' nodes'' where
+ "y = (slot'', nodes'')" and
+ "hb \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'') \<rightarrow>\<^sub>r yc" and
+ "hb \<turnstile> forall_M remove yc \<rightarrow>\<^sub>h hba" and
+ "hba \<turnstile> forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'')) nodes'' \<rightarrow>\<^sub>h hbb" and
+ remainder: "hbb \<turnstile> forall_M (\<lambda>(slot, assigned_nodes).
+Heap_Error_Monad.bind (get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot))
+(\<lambda>x. Heap_Error_Monad.bind (forall_M remove x)
+(\<lambda>_. forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot)) assigned_nodes))) ys \<rightarrow>\<^sub>h h2"
+ using Cons(7)
+ by (auto elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated] split: prod.splits)
+
+ have "slot \<noteq> slot''"
+ by (metis Cons.prems(5) Cons.prems(7) Cons.prems(8) \<open>y = (slot'', nodes'')\<close>
+ list.set_intros(1) list.set_intros(2))
+ then have "set nodes \<inter> set nodes'' = {}"
+ by (metis Cons.prems(8) Cons.prems(9) \<open>y = (slot'', nodes'')\<close> list.set_intros(1)
+ list.set_intros(2))
+
+ have "hba \<turnstile> get_child_nodes (cast slot) \<rightarrow>\<^sub>r nodes \<and> heap_is_wellformed hba \<and> type_wf hba \<and> known_ptrs hba"
+ using \<open>hb \<turnstile> get_child_nodes (cast slot) \<rightarrow>\<^sub>r nodes\<close>
+ using \<open>hb \<turnstile> forall_M remove yc \<rightarrow>\<^sub>h hba\<close>
+ using \<open>hb \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'') \<rightarrow>\<^sub>r yc\<close>
+ using \<open>heap_is_wellformed hb\<close> \<open>type_wf hb\<close> \<open>known_ptrs hb\<close>
+ proof(induct yc arbitrary: hb, simp)
+ case (Cons a yc)
+ obtain hb1 where
+ hb1: "hb \<turnstile> remove a \<rightarrow>\<^sub>h hb1" and
+ hba: "hb1 \<turnstile> forall_M remove yc \<rightarrow>\<^sub>h hba"
+ using Cons
+ by (auto elim!: bind_returns_heap_E)
+ have "hb \<turnstile> get_parent a \<rightarrow>\<^sub>r Some (cast slot'')"
+ using Cons.prems(3) Cons.prems(4) Cons.prems(5) Cons.prems(6) local.child_parent_dual
+ by auto
+
+ moreover
+ have "heap_is_wellformed hb1" and "type_wf hb1" and "known_ptrs hb1"
+ using \<open>hb \<turnstile> remove a \<rightarrow>\<^sub>h hb1\<close> Cons.prems(4) Cons.prems(5) Cons.prems(6)
+ local.remove_child_heap_is_wellformed_preserved
+ apply(auto simp add: CD.remove_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1]
+ using Cons.prems(4) Cons.prems(5) Cons.prems(6) hb1 local.remove_preserves_type_wf
+ apply blast
+ using Cons.prems(4) Cons.prems(5) Cons.prems(6) hb1 local.remove_preserves_known_ptrs
+ by blast
+ moreover have "hb1 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'') \<rightarrow>\<^sub>r yc"
+ using \<open>hb \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'') \<rightarrow>\<^sub>r a # yc\<close> hb1
+ using remove_removes_child \<open>heap_is_wellformed hb\<close> \<open>type_wf hb\<close> \<open>known_ptrs hb\<close>
+ by simp
+ moreover have "hb1 \<turnstile> get_child_nodes (cast slot) \<rightarrow>\<^sub>r nodes"
+ using Cons(2) hb1 CD.set_child_nodes_get_child_nodes_different_pointers
+ \<open>hb \<turnstile> get_parent a \<rightarrow>\<^sub>r Some (cast slot'')\<close> \<open>slot \<noteq> slot''\<close>
+ apply(auto simp add: CD.remove_child_locs_def elim!: bind_returns_heap_E
+ dest!: reads_writes_separate_forwards[OF get_child_nodes_reads CD.remove_writes])[1]
+ by (metis cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject)
+ ultimately show ?thesis
+ using \<open>hb1 \<turnstile> forall_M remove (yc) \<rightarrow>\<^sub>h hba\<close> Cons
+ by auto
+ qed
+
+
+ then have "hbb \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes \<and>
+heap_is_wellformed hbb \<and> type_wf hbb \<and> known_ptrs hbb"
+ using \<open>hba \<turnstile> forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'')) nodes'' \<rightarrow>\<^sub>h hbb\<close>
+ using \<open>set nodes \<inter> set nodes'' = {}\<close>
+ proof(induct nodes'' arbitrary: hba, simp)
+ case (Cons a nodes'')
+ then have "hba \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes" and
+ "heap_is_wellformed hba" and
+ "type_wf hba" and
+ "known_ptrs hba"
+ by auto
+ obtain hba1 where
+ hba1: "hba \<turnstile> append_child (cast slot'') a \<rightarrow>\<^sub>h hba1" and
+ "hba1 \<turnstile> forall_M (append_child (cast slot'')) nodes'' \<rightarrow>\<^sub>h hbb"
+ using Cons(3)
+ by (auto elim!: bind_returns_heap_E)
+
+ have "heap_is_wellformed hba1" and "type_wf hba1" and "known_ptrs hba1"
+ using Cons.prems(1) hba1 local.append_child_heap_is_wellformed_preserved(1)
+ apply blast
+ using \<open>heap_is_wellformed hba\<close> \<open>known_ptrs hba\<close> \<open>type_wf hba\<close> hba1 local.append_child_preserves_type_wf
+ apply blast
+ using Cons.prems(1) hba1 local.append_child_preserves_known_ptrs
+ by blast
+
+ moreover
+ have "a \<notin> set nodes"
+ using \<open>set nodes \<inter> set (a # nodes'') = {}\<close>
+ by auto
+
+
+ moreover
+ obtain parent_opt where "hba \<turnstile> get_parent a \<rightarrow>\<^sub>r parent_opt"
+ using insert_before_child_in_heap hba1 get_parent_ok unfolding append_child_def
+ by (meson Cons.prems(1) is_OK_returns_heap_I is_OK_returns_result_E)
+ then
+ have "hba1 \<turnstile> get_child_nodes (cast slot) \<rightarrow>\<^sub>r nodes"
+ proof (induct parent_opt)
+ case None
+ then show ?case
+ using \<open>hba \<turnstile> append_child (cast slot'') a \<rightarrow>\<^sub>h hba1\<close>
+ using \<open>hba \<turnstile> get_child_nodes (cast slot) \<rightarrow>\<^sub>r nodes\<close>
+ using \<open>slot \<noteq> slot''\<close>
+ apply(auto simp add: append_child_def insert_before_locs_def adopt_node_locs_def
+ CD.adopt_node_locs_def remove_child_locs_def elim!: reads_writes_separate_forwards[OF get_child_nodes_reads
+ insert_before_writes])[1]
+ by (metis cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject
+ CD.set_child_nodes_get_child_nodes_different_pointers)
+ next
+ case (Some parent)
+ have "parent \<noteq> cast slot"
+ apply(rule ccontr, simp)
+ using Cons(2)
+ apply -
+ apply(rule get_parent_child_dual[OF \<open>hba \<turnstile> get_parent a \<rightarrow>\<^sub>r Some parent\<close>])
+ apply(auto)[1]
+ using \<open>a \<notin> set nodes\<close> returns_result_eq
+ by fastforce
+ show ?case
+ apply(rule reads_writes_separate_forwards)
+ apply(fact get_child_nodes_reads)
+ apply(fact insert_before_writes)
+ apply(fact \<open>hba \<turnstile> append_child (cast slot'') a \<rightarrow>\<^sub>h hba1\<close>[unfolded append_child_def])
+ apply(fact \<open>hba \<turnstile> get_child_nodes (cast slot) \<rightarrow>\<^sub>r nodes\<close>)
+ using \<open>hba \<turnstile> get_parent a \<rightarrow>\<^sub>r Some parent\<close> \<open>parent \<noteq> cast slot\<close> \<open>slot \<noteq> slot''\<close>
+ apply(auto simp add: insert_before_locs_def adopt_node_locs_def CD.adopt_node_locs_def
+ CD.remove_child_locs_def)[1]
+ apply (simp_all add: CD.set_child_nodes_get_child_nodes_different_pointers
+ CD.set_disconnected_nodes_get_child_nodes)
+ by (metis cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject
+ CD.set_child_nodes_get_child_nodes_different_pointers)
+ qed
+ moreover
+ have "set nodes \<inter> set nodes'' = {}"
+ using Cons.prems(3) by auto
+ ultimately show ?case
+ using Cons.hyps \<open>hba1 \<turnstile> forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot'')) nodes'' \<rightarrow>\<^sub>h hbb\<close>
+ by blast
+ qed
+ show ?case
+ apply(rule Cons(1))
+ using \<open>hbb \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes \<and>
+heap_is_wellformed hbb \<and> type_wf hbb \<and> known_ptrs hbb\<close>
+ apply(auto)[1]
+ using \<open>hbb \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes \<and>
+heap_is_wellformed hbb \<and> type_wf hbb \<and> known_ptrs hbb\<close>
+ apply(auto)[1]
+ using \<open>hbb \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes \<and>
+heap_is_wellformed hbb \<and> type_wf hbb \<and> known_ptrs hbb\<close>
+ apply(auto)[1]
+ using \<open>hbb \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes \<and>
+heap_is_wellformed hbb \<and> type_wf hbb \<and> known_ptrs hbb\<close>
+ apply(auto)[1]
+ using Cons.prems(5) apply auto[1]
+ apply (simp add: remainder)
+ using Cons.prems(7) apply auto[1]
+ apply (simp add: True \<open>nodes' = nodes\<close> \<open>x = (slot', nodes')\<close>)
+ by (metis Cons.prems(9) insert_iff list.simps(15))
+ qed
+ next
+ case False
+ then have "nodes' \<noteq> nodes"
+ using Cons.prems(1) Cons.prems(9) \<open>x = (slot', nodes')\<close>
+ by (metis assms(6) inf.idem list.set_intros(1) set_empty2)
+ then
+ have "(slot, nodes) \<in> set xs"
+ using Cons.prems(1) \<open>x = (slot', nodes')\<close>
+ by auto
+ then show ?thesis
+ using Cons(1)[simplified, OF \<open>(slot, nodes) \<in> set xs\<close> remainder
+ \<open>heap_is_wellformed hb\<close> \<open>type_wf hb\<close> \<open>known_ptrs hb\<close>]
+ using Cons.prems(6) tag_names_same Cons.prems(8) Cons.prems(9)
+ by (smt Cons.prems(10) distinct.simps(2) list.set_intros(2))
+ qed
+ qed
+ then
+ show ?thesis
+ using h' \<open>h2 \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''\<close>
+ proof(induct shadow_root_ptrs arbitrary: h2, simp)
+ case (Cons shadow_root_ptr shadow_root_ptrs)
+ then have "h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes" and
+ "heap_is_wellformed h2" and
+ "type_wf h2" and
+ "known_ptrs h2"
+ by auto
+ obtain host h2a h2b h2c host_children shadow_root_children where
+ "h2 \<turnstile> get_host shadow_root_ptr \<rightarrow>\<^sub>r host" and
+ "h2 \<turnstile> get_child_nodes (cast host) \<rightarrow>\<^sub>r host_children" and
+ h2a: "h2 \<turnstile> forall_M remove host_children \<rightarrow>\<^sub>h h2a" and
+ "h2a \<turnstile> get_child_nodes (cast shadow_root_ptr) \<rightarrow>\<^sub>r shadow_root_children" and
+ h2b: "h2a \<turnstile> forall_M (append_child (cast host)) shadow_root_children \<rightarrow>\<^sub>h h2b" and
+ "h2b \<turnstile> remove_shadow_root host \<rightarrow>\<^sub>h h2c" and
+ remainder: "h2c \<turnstile> forall_M(\<lambda>shadow_root_ptr. Heap_Error_Monad.bind (get_host shadow_root_ptr)
+ (\<lambda>host. Heap_Error_Monad.bind (get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host))
+ (\<lambda>x. Heap_Error_Monad.bind (forall_M remove x)
+ (\<lambda>_. Heap_Error_Monad.bind (get_child_nodes (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr))
+ (\<lambda>x. Heap_Error_Monad.bind (forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host)) x)
+ (\<lambda>_. remove_shadow_root host))))))
+ shadow_root_ptrs
+ \<rightarrow>\<^sub>h h'"
+ using Cons(3)
+ by(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_host_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated])
+
+
+ have "h2 \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ using \<open>h2 \<turnstile> get_host shadow_root_ptr \<rightarrow>\<^sub>r host\<close> shadow_root_host_dual
+ using \<open>heap_is_wellformed h2\<close> \<open>type_wf h2\<close> by blast
+ then have "h2a \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ using \<open>h2 \<turnstile> forall_M remove host_children \<rightarrow>\<^sub>h h2a\<close>
+ apply(induct host_children arbitrary: h2)
+ by(auto simp add: set_disconnected_nodes_get_shadow_root set_child_nodes_get_shadow_root
+ CD.remove_child_locs_def elim!: bind_returns_heap_E
+ dest!: reads_writes_separate_forwards[OF get_shadow_root_reads CD.remove_writes])
+ then have "h2b \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ using \<open>h2a \<turnstile> forall_M (append_child (cast host)) shadow_root_children \<rightarrow>\<^sub>h h2b\<close>
+ apply(induct shadow_root_children arbitrary: h2a)
+ by(auto simp add: set_disconnected_nodes_get_shadow_root set_child_nodes_get_shadow_root
+ append_child_def insert_before_locs_def adopt_node_locs_def CD.adopt_node_locs_def
+ CD.remove_child_locs_def elim!: bind_returns_heap_E
+ dest!: reads_writes_separate_forwards[OF get_shadow_root_reads insert_before_writes]
+ split: if_splits)
+
+ have "host \<noteq> slot"
+ proof (rule ccontr, simp)
+ assume "host = slot"
+ show False
+ using get_host_valid_tag_name[OF \<open>heap_is_wellformed h2\<close> \<open>type_wf h2\<close>
+ \<open>h2 \<turnstile> get_host shadow_root_ptr \<rightarrow>\<^sub>r host\<close>[unfolded \<open>host = slot\<close>] \<open>h2 \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''\<close>]
+ by(simp)
+ qed
+
+ have "heap_is_wellformed h2a" and "type_wf h2a" and "known_ptrs h2a"
+ using \<open>heap_is_wellformed h2\<close> and \<open>type_wf h2\<close> and \<open>known_ptrs h2\<close> \<open>h2 \<turnstile> forall_M remove host_children \<rightarrow>\<^sub>h h2a\<close>
+ apply(induct host_children arbitrary: h2)
+ apply(auto simp add: CD.remove_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1]
+ apply(auto simp add: CD.remove_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1]
+ apply(auto simp add: CD.remove_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1]
+ apply(auto simp add: CD.remove_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1]
+ using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf
+ remove_child_preserves_known_ptrs apply metis
+ apply(auto simp add: CD.remove_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1]
+ using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf
+ remove_child_preserves_known_ptrs apply metis
+ apply(auto simp add: CD.remove_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated] split: option.splits)[1]
+ using remove_child_heap_is_wellformed_preserved remove_child_preserves_type_wf
+ remove_child_preserves_known_ptrs apply metis
+ done
+ then
+ have "heap_is_wellformed h2b" and "type_wf h2b" and "known_ptrs h2b"
+ using \<open>h2a \<turnstile> forall_M (append_child (cast host)) shadow_root_children \<rightarrow>\<^sub>h h2b\<close>
+ apply(induct shadow_root_children arbitrary: h2a)
+ apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1]
+ apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1]
+ apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1]
+ apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1]
+ using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs
+ apply(metis)
+ apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1]
+ using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs
+ apply(metis)
+ apply(auto simp add: append_child_def elim!: bind_returns_heap_E)[1]
+ using insert_before_heap_is_wellformed_preserved insert_before_preserves_type_wf insert_before_preserves_known_ptrs
+ apply(metis)
+ done
+ then
+ have "heap_is_wellformed h2c" and "type_wf h2c" and "known_ptrs h2c"
+ using remove_shadow_root_preserves \<open>h2b \<turnstile> remove_shadow_root host \<rightarrow>\<^sub>h h2c\<close>
+ by blast+
+
+ moreover
+ have "h2a \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes"
+ using \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes\<close>
+ using \<open>h2 \<turnstile> forall_M remove host_children \<rightarrow>\<^sub>h h2a\<close>
+ using \<open>h2 \<turnstile> get_child_nodes (cast host) \<rightarrow>\<^sub>r host_children\<close>
+ using \<open>heap_is_wellformed h2\<close> \<open>type_wf h2\<close> \<open>known_ptrs h2\<close>
+ proof (induct host_children arbitrary: h2, simp)
+ case (Cons a host_children)
+ obtain h21 where "h2 \<turnstile> remove a \<rightarrow>\<^sub>h h21" and
+ "h21 \<turnstile> forall_M remove host_children \<rightarrow>\<^sub>h h2a"
+ using Cons(3)
+ by(auto elim!: bind_returns_heap_E)
+
+ have "heap_is_wellformed h21" and "type_wf h21" and "known_ptrs h21"
+ using Cons.prems(4) Cons.prems(5) Cons.prems(6) \<open>h2 \<turnstile> remove a \<rightarrow>\<^sub>h h21\<close> local.remove_heap_is_wellformed_preserved
+ apply blast
+ using Cons.prems(4) Cons.prems(5) Cons.prems(6) \<open>h2 \<turnstile> remove a \<rightarrow>\<^sub>h h21\<close> local.remove_preserves_type_wf
+ apply blast
+ using Cons.prems(4) Cons.prems(5) Cons.prems(6) \<open>h2 \<turnstile> remove a \<rightarrow>\<^sub>h h21\<close> local.remove_preserves_known_ptrs
+ by blast
+ have "h2 \<turnstile> get_parent a \<rightarrow>\<^sub>r Some (cast host)"
+ using \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) \<rightarrow>\<^sub>r a # host_children\<close>
+ using \<open>heap_is_wellformed h2\<close> \<open>type_wf h2\<close> \<open>known_ptrs h2\<close> child_parent_dual
+ using heap_is_wellformed_def by auto
+ then have "h21 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes"
+ using \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes\<close> \<open>host \<noteq> slot\<close>
+ using \<open>h2 \<turnstile> remove a \<rightarrow>\<^sub>h h21\<close>
+ apply(auto simp add: CD.remove_child_locs_def CD.set_disconnected_nodes_get_child_nodes
+ dest!: reads_writes_preserved[OF get_child_nodes_reads CD.remove_writes])[1]
+ by (meson cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject
+ CD.set_child_nodes_get_child_nodes_different_pointers)
+ moreover have "h21 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) \<rightarrow>\<^sub>r host_children"
+ using \<open>h2 \<turnstile> remove a \<rightarrow>\<^sub>h h21\<close> remove_removes_child[OF \<open>heap_is_wellformed h2\<close> \<open>type_wf h2\<close>
+ \<open>known_ptrs h2\<close> \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) \<rightarrow>\<^sub>r a # host_children\<close>]
+ by blast
+ ultimately show ?case
+ using \<open>heap_is_wellformed h21\<close> and \<open>type_wf h21\<close> and \<open>known_ptrs h21\<close>
+ \<open>h21 \<turnstile> forall_M remove host_children \<rightarrow>\<^sub>h h2a\<close> Cons(1)
+ using Cons.prems(3) Cons.prems(4) Cons.prems(5) Cons.prems(6) heap_is_wellformed_def
+ \<open>h2 \<turnstile> remove a \<rightarrow>\<^sub>h h21\<close> remove_removes_child
+ by blast
+ qed
+
+ then
+ have "h2b \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes"
+ using \<open>h2a \<turnstile> forall_M (append_child (cast host)) shadow_root_children \<rightarrow>\<^sub>h h2b\<close>
+ using \<open>h2a \<turnstile> get_child_nodes (cast shadow_root_ptr) \<rightarrow>\<^sub>r shadow_root_children\<close>
+ using \<open>heap_is_wellformed h2a\<close> \<open>type_wf h2a\<close> \<open>known_ptrs h2a\<close>
+ proof(induct shadow_root_children arbitrary: h2a, simp)
+ case (Cons a shadow_root_children)
+ obtain h2a1 where "h2a \<turnstile> append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) a \<rightarrow>\<^sub>h h2a1" and
+ "h2a1 \<turnstile> forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host)) (shadow_root_children) \<rightarrow>\<^sub>h h2b"
+ using Cons(3)
+ by(auto elim!: bind_returns_heap_E)
+
+ have "heap_is_wellformed h2a1" and "type_wf h2a1" and "known_ptrs h2a1"
+ using Cons.prems(4) Cons.prems(5) Cons.prems(6) \<open>h2a \<turnstile> append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) a \<rightarrow>\<^sub>h h2a1\<close>
+ local.append_child_heap_is_wellformed_preserved by blast+
+ moreover have "h2a1 \<turnstile> get_child_nodes (cast shadow_root_ptr) \<rightarrow>\<^sub>r shadow_root_children"
+ using \<open>h2a \<turnstile> get_child_nodes (cast shadow_root_ptr) \<rightarrow>\<^sub>r a # shadow_root_children\<close>
+ using insert_before_removes_child \<open>h2a \<turnstile> append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) a \<rightarrow>\<^sub>h h2a1\<close>[unfolded append_child_def]
+ using \<open>heap_is_wellformed h2a\<close> \<open>type_wf h2a\<close> \<open>known_ptrs h2a\<close>
+ using cast_document_ptr_not_node_ptr(2) by blast
+ moreover have "h2a \<turnstile> get_parent a \<rightarrow>\<^sub>r Some (cast shadow_root_ptr)"
+ using \<open>h2a \<turnstile> get_child_nodes (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) \<rightarrow>\<^sub>r a # shadow_root_children\<close>
+ using \<open>heap_is_wellformed h2a\<close> \<open>type_wf h2a\<close> \<open>known_ptrs h2a\<close> child_parent_dual
+ using heap_is_wellformed_def by auto
+ then have "h2a1 \<turnstile> get_child_nodes (cast slot) \<rightarrow>\<^sub>r nodes"
+ using \<open>h2a \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes\<close>
+ using \<open>h2a \<turnstile> append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) a \<rightarrow>\<^sub>h h2a1\<close> \<open>host \<noteq> slot\<close>
+ apply(auto simp add: set_disconnected_nodes_get_child_nodes append_child_def
+ insert_before_locs_def adopt_node_locs_def CD.adopt_node_locs_def CD.remove_child_locs_def
+ elim!: bind_returns_heap_E dest!: reads_writes_preserved[OF get_child_nodes_reads insert_before_writes])[1]
+ using CD.set_child_nodes_get_child_nodes_different_pointers cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject
+ cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject cast_document_ptr_not_node_ptr(2)
+ by metis+
+ ultimately
+ show ?case
+ using Cons(1) \<open>h2a1 \<turnstile> forall_M (append_child (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host)) shadow_root_children \<rightarrow>\<^sub>h h2b\<close>
+ by blast
+ qed
+ then
+ have "h2c \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r slot) \<rightarrow>\<^sub>r nodes"
+ using \<open>h2b \<turnstile> remove_shadow_root host \<rightarrow>\<^sub>h h2c\<close>
+ by(auto simp add: remove_shadow_root_get_child_nodes_different_pointers[OF
+ cast_document_ptr_not_node_ptr(2)] dest!: reads_writes_separate_forwards[OF get_child_nodes_reads
+ remove_shadow_root_writes])
+
+ moreover
+ have "h2a \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using h2a \<open>h2 \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''\<close>
+ apply(induct host_children arbitrary: h2)
+ by(auto simp add: CD.remove_child_locs_def set_disconnected_nodes_get_tag_name
+ set_child_nodes_get_tag_name dest!: reads_writes_separate_forwards[OF get_tag_name_reads CD.remove_writes]
+ elim!: bind_returns_heap_E)
+ then
+ have "h2b \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using h2b
+ apply(induct shadow_root_children arbitrary: h2a)
+ by(auto simp add: append_child_def insert_before_locs_def adopt_node_locs_def
+ CD.adopt_node_locs_def CD.remove_child_locs_def set_disconnected_nodes_get_tag_name
+ set_child_nodes_get_tag_name dest!: reads_writes_separate_forwards[OF get_tag_name_reads insert_before_writes]
+ elim!: bind_returns_heap_E split: if_splits)
+ then
+ have "h2c \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using \<open>h2b \<turnstile> remove_shadow_root host \<rightarrow>\<^sub>h h2c\<close>
+ by(auto simp add: remove_shadow_root_get_tag_name dest!:
+ reads_writes_separate_forwards[OF get_tag_name_reads remove_shadow_root_writes])
+
+ ultimately show ?case
+ using Cons(1) remainder
+ by auto
+ qed
+qed
+end
+
+interpretation i_assigned_nodes_component?: l_assigned_nodes_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf get_tag_name get_tag_name_locs known_ptr get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs
+ heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document
+ get_disconnected_document_locs get_parent get_parent_locs get_mode get_mode_locs get_attribute
+ get_attribute_locs first_in_tree_order find_slot assigned_slot known_ptrs to_tree_order assigned_nodes
+ assigned_nodes_flatten flatten_dom get_root_node get_root_node_locs remove insert_before insert_before_locs
+ append_child remove_shadow_root remove_shadow_root_locs set_shadow_root set_shadow_root_locs remove_child
+ remove_child_locs get_dom_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_ancestors
+ get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name get_owner_document
+ set_disconnected_nodes set_disconnected_nodes_locs get_ancestors_di get_ancestors_di_locs
+ adopt_node adopt_node_locs adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_child_nodes set_child_nodes_locs
+ by(auto simp add: l_assigned_nodes_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_assigned_nodes_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_owner\_document\<close>
+
+locale l_get_owner_document_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_owner_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma get_owner_document_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ assumes "\<not>is_document_ptr_kind |h \<turnstile> get_root_node ptr|\<^sub>r"
+ shows "set |h \<turnstile> get_dom_component ptr|\<^sub>r \<inter> set |h \<turnstile> get_dom_component (cast owner_document)|\<^sub>r = {}"
+proof -
+ have "owner_document |\<in>| document_ptr_kinds h"
+ using assms(1) assms(2) assms(3) assms(4) get_owner_document_owner_document_in_heap by blast
+ have "ptr |\<in>| object_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_result_I local.get_owner_document_ptr_in_heap)
+ obtain root where root: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ by (meson assms(1) assms(2) assms(3) assms(4) is_OK_returns_result_I
+ local.get_owner_document_ptr_in_heap local.get_root_node_ok returns_result_select_result)
+ then obtain to where to: "h \<turnstile> to_tree_order root \<rightarrow>\<^sub>r to"
+ by (meson assms(1) assms(2) assms(3) is_OK_returns_result_E local.get_root_node_root_in_heap
+ local.to_tree_order_ok)
+ then have "\<forall>p \<in> set to. \<not>is_document_ptr_kind p"
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) assms(5) document_ptr_casts_commute3
+ local.to_tree_order_node_ptrs node_ptr_no_document_ptr_cast root select_result_I2)
+ then have "cast owner_document \<notin> set |h \<turnstile> get_dom_component ptr|\<^sub>r"
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) assms(5) document_ptr_document_ptr_cast
+ is_OK_returns_result_I l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_dom_component_ok local.get_dom_component_root_node_same
+ local.get_root_node_not_node_same local.get_root_node_ptr_in_heap local.l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms
+ node_ptr_no_document_ptr_cast returns_result_select_result root select_result_I2)
+ then have "|h \<turnstile> get_dom_component ptr|\<^sub>r \<noteq> |h \<turnstile> get_dom_component (cast owner_document)|\<^sub>r"
+ by (metis (no_types, lifting) \<open>owner_document |\<in>| document_ptr_kinds h\<close> assms(1) assms(2) assms(3)
+ document_ptr_kinds_commutes l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_dom_component_ok local.get_dom_component_ptr
+ local.l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms returns_result_select_result)
+ then show ?thesis
+ by (meson \<open>owner_document |\<in>| document_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2)
+ assms(3) document_ptr_kinds_commutes l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_dom_component_no_overlap
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_dom_component_ok local.l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms returns_result_select_result)
+qed
+
+end
+
+interpretation i_get_owner_document_component?: l_get_owner_document_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf get_disconnected_nodes get_disconnected_nodes_locs known_ptr get_child_nodes get_child_nodes_locs
+ DocumentClass.known_ptr get_parent get_parent_locs DocumentClass.type_wf get_root_node get_root_node_locs
+ CD.a_get_owner_document get_host get_host_locs get_owner_document get_shadow_root get_shadow_root_locs
+ get_tag_name get_tag_name_locs heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_disconnected_document get_disconnected_document_locs known_ptrs get_ancestors get_ancestors_locs to_tree_order
+ get_dom_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_element_by_id
+ get_elements_by_class_name get_elements_by_tag_name
+ by(auto simp add: l_get_owner_document_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_owner_document_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+definition is_shadow_root_component :: "(_) object_ptr list \<Rightarrow> bool"
+ where
+ "is_shadow_root_component c = is_shadow_root_ptr_kind (hd c)"
+
+end
diff --git a/thys/SC_DOM_Components/Shadow_DOM_SC_DOM_Components.thy b/thys/SC_DOM_Components/Shadow_DOM_SC_DOM_Components.thy
new file mode 100644
--- /dev/null
+++ b/thys/SC_DOM_Components/Shadow_DOM_SC_DOM_Components.thy
@@ -0,0 +1,1005 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section \<open>Shadow SC DOM Components II\<close>
+theory Shadow_DOM_SC_DOM_Components
+ imports
+ Core_DOM_SC_DOM_Components
+ Shadow_DOM_DOM_Components
+begin
+
+section \<open>Shadow root scope components\<close>
+
+
+subsection \<open>get\_scope\_component\<close>
+
+global_interpretation l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_owner_document get_disconnected_nodes
+ get_disconnected_nodes_locs to_tree_order
+ defines get_scdom_component = a_get_scdom_component
+ and is_strongly_scdom_component_safe = a_is_strongly_scdom_component_safe
+ and is_weakly_scdom_component_safe = a_is_weakly_scdom_component_safe
+ .
+interpretation i_get_scdom_component?: l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe
+ get_owner_document get_disconnected_nodes get_disconnected_nodes_locs to_tree_order
+ by(auto simp add: l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def get_scdom_component_def
+ is_strongly_scdom_component_safe_def is_weakly_scdom_component_safe_def instances)
+declare l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_component\<close>
+
+locale l_get_dom_component_get_scdom_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_heap_is_wellformed +
+ l_get_owner_document +
+ l_get_owner_document_wf +
+ l_get_disconnected_nodes +
+ l_to_tree_order +
+ l_known_ptr +
+ l_known_ptrs +
+ l_get_owner_document_wf_get_root_node_wf +
+ assumes known_ptr_impl: "known_ptr = ShadowRootClass.known_ptr"
+begin
+
+lemma known_ptr_node_or_document: "known_ptr ptr \<Longrightarrow> is_node_ptr_kind ptr \<or> is_document_ptr_kind ptr"
+ by(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+
+lemma get_scdom_component_subset_get_dom_component:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "h \<turnstile> get_dom_component ptr \<rightarrow>\<^sub>r c"
+ shows "set c \<subseteq> set sc"
+proof -
+ obtain document disc_nodes tree_order disconnected_tree_orders where document: "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r document"
+ and disc_nodes: "h \<turnstile> get_disconnected_nodes document \<rightarrow>\<^sub>r disc_nodes"
+ and tree_order: "h \<turnstile> to_tree_order (cast document) \<rightarrow>\<^sub>r tree_order"
+ and disconnected_tree_orders: "h \<turnstile> map_M (to_tree_order \<circ> cast) disc_nodes \<rightarrow>\<^sub>r disconnected_tree_orders"
+ and sc: "sc = tree_order @ (concat disconnected_tree_orders)"
+ using assms(4)
+ by(auto simp add: get_scdom_component_def elim!: bind_returns_result_E
+ elim!: bind_returns_result_E2[rotated, OF get_owner_document_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF to_tree_order_pure, rotated]
+ )
+
+ obtain root_ptr where root_ptr: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root_ptr"
+ and c: "h \<turnstile> to_tree_order root_ptr \<rightarrow>\<^sub>r c"
+ using assms(5)
+ by(auto simp add: get_dom_component_def elim!: bind_returns_result_E2[rotated, OF get_root_node_pure, rotated])
+
+ show ?thesis
+ proof (cases "is_document_ptr_kind root_ptr")
+ case True
+ then have "cast document = root_ptr"
+ using get_root_node_document assms(1) assms(2) assms(3) root_ptr document
+ by (metis document_ptr_casts_commute3 returns_result_eq)
+ then have "c = tree_order"
+ using tree_order c
+ by auto
+ then show ?thesis
+ by(simp add: sc)
+ next
+ case False
+ moreover have "root_ptr |\<in>| object_ptr_kinds h"
+ using assms(1) assms(2) assms(3) local.get_root_node_root_in_heap root_ptr by blast
+ ultimately have "is_node_ptr_kind root_ptr"
+ using assms(3) known_ptrs_known_ptr known_ptr_node_or_document
+ by auto
+ then obtain root_node_ptr where root_node_ptr: "root_ptr = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node_ptr"
+ by (metis node_ptr_casts_commute3)
+ then have "h \<turnstile> get_owner_document root_ptr \<rightarrow>\<^sub>r document"
+ using get_root_node_same_owner_document
+ using assms(1) assms(2) assms(3) document root_ptr by blast
+ then have "root_node_ptr \<in> set disc_nodes"
+ using assms(1) assms(2) assms(3) disc_nodes in_disconnected_nodes_no_parent root_node_ptr
+ using local.get_root_node_same_no_parent root_ptr by blast
+ then have "c \<in> set disconnected_tree_orders"
+ using c root_node_ptr
+ using map_M_pure_E[OF disconnected_tree_orders]
+ by (metis (mono_tags, lifting) comp_apply local.to_tree_order_pure select_result_I2)
+ then show ?thesis
+ by(auto simp add: sc)
+ qed
+qed
+
+lemma get_scdom_component_ptrs_same_owner_document:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "ptr' \<in> set sc"
+ assumes "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ shows "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r owner_document"
+proof -
+ obtain document disc_nodes tree_order disconnected_tree_orders where document: "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r document"
+ and disc_nodes: "h \<turnstile> get_disconnected_nodes document \<rightarrow>\<^sub>r disc_nodes"
+ and tree_order: "h \<turnstile> to_tree_order (cast document) \<rightarrow>\<^sub>r tree_order"
+ and disconnected_tree_orders: "h \<turnstile> map_M (to_tree_order \<circ> cast) disc_nodes \<rightarrow>\<^sub>r disconnected_tree_orders"
+ and sc: "sc = tree_order @ (concat disconnected_tree_orders)"
+ using assms(4)
+ by(auto simp add: get_scdom_component_def elim!: bind_returns_result_E
+ elim!: bind_returns_result_E2[rotated, OF get_owner_document_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF to_tree_order_pure, rotated]
+ )
+ show ?thesis
+ proof (cases "ptr' \<in> set tree_order")
+ case True
+ have "owner_document = document"
+ using assms(6) document by fastforce
+ then show ?thesis
+ by (metis (no_types) True assms(1) assms(2) assms(3) cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject document
+ document_ptr_casts_commute3 document_ptr_document_ptr_cast document_ptr_kinds_commutes
+ local.get_owner_document_owner_document_in_heap local.get_root_node_document
+ local.get_root_node_not_node_same local.to_tree_order_same_root node_ptr_no_document_ptr_cast
+ tree_order)
+ next
+ case False
+ then obtain disconnected_tree_order where disconnected_tree_order:
+ "ptr' \<in> set disconnected_tree_order" and "disconnected_tree_order \<in> set disconnected_tree_orders"
+ using sc \<open>ptr' \<in> set sc\<close>
+ by auto
+ obtain root_ptr' where
+ root_ptr': "root_ptr' \<in> set disc_nodes" and
+ "h \<turnstile> to_tree_order (cast root_ptr') \<rightarrow>\<^sub>r disconnected_tree_order"
+ using map_M_pure_E2[OF disconnected_tree_orders \<open>disconnected_tree_order \<in> set disconnected_tree_orders\<close>]
+ by (metis comp_apply local.to_tree_order_pure)
+ have "\<not>(\<exists>parent \<in> fset (object_ptr_kinds h). root_ptr' \<in> set |h \<turnstile> get_child_nodes parent|\<^sub>r)"
+ using disc_nodes
+ by (meson assms(1) assms(2) assms(3) disjoint_iff_not_equal local.get_child_nodes_ok
+ local.heap_is_wellformed_children_disc_nodes_different local.known_ptrs_known_ptr notin_fset
+ returns_result_select_result root_ptr')
+ then
+ have "h \<turnstile> get_parent root_ptr' \<rightarrow>\<^sub>r None"
+ using disc_nodes
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) fmember.rep_eq local.get_parent_child_dual
+ local.get_parent_ok local.get_parent_parent_in_heap local.heap_is_wellformed_disc_nodes_in_heap
+ returns_result_select_result root_ptr' select_result_I2 split_option_ex)
+ then have "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r cast root_ptr'"
+ using \<open>h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_ptr') \<rightarrow>\<^sub>r disconnected_tree_order\<close> assms(1)
+ assms(2) assms(3) disconnected_tree_order local.get_root_node_no_parent local.to_tree_order_get_root_node
+ local.to_tree_order_ptr_in_result
+ by blast
+ then have "h \<turnstile> get_owner_document (cast root_ptr') \<rightarrow>\<^sub>r document"
+ using assms(1) assms(2) assms(3) disc_nodes local.get_owner_document_disconnected_nodes root_ptr'
+ by blast
+
+ then have "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r document"
+ using \<open>h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_ptr'\<close> assms(1) assms(2) assms(3)
+ local.get_root_node_same_owner_document
+ by blast
+ then show ?thesis
+ using assms(6) document returns_result_eq by force
+ qed
+qed
+
+lemma get_scdom_component_ptrs_same_scope_component:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "ptr' \<in> set sc"
+ shows "h \<turnstile> get_scdom_component ptr' \<rightarrow>\<^sub>r sc"
+proof -
+ obtain document disc_nodes tree_order disconnected_tree_orders where document:
+ "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r document"
+ and disc_nodes: "h \<turnstile> get_disconnected_nodes document \<rightarrow>\<^sub>r disc_nodes"
+ and tree_order: "h \<turnstile> to_tree_order (cast document) \<rightarrow>\<^sub>r tree_order"
+ and disconnected_tree_orders: "h \<turnstile> map_M (to_tree_order \<circ> cast) disc_nodes \<rightarrow>\<^sub>r disconnected_tree_orders"
+ and sc: "sc = tree_order @ (concat disconnected_tree_orders)"
+ using assms(4)
+ by(auto simp add: get_scdom_component_def elim!: bind_returns_result_E
+ elim!: bind_returns_result_E2[rotated, OF get_owner_document_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ elim!: bind_returns_result_E2[rotated, OF to_tree_order_pure, rotated]
+ )
+ show ?thesis
+ proof (cases "ptr' \<in> set tree_order")
+ case True
+ then have "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r document"
+ by (metis assms(1) assms(2) assms(3) cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_inject document document_ptr_casts_commute3
+ document_ptr_kinds_commutes known_ptr_node_or_document local.get_owner_document_owner_document_in_heap
+ local.get_root_node_document local.get_root_node_not_node_same local.known_ptrs_known_ptr
+ local.to_tree_order_get_root_node local.to_tree_order_ptr_in_result node_ptr_no_document_ptr_cast tree_order)
+ then show ?thesis
+ using disc_nodes tree_order disconnected_tree_orders sc
+ by(auto simp add: get_scdom_component_def intro!: bind_pure_returns_result_I map_M_pure_I)
+ next
+ case False
+ then obtain disconnected_tree_order where disconnected_tree_order:
+ "ptr' \<in> set disconnected_tree_order" and "disconnected_tree_order \<in> set disconnected_tree_orders"
+ using sc \<open>ptr' \<in> set sc\<close>
+ by auto
+ obtain root_ptr' where
+ root_ptr': "root_ptr' \<in> set disc_nodes" and
+ "h \<turnstile> to_tree_order (cast root_ptr') \<rightarrow>\<^sub>r disconnected_tree_order"
+ using map_M_pure_E2[OF disconnected_tree_orders \<open>disconnected_tree_order \<in> set disconnected_tree_orders\<close>]
+ by (metis comp_apply local.to_tree_order_pure)
+ have "\<not>(\<exists>parent \<in> fset (object_ptr_kinds h). root_ptr' \<in> set |h \<turnstile> get_child_nodes parent|\<^sub>r)"
+ using disc_nodes
+ by (meson assms(1) assms(2) assms(3) disjoint_iff_not_equal local.get_child_nodes_ok
+ local.heap_is_wellformed_children_disc_nodes_different local.known_ptrs_known_ptr notin_fset
+ returns_result_select_result root_ptr')
+ then
+ have "h \<turnstile> get_parent root_ptr' \<rightarrow>\<^sub>r None"
+ using disc_nodes
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) fmember.rep_eq local.get_parent_child_dual
+ local.get_parent_ok local.get_parent_parent_in_heap local.heap_is_wellformed_disc_nodes_in_heap
+ returns_result_select_result root_ptr' select_result_I2 split_option_ex)
+ then have "h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r cast root_ptr'"
+ using \<open>h \<turnstile> to_tree_order (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_ptr') \<rightarrow>\<^sub>r disconnected_tree_order\<close> assms(1)
+ assms(2) assms(3) disconnected_tree_order local.get_root_node_no_parent local.to_tree_order_get_root_node
+ local.to_tree_order_ptr_in_result
+ by blast
+ then have "h \<turnstile> get_owner_document (cast root_ptr') \<rightarrow>\<^sub>r document"
+ using assms(1) assms(2) assms(3) disc_nodes local.get_owner_document_disconnected_nodes root_ptr'
+ by blast
+
+ then have "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r document"
+ using \<open>h \<turnstile> get_root_node ptr' \<rightarrow>\<^sub>r cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_ptr'\<close> assms(1) assms(2) assms(3)
+ local.get_root_node_same_owner_document
+ by blast
+ then show ?thesis
+ using disc_nodes tree_order disconnected_tree_orders sc
+ by(auto simp add: get_scdom_component_def intro!: bind_pure_returns_result_I map_M_pure_I)
+ qed
+qed
+
+lemma get_scdom_component_ok:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ shows "h \<turnstile> ok (get_scdom_component ptr)"
+ using assms
+ apply(auto simp add: get_scdom_component_def intro!: bind_is_OK_pure_I map_M_pure_I map_M_ok_I)[1]
+ using get_owner_document_ok
+ apply blast
+ apply (simp add: local.get_disconnected_nodes_ok local.get_owner_document_owner_document_in_heap)
+ apply (simp add: local.get_owner_document_owner_document_in_heap local.to_tree_order_ok)
+ using local.heap_is_wellformed_disc_nodes_in_heap local.to_tree_order_ok node_ptr_kinds_commutes
+ by blast
+
+
+lemma get_scdom_component_ptr_in_heap:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "ptr' \<in> set sc"
+ shows "ptr' |\<in>| object_ptr_kinds h"
+ using assms
+ apply(auto simp add: get_scdom_component_def elim!: bind_returns_result_E2 intro!: map_M_pure_I)[1]
+ using local.to_tree_order_ptrs_in_heap apply blast
+ by (metis (no_types, lifting) assms(4) assms(5) bind_returns_result_E get_scdom_component_impl
+ get_scdom_component_ptrs_same_scope_component is_OK_returns_result_I
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_scdom_component_def local.get_owner_document_ptr_in_heap)
+
+lemma get_scdom_component_contains_get_dom_component:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "ptr' \<in> set sc"
+ obtains c where "h \<turnstile> get_dom_component ptr' \<rightarrow>\<^sub>r c" and "set c \<subseteq> set sc"
+proof -
+ have "h \<turnstile> get_scdom_component ptr' \<rightarrow>\<^sub>r sc"
+ using assms(1) assms(2) assms(3) assms(4) assms(5) get_scdom_component_ptrs_same_scope_component
+ by blast
+ then show ?thesis
+ by (meson assms(1) assms(2) assms(3) assms(5) get_scdom_component_ptr_in_heap
+ get_scdom_component_subset_get_dom_component is_OK_returns_result_E local.get_dom_component_ok that)
+qed
+
+lemma get_scdom_component_owner_document_same:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "ptr' \<in> set sc"
+ obtains owner_document where "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r owner_document" and "cast owner_document \<in> set sc"
+ using assms
+ apply(auto simp add: get_scdom_component_def elim!: bind_returns_result_E2 intro!: map_M_pure_I)[1]
+ apply (metis (no_types, lifting) assms(4) assms(5) document_ptr_casts_commute3
+ document_ptr_document_ptr_cast get_scdom_component_contains_get_dom_component local.get_dom_component_ptr
+ local.get_dom_component_root_node_same local.get_dom_component_to_tree_order local.get_root_node_document
+ local.get_root_node_not_node_same local.to_tree_order_ptr_in_result local.to_tree_order_ptrs_in_heap
+ node_ptr_no_document_ptr_cast)
+ apply(rule map_M_pure_E2)
+ apply(simp)
+ apply(simp)
+ apply(simp)
+ by (smt assms(4) assms(5) comp_apply get_scdom_component_ptr_in_heap is_OK_returns_result_E
+ local.get_owner_document_disconnected_nodes local.get_root_node_ok local.get_root_node_same_owner_document
+ local.to_tree_order_get_root_node local.to_tree_order_ptr_in_result)
+
+lemma get_scdom_component_different_owner_documents:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ assumes "h \<turnstile> get_owner_document ptr' \<rightarrow>\<^sub>r owner_document'"
+ assumes "owner_document \<noteq> owner_document'"
+ shows "set |h \<turnstile> get_scdom_component ptr|\<^sub>r \<inter> set |h \<turnstile> get_scdom_component ptr'|\<^sub>r = {}"
+ using assms get_scdom_component_ptrs_same_owner_document
+ by (smt disjoint_iff_not_equal get_scdom_component_ok is_OK_returns_result_I
+ local.get_owner_document_ptr_in_heap returns_result_eq returns_result_select_result)
+end
+
+interpretation i_get_dom_component_get_scdom_component?: l_get_dom_component_get_scdom_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_owner_document
+ get_disconnected_nodes get_disconnected_nodes_locs to_tree_order heap_is_wellformed parent_child_rel
+ type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_dom_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node
+ get_root_node_locs get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name
+ by(auto simp add: l_get_dom_component_get_scdom_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_dom_component_get_scdom_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_get_dom_component_get_scdom_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_dom_component_get_scdom_component_is_l_get_dom_component_get_scdom_component [instances]:
+ "l_get_dom_component_get_scdom_component get_owner_document heap_is_wellformed type_wf known_ptr known_ptrs get_scdom_component get_dom_component"
+ apply(auto simp add: l_get_dom_component_get_scdom_component_def
+ l_get_dom_component_get_scdom_component_axioms_def instances)[1]
+ using get_scdom_component_subset_get_dom_component apply fast
+ using get_scdom_component_ptrs_same_scope_component apply fast
+ using get_scdom_component_ptrs_same_owner_document apply fast
+ using get_scdom_component_ok apply fast
+ using get_scdom_component_ptr_in_heap apply fast
+ using get_scdom_component_contains_get_dom_component apply blast
+ using get_scdom_component_owner_document_same apply blast
+ using get_scdom_component_different_owner_documents apply fast
+ done
+
+
+subsection \<open>attach\_shadow\_root\<close>
+
+lemma attach_shadow_root_not_strongly_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'ShadowRoot::{equal,linorder}) heap" and
+ h' and host and new_shadow_root_ptr where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> attach_shadow_root host m \<rightarrow>\<^sub>r new_shadow_root_ptr \<rightarrow>\<^sub>h h'" and
+ "\<not> is_strongly_scdom_component_safe {cast host} {cast new_shadow_root_ptr} h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder},
+'ShadowRoot::{equal,linorder}) heap"
+ let ?P = "do {
+ doc \<leftarrow> create_document;
+ create_element doc ''div''
+}"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?e1 = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and host="?e1"])
+ by code_simp+
+qed
+
+locale l_get_scdom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_dom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component_get_scdom_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma attach_shadow_root_is_weakly_component_safe_step:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>h h'"
+ assumes "ptr \<noteq> cast |h \<turnstile> attach_shadow_root element_ptr shadow_root_mode|\<^sub>r"
+ assumes "ptr \<notin> set |h \<turnstile> get_scdom_component (cast element_ptr)|\<^sub>r"
+ shows "preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'"
+proof -
+ have "element_ptr |\<in>| element_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_heap_I local.attach_shadow_root_element_ptr_in_heap)
+ obtain sc where sc: "h \<turnstile> get_scdom_component (cast element_ptr) \<rightarrow>\<^sub>r sc"
+ using get_scdom_component_ok
+ by (meson assms(1) assms(2) assms(3) assms(4) element_ptr_kinds_commutes is_OK_returns_heap_I
+ local.attach_shadow_root_element_ptr_in_heap node_ptr_kinds_commutes select_result_I)
+ then have "ptr \<notin> set |h \<turnstile> get_dom_component (cast element_ptr)|\<^sub>r"
+ by (metis (no_types, lifting) \<open>element_ptr |\<in>| element_ptr_kinds h\<close> assms(1) assms(2) assms(3)
+ assms(6) element_ptr_kinds_commutes local.get_dom_component_ok
+ local.get_scdom_component_subset_get_dom_component node_ptr_kinds_commutes
+ returns_result_select_result select_result_I2 set_rev_mp)
+ then show ?thesis
+ using assms(1) assms(2) assms(3) assms(4) assms(5) local.attach_shadow_root_is_weakly_dom_component_safe
+ by blast
+qed
+
+lemma attach_shadow_root_is_weakly_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>r result"
+ assumes "h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>h h'"
+ shows "is_weakly_scdom_component_safe {cast element_ptr} {cast result} h h'"
+proof -
+
+ obtain h2 h3 new_shadow_root_ptr where
+ h2: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h2" and
+ new_shadow_root_ptr: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr" and
+ h3: "h2 \<turnstile> set_mode new_shadow_root_ptr shadow_root_mode \<rightarrow>\<^sub>h h3" and
+ h': "h3 \<turnstile> set_shadow_root element_ptr (Some new_shadow_root_ptr) \<rightarrow>\<^sub>h h'"
+ using assms(5)
+ by(auto simp add: attach_shadow_root_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_tag_name_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_shadow_root_pure, rotated] split: if_splits)
+ have "h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ using new_shadow_root_ptr h2 h3 h'
+ using assms(5)
+ by(auto simp add: attach_shadow_root_def intro!: bind_returns_result_I
+ bind_pure_returns_result_I[OF get_tag_name_pure] bind_pure_returns_result_I[OF get_shadow_root_pure]
+ elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_tag_name_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_shadow_root_pure, rotated] split: if_splits)
+ then
+ have "object_ptr_kinds h2 = {|cast result|} |\<union>| object_ptr_kinds h"
+ using h2 new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_new_ptr
+ using new_shadow_root_ptr
+ using assms(4) by auto
+ moreover
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h2 = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_mode_writes h3])
+ using set_mode_pointers_preserved
+ apply blast
+ by (auto simp add: reflp_def transp_def)
+ moreover
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h3 = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_shadow_root_writes h'])
+ using set_shadow_root_pointers_preserved
+ apply blast
+ by (auto simp add: reflp_def transp_def)
+ ultimately have "object_ptr_kinds h' = {|cast result|} |\<union>| object_ptr_kinds h"
+ by simp
+ moreover
+ have "result |\<notin>| shadow_root_ptr_kinds h"
+ using h2 new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_not_in_heap new_shadow_root_ptr
+ using \<open>h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>r new_shadow_root_ptr\<close> assms(4)
+ returns_result_eq by metis
+ ultimately
+ show ?thesis
+ using assms
+ apply(auto simp add: is_weakly_scdom_component_safe_def Let_def)[1]
+ using attach_shadow_root_is_weakly_component_safe_step
+ by (smt document_ptr_kinds_commutes local.get_scdom_component_impl select_result_I2
+ shadow_root_ptr_kinds_commutes)
+qed
+end
+
+interpretation i_get_scdom_component_attach_shadow_root?: l_get_scdom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe
+ get_dom_component is_strongly_dom_component_safe is_weakly_dom_component_safe to_tree_order
+ get_parent get_parent_locs get_child_nodes get_child_nodes_locs get_root_node get_root_node_locs
+ get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name
+ set_shadow_root set_shadow_root_locs set_mode set_mode_locs attach_shadow_root get_disconnected_nodes
+ get_disconnected_nodes_locs get_tag_name get_tag_name_locs get_shadow_root get_shadow_root_locs
+ by(auto simp add: l_get_scdom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_attach_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsection \<open>get\_shadow\_root\<close>
+
+lemma get_shadow_root_not_weakly_scdom_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder},
+'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and
+ element_ptr and shadow_root_ptr_opt and h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> get_shadow_root_safe element_ptr \<rightarrow>\<^sub>r shadow_root_ptr_opt \<rightarrow>\<^sub>h h'" and
+ "\<not> is_weakly_scdom_component_safe {cast element_ptr} (cast ` set_option shadow_root_ptr_opt) h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder}, 'CharacterData::{equal,linorder},
+'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap"
+ let ?P = "do {
+ document_ptr \<leftarrow> create_document;
+ html \<leftarrow> create_element document_ptr ''html'';
+ append_child (cast document_ptr) (cast html);
+ head \<leftarrow> create_element document_ptr ''head'';
+ append_child (cast html) (cast head);
+ body \<leftarrow> create_element document_ptr ''body'';
+ append_child (cast html) (cast body);
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast body) (cast e1);
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast e1) (cast e2);
+ s1 \<leftarrow> attach_shadow_root e1 Open;
+ e3 \<leftarrow> create_element document_ptr ''slot'';
+ append_child (cast s1) (cast e3);
+ return e1
+ }"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?e1 = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and element_ptr="?e1"])
+ by code_simp+
+qed
+
+locale l_get_shadow_root_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_scdom_component +
+ l_get_shadow_root_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_create_document +
+ l_get_owner_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_mode +
+ l_get_scdom_component\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_shadow_root_safe\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ assumes known_ptrs_impl: "known_ptrs = a_known_ptrs"
+begin
+lemma get_shadow_root_components_disjunct:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ shows "set |h \<turnstile> get_scdom_component (cast host)|\<^sub>r \<inter> set | h \<turnstile> get_scdom_component (cast shadow_root_ptr)|\<^sub>r = {}"
+proof -
+ obtain owner_document where owner_document: "h \<turnstile> get_owner_document (cast host) \<rightarrow>\<^sub>r owner_document"
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) assms(5) element_ptr_kinds_commutes
+ is_OK_returns_result_E is_OK_returns_result_I local.get_dom_component_ok local.get_dom_component_ptr
+ local.get_scdom_component_ok local.get_scdom_component_owner_document_same
+ local.get_scdom_component_subset_get_dom_component local.get_shadow_root_ptr_in_heap node_ptr_kinds_commutes
+ subset_code(1))
+ have "owner_document \<noteq> cast shadow_root_ptr"
+ proof
+ assume "owner_document = cast shadow_root_ptr"
+ then have "(cast owner_document, cast host) \<in>
+(parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ using get_owner_document_rel owner_document
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) cast_document_ptr_not_node_ptr(2)
+ in_rtrancl_UnI inf_sup_aci(6) inf_sup_aci(7))
+ then have "(cast shadow_root_ptr, cast host) \<in>
+(parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ by (simp add: \<open>owner_document = cast shadow_root_ptr\<close>)
+ moreover have "(cast host, cast shadow_root_ptr) \<in> a_host_shadow_root_rel h"
+ by (metis (mono_tags, lifting) assms(5) is_OK_returns_result_I local.get_shadow_root_ptr_in_heap
+ local.a_host_shadow_root_rel_def mem_Collect_eq pair_imageI prod.simps(2) select_result_I2)
+ then have "(cast host, cast shadow_root_ptr) \<in>
+(parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)"
+ by (simp)
+ ultimately show False
+ using assms(1)
+ unfolding heap_is_wellformed_def \<open>owner_document = cast shadow_root_ptr\<close> acyclic_def
+ by (meson rtrancl_into_trancl1)
+ qed
+ moreover
+ have "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ using assms(1) assms(5) local.get_shadow_root_shadow_root_ptr_in_heap by blast
+ then
+ have "cast shadow_root_ptr \<in> fset (object_ptr_kinds h)"
+ by auto
+ have "is_shadow_root_ptr shadow_root_ptr"
+ using assms(3)[unfolded known_ptrs_impl ShadowRootClass.known_ptrs_defs
+ ShadowRootClass.known_ptr_defs DocumentClass.known_ptr_defs CharacterDataClass.known_ptr_defs
+ ElementClass.known_ptr_defs NodeClass.known_ptr_defs, simplified, rule_format, OF
+ \<open>cast shadow_root_ptr \<in> fset (object_ptr_kinds h)\<close>]
+ by(auto simp add: is_document_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: option.splits document_ptr.splits)
+ then
+ have "h \<turnstile> get_owner_document (cast shadow_root_ptr) \<rightarrow>\<^sub>r cast shadow_root_ptr"
+ using \<open>shadow_root_ptr |\<in>| shadow_root_ptr_kinds h\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ by(auto simp add: is_node_ptr_kind_none a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+ ultimately show ?thesis
+ using assms(1) assms(2) assms(3) get_scdom_component_different_owner_documents owner_document
+ by blast
+qed
+
+lemma get_shadow_root_is_strongly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_shadow_root_safe element_ptr \<rightarrow>\<^sub>r shadow_root_ptr_opt \<rightarrow>\<^sub>h h'"
+ assumes "\<forall>shadow_root_ptr \<in> fset (shadow_root_ptr_kinds h). h \<turnstile> get_mode shadow_root_ptr \<rightarrow>\<^sub>r Closed"
+ shows "is_strongly_scdom_component_safe {cast element_ptr} (cast ` set_option shadow_root_ptr_opt) h h'"
+proof -
+ have "h = h'"
+ using assms(4)
+ by(auto simp add: returns_result_heap_def pure_returns_heap_eq)
+ moreover have "shadow_root_ptr_opt = None"
+ using assms(4)
+ apply(auto simp add: returns_result_heap_def get_shadow_root_safe_def elim!: bind_returns_result_E2
+ split: option.splits if_splits)[1]
+ using get_shadow_root_shadow_root_ptr_in_heap
+ by (meson assms(5) is_OK_returns_result_I local.get_mode_ptr_in_heap notin_fset returns_result_eq
+ shadow_root_mode.distinct(1))
+ ultimately show ?thesis
+ by(simp add: is_strongly_scdom_component_safe_def preserved_def)
+qed
+end
+
+interpretation i_get_shadow_root_scope_component?: l_get_shadow_root_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe get_dom_component
+ is_strongly_dom_component_safe is_weakly_dom_component_safe get_shadow_root get_shadow_root_locs
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs get_tag_name
+ get_tag_name_locs heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document
+ get_disconnected_document_locs to_tree_order get_parent get_parent_locs get_root_node get_root_node_locs
+ get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name
+ remove_shadow_root remove_shadow_root_locs create_document DocumentClass.known_ptr DocumentClass.type_wf
+ CD.a_get_owner_document get_mode get_mode_locs get_shadow_root_safe get_shadow_root_safe_locs
+ by(auto simp add: l_get_shadow_root_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_shadow_root_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_get_shadow_root_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsection \<open>get\_host\<close>
+
+lemma get_host_not_weakly_scdom_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and
+ shadow_root_ptr and element_ptr and h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> get_host shadow_root_ptr \<rightarrow>\<^sub>r element_ptr \<rightarrow>\<^sub>h h'" and
+ "\<not> is_weakly_scdom_component_safe {cast shadow_root_ptr} {cast element_ptr} h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder},
+'Shadowroot::{equal,linorder}) heap"
+ let ?P = "do {
+ document_ptr \<leftarrow> create_document;
+ html \<leftarrow> create_element document_ptr ''html'';
+ append_child (cast document_ptr) (cast html);
+ head \<leftarrow> create_element document_ptr ''head'';
+ append_child (cast html) (cast head);
+ body \<leftarrow> create_element document_ptr ''body'';
+ append_child (cast html) (cast body);
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast body) (cast e1);
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast e1) (cast e2);
+ s1 \<leftarrow> attach_shadow_root e1 Open;
+ e3 \<leftarrow> create_element document_ptr ''slot'';
+ append_child (cast s1) (cast e3);
+ return s1
+ }"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?s1 = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and shadow_root_ptr="?s1"])
+ by code_simp+
+qed
+
+locale l_get_host_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_shadow_root_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_host_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma get_host_components_disjunct:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_scdom_component ptr \<rightarrow>\<^sub>r sc"
+ assumes "h \<turnstile> get_host shadow_root_ptr \<rightarrow>\<^sub>r host"
+ shows "set |h \<turnstile> get_scdom_component (cast host)|\<^sub>r \<inter> set | h \<turnstile> get_scdom_component (cast shadow_root_ptr)|\<^sub>r = {}"
+ using assms get_shadow_root_components_disjunct local.shadow_root_host_dual
+ by blast
+end
+
+interpretation i_get_host_scope_component?: l_get_host_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document heap_is_wellformed parent_child_rel type_wf known_ptr
+ known_ptrs get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe
+ get_dom_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_shadow_root
+ get_shadow_root_locs get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ get_tag_name get_tag_name_locs heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document
+ get_disconnected_document_locs to_tree_order get_parent get_parent_locs get_root_node get_root_node_locs
+ get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name
+ remove_shadow_root remove_shadow_root_locs create_document DocumentClass.known_ptr DocumentClass.type_wf
+ CD.a_get_owner_document get_mode get_mode_locs get_shadow_root_safe get_shadow_root_safe_locs
+ by(auto simp add: l_get_host_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_host_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsection \<open>get\_root\_node\_si\<close>
+
+lemma get_composed_root_node_not_weakly_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and
+ ptr and root and h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> get_root_node_si ptr \<rightarrow>\<^sub>r root \<rightarrow>\<^sub>h h'" and
+ "\<not> is_weakly_scdom_component_safe {ptr} {root} h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder},
+'Shadowroot::{equal,linorder}) heap"
+ let ?P = "do {
+ document_ptr \<leftarrow> create_document;
+ html \<leftarrow> create_element document_ptr ''html'';
+ append_child (cast document_ptr) (cast html);
+ head \<leftarrow> create_element document_ptr ''head'';
+ append_child (cast html) (cast head);
+ body \<leftarrow> create_element document_ptr ''body'';
+ append_child (cast html) (cast body);
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast body) (cast e1);
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast e1) (cast e2);
+ s1 \<leftarrow> attach_shadow_root e1 Closed;
+ e3 \<leftarrow> create_element document_ptr ''slot'';
+ append_child (cast s1) (cast e3);
+ return e3
+ }"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?e3 = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and ptr="cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ?e3"])
+ by code_simp+
+qed
+
+locale l_get_scdom_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_dom_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_dom_component_get_scdom_component
+begin
+
+lemma get_root_node_si_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node_si ptr' \<rightarrow>\<^sub>r root"
+ shows "set |h \<turnstile> get_scdom_component ptr'|\<^sub>r = set |h \<turnstile> get_scdom_component root|\<^sub>r \<or>
+set |h \<turnstile> get_scdom_component ptr'|\<^sub>r \<inter> set |h \<turnstile> get_scdom_component root|\<^sub>r = {}"
+proof -
+ have "ptr' |\<in>| object_ptr_kinds h"
+ using get_ancestors_si_ptr_in_heap assms(4)
+ by(auto simp add: get_root_node_si_def elim!: bind_returns_result_E2)
+ then
+ obtain sc where "h \<turnstile> get_scdom_component ptr' \<rightarrow>\<^sub>r sc"
+ by (meson assms(1) assms(2) assms(3) local.get_scdom_component_ok select_result_I)
+ moreover
+ have "root |\<in>| object_ptr_kinds h"
+ using get_ancestors_si_ptr assms(4)
+ apply(auto simp add: get_root_node_si_def elim!: bind_returns_result_E2)[1]
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) empty_iff empty_set
+ get_ancestors_si_ptrs_in_heap last_in_set)
+ then
+ obtain sc' where "h \<turnstile> get_scdom_component root \<rightarrow>\<^sub>r sc'"
+ by (meson assms(1) assms(2) assms(3) local.get_scdom_component_ok select_result_I)
+ ultimately show ?thesis
+ by (metis (no_types, hide_lams) IntE \<open>\<And>thesis. (\<And>sc'. h \<turnstile> get_scdom_component root \<rightarrow>\<^sub>r sc' \<Longrightarrow> thesis) \<Longrightarrow> thesis\<close>
+ \<open>\<And>thesis. (\<And>sc. h \<turnstile> get_scdom_component ptr' \<rightarrow>\<^sub>r sc \<Longrightarrow> thesis) \<Longrightarrow> thesis\<close> assms(1) assms(2) assms(3) empty_subsetI
+ local.get_scdom_component_ptrs_same_scope_component returns_result_eq select_result_I2 subsetI subset_antisym)
+qed
+end
+
+interpretation i_get_scdom_component_get_root_node_si?: l_get_scdom_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs get_host
+ get_host_locs get_ancestors_si get_ancestors_si_locs get_root_node_si get_root_node_si_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs heap_is_wellformed
+ parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_document get_disconnected_document_locs to_tree_order
+ get_dom_component is_strongly_dom_component_safe is_weakly_dom_component_safe get_root_node get_root_node_locs
+ get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name
+ get_owner_document get_scdom_component is_strongly_scdom_component_safe
+ by(auto simp add: l_get_scdom_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_scdom_component_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsection \<open>get\_assigned\_nodes\<close>
+
+lemma assigned_nodes_not_weakly_scdom_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and
+ node_ptr and nodes and h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> assigned_nodes node_ptr \<rightarrow>\<^sub>r nodes \<rightarrow>\<^sub>h h'" and
+ "\<not> is_weakly_scdom_component_safe {cast node_ptr} (cast ` set nodes) h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap"
+ let ?P = "do {
+ document_ptr \<leftarrow> create_document;
+ html \<leftarrow> create_element document_ptr ''html'';
+ append_child (cast document_ptr) (cast html);
+ head \<leftarrow> create_element document_ptr ''head'';
+ append_child (cast html) (cast head);
+ body \<leftarrow> create_element document_ptr ''body'';
+ append_child (cast html) (cast body);
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast body) (cast e1);
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast e1) (cast e2);
+ s1 \<leftarrow> attach_shadow_root e1 Closed;
+ e3 \<leftarrow> create_element document_ptr ''slot'';
+ append_child (cast s1) (cast e3);
+ return e3
+ }"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?e3 = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and node_ptr="?e3"])
+ by code_simp+
+qed
+
+lemma assigned_slot_not_weakly_component_safe:
+ obtains
+ h :: "('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder}, 'element_ptr::{equal,linorder},
+'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder}, 'shadow_root_ptr::{equal,linorder},
+'Object::{equal,linorder}, 'Node::{equal,linorder}, 'Element::{equal,linorder},
+'CharacterData::{equal,linorder}, 'Document::{equal,linorder}, 'Shadowroot::{equal,linorder}) heap" and
+ node_ptr and slot_opt and h' where
+ "heap_is_wellformed h" and "type_wf h" and "known_ptrs h" and
+ "h \<turnstile> assigned_slot node_ptr \<rightarrow>\<^sub>r slot_opt \<rightarrow>\<^sub>h h'" and
+ "\<not> is_weakly_scdom_component_safe {cast node_ptr} (cast ` set_option slot_opt) h h'"
+proof -
+ let ?h0 = "Heap fmempty ::('object_ptr::{equal,linorder}, 'node_ptr::{equal,linorder},
+'element_ptr::{equal,linorder}, 'character_data_ptr::{equal,linorder}, 'document_ptr::{equal,linorder},
+'shadow_root_ptr::{equal,linorder}, 'Object::{equal,linorder}, 'Node::{equal,linorder},
+'Element::{equal,linorder}, 'CharacterData::{equal,linorder}, 'Document::{equal,linorder},
+'Shadowroot::{equal,linorder}) heap"
+ let ?P = "do {
+ document_ptr \<leftarrow> create_document;
+ html \<leftarrow> create_element document_ptr ''html'';
+ append_child (cast document_ptr) (cast html);
+ head \<leftarrow> create_element document_ptr ''head'';
+ append_child (cast html) (cast head);
+ body \<leftarrow> create_element document_ptr ''body'';
+ append_child (cast html) (cast body);
+ e1 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast body) (cast e1);
+ e2 \<leftarrow> create_element document_ptr ''div'';
+ append_child (cast e1) (cast e2);
+ s1 \<leftarrow> attach_shadow_root e1 Open;
+ e3 \<leftarrow> create_element document_ptr ''slot'';
+ append_child (cast s1) (cast e3);
+ return e2
+ }"
+ let ?h1 = "|?h0 \<turnstile> ?P|\<^sub>h"
+ let ?e2 = "|?h0 \<turnstile> ?P|\<^sub>r"
+
+ show thesis
+ apply(rule that[where h="?h1" and node_ptr="cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ?e2"])
+ by code_simp+
+qed
+
+locale l_assigned_nodes_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_assigned_nodes_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_shadow_root_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_find_slot\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma find_slot_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> find_slot open_flag node_ptr \<rightarrow>\<^sub>r Some slot"
+ shows "set |h \<turnstile> get_scdom_component (cast node_ptr)|\<^sub>r \<inter> set |h \<turnstile> get_scdom_component (cast slot)|\<^sub>r = {}"
+proof -
+ obtain host shadow_root_ptr to where
+ "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r Some (cast host)" and
+ "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr" and
+ "h \<turnstile> to_tree_order (cast shadow_root_ptr) \<rightarrow>\<^sub>r to" and
+ "cast slot \<in> set to"
+ using assms(4)
+ apply(auto simp add: find_slot_def first_in_tree_order_def elim!: bind_returns_result_E2
+ map_filter_M_pure_E[where y=slot] split: option.splits if_splits list.splits
+ intro!: map_filter_M_pure bind_pure_I)[1]
+ by (metis element_ptr_casts_commute3)+
+
+ have "node_ptr |\<in>| node_ptr_kinds h"
+ using assms(4) find_slot_ptr_in_heap by blast
+ then obtain node_ptr_c where node_ptr_c: "h \<turnstile> get_scdom_component (cast node_ptr) \<rightarrow>\<^sub>r node_ptr_c"
+ using assms(1) assms(2) assms(3) get_scdom_component_ok is_OK_returns_result_E
+ node_ptr_kinds_commutes[symmetric]
+ by metis
+
+ then have "cast host \<in> set node_ptr_c"
+ using \<open>h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r Some (cast host)\<close> assms(1) assms(2) assms(3)
+ by (meson assms(4) is_OK_returns_result_E local.find_slot_ptr_in_heap local.get_dom_component_ok
+ local.get_dom_component_parent_inside local.get_dom_component_ptr
+ local.get_scdom_component_subset_get_dom_component node_ptr_kinds_commutes subsetCE)
+
+ then have "h \<turnstile> get_scdom_component (cast host) \<rightarrow>\<^sub>r node_ptr_c"
+ using \<open>h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r Some (cast host)\<close> a_heap_is_wellformed_def assms(1) assms(2)
+ assms(3) node_ptr_c
+ using local.get_scdom_component_ptrs_same_scope_component by blast
+
+ moreover have "slot |\<in>| element_ptr_kinds h"
+ using assms(4) find_slot_slot_in_heap by blast
+ then obtain slot_c where slot_c: "h \<turnstile> get_scdom_component (cast slot) \<rightarrow>\<^sub>r slot_c"
+ using a_heap_is_wellformed_def assms(1) assms(2) assms(3) get_scdom_component_ok
+ is_OK_returns_result_E node_ptr_kinds_commutes[symmetric] element_ptr_kinds_commutes[symmetric]
+ by smt
+ then have "cast shadow_root_ptr \<in> set slot_c"
+ using \<open>h \<turnstile> to_tree_order (cast shadow_root_ptr) \<rightarrow>\<^sub>r to\<close> \<open>cast slot \<in> set to\<close> assms(1) assms(2) assms(3)
+ by (meson is_OK_returns_result_E local.get_dom_component_ok local.get_dom_component_ptr
+ local.get_dom_component_to_tree_order local.get_scdom_component_subset_get_dom_component local.to_tree_order_ptrs_in_heap subsetCE)
+ then have "h \<turnstile> get_scdom_component (cast shadow_root_ptr) \<rightarrow>\<^sub>r slot_c"
+ using \<open>h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr\<close> assms(1) assms(2) assms(3) slot_c
+ using local.get_scdom_component_ptrs_same_scope_component by blast
+
+ ultimately show ?thesis
+ using get_shadow_root_components_disjunct assms \<open>h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr\<close>
+ node_ptr_c slot_c
+ by (metis (no_types, lifting) select_result_I2)
+qed
+
+
+lemma assigned_nodes_is_component_unsafe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> assigned_nodes element_ptr \<rightarrow>\<^sub>r nodes"
+ assumes "node_ptr \<in> set nodes"
+ shows "set |h \<turnstile> get_scdom_component (cast element_ptr)|\<^sub>r \<inter> set |h \<turnstile> get_scdom_component (cast node_ptr)|\<^sub>r = {}"
+ using assms
+proof -
+ have "h \<turnstile> find_slot False node_ptr \<rightarrow>\<^sub>r Some element_ptr"
+ using assms(4) assms(5)
+ by(auto simp add: assigned_nodes_def elim!: bind_returns_result_E2
+ dest!: filter_M_holds_for_result[where x=node_ptr] intro!: bind_pure_I split: if_splits)
+ then show ?thesis
+ using assms find_slot_is_component_unsafe
+ by blast
+qed
+
+lemma assigned_slot_is_strongly_scdom_component_safe:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> assigned_slot element_ptr \<rightarrow>\<^sub>r slot_opt \<rightarrow>\<^sub>h h'"
+ assumes "\<forall>shadow_root_ptr \<in> fset (shadow_root_ptr_kinds h). h \<turnstile> get_mode shadow_root_ptr \<rightarrow>\<^sub>r Closed"
+ shows "is_strongly_scdom_component_safe {cast element_ptr} (cast ` set_option slot_opt) h h'"
+proof -
+ have "h = h'"
+ using assms(4) find_slot_pure
+ by(auto simp add: assigned_slot_def returns_result_heap_def pure_returns_heap_eq find_slot_impl)
+ moreover have "slot_opt = None"
+ using assms(4) assms(5)
+ apply(auto simp add: returns_result_heap_def assigned_slot_def a_find_slot_def
+ elim!: bind_returns_result_E2 split: option.splits if_splits
+ dest!: get_shadow_root_shadow_root_ptr_in_heap[OF assms(1)])[1]
+ apply (meson finite_set_in returns_result_eq shadow_root_mode.distinct(1))
+ apply (meson finite_set_in returns_result_eq shadow_root_mode.distinct(1))
+ done
+ ultimately show ?thesis
+ by(auto simp add: is_strongly_scdom_component_safe_def preserved_def)
+qed
+end
+
+interpretation i_assigned_nodes_scope_component?: l_assigned_nodes_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf get_tag_name get_tag_name_locs known_ptr get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs
+ heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs
+ get_disconnected_document get_disconnected_document_locs get_parent get_parent_locs
+ get_mode get_mode_locs get_attribute get_attribute_locs first_in_tree_order find_slot
+ assigned_slot known_ptrs to_tree_order assigned_nodes assigned_nodes_flatten flatten_dom
+ get_root_node get_root_node_locs remove insert_before insert_before_locs append_child
+ remove_shadow_root remove_shadow_root_locs set_shadow_root set_shadow_root_locs remove_child
+ remove_child_locs get_dom_component is_strongly_dom_component_safe is_weakly_dom_component_safe
+ get_ancestors get_ancestors_locs get_element_by_id get_elements_by_class_name get_elements_by_tag_name
+ get_owner_document set_disconnected_nodes set_disconnected_nodes_locs get_ancestors_di get_ancestors_di_locs
+ adopt_node adopt_node_locs adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_child_nodes set_child_nodes_locs
+ get_scdom_component is_strongly_scdom_component_safe is_weakly_scdom_component_safe create_document
+ DocumentClass.known_ptr DocumentClass.type_wf CD.a_get_owner_document get_shadow_root_safe
+ get_shadow_root_safe_locs
+ by(auto simp add: l_assigned_nodes_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_assigned_nodes_scope_component\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+end
diff --git a/thys/SC_DOM_Components/document/fancytabs-normal.jpg b/thys/SC_DOM_Components/document/fancytabs-normal.jpg
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ffe62d666c8862ebadf014eff01173d5cb182b3c
GIT binary patch
literal 34081
zc%1CI2UwF^vnU+tT`AH*DWQXs(2GbXp@$+}fe;A23n(ZkO?s%Ix6na)wV?FgYe0Gj
z1t}^ZT=(~FxBI(ipa0x@&w0-OKlk60JXtIA&di#%*1R*b-gz&lFBbvVpehg*z?CZi
zz?B~#z$F%-2*Ah1!^6YH|M7#5k552IMnw1nu9A`xlTlu!qN2P?Nl8u1Oh-+_c%71x
zo{gT7h2_SL8`N~{ob0Te%&a$9e-m=$2P+`~Aq5c;1uG3D4eS3lT($xziEy}Z3~;Zo
z18^v>;8I?>YzHv^P!b3C%5VDq1VSP_e1adiA6M^R0|4-GuHX?-T>CKrLR|bGv%<ms
zahZ~kip_wC`Z}F(!pJBMEjw6TUf<9yKEI}Ij9yGxSI-jR>GkY6DiO210)oX=a|Gt(
zDyY;FbBZcjxmQWRmn79Zg5LcYfa%IVhyOJ?;0pea5eNu>T)ayOzyaXkkQ0$y!T+7)
z3J&FO!_!=6(}lSO##N2%Q_%{8<@GFcsM$qC_1#g`??yoiR=G<D?}IL90c5y8#8cu@
z0^|T`Ai;Q3#$;5VSADskMsRnbD(Y<1vVJGJu^wd)OF%BIvV=m!T>Qi?0ZV0vs*%Yj
z;JP;<q3b&0;4C*1due*7AqJGj*K0~fsgW%{b|atAM4aPC@rW;ZE*FeLB2ti=M<WfF
z0CL+@G3k`i+7>R47kj0-Ns&)_2$U}Zn{?mMK4g8A4w&-%YnDW&C0n<Rrgwi6{!REN
zJMygK^043I&rNzI*MqRRc(#N8g|^W8ZOGiaIG#RvfygQ#rFYd>-U0`}-tQMD3+K%1
zP3$Egq-KC={~9EFi)-MM%EGy5rrocBTw1UEjsL#`uYF<<?;VaYZYZhkb?_|QU{~Nw
zpkd3GtlLwH7eTpp;WGesPaG}*z4x7t03a34Dbz)$cf;`Tc`w1pr}F^rf%_NhAuoa7
zBllc#a=s;y=Pi6a*G_%=eUA(R4waNL573<AON6FrgtQw8ukykkG@d3En)yr6Iux<9
zbE(%p=8_W54xFK?InuZ)dmF-)$3=&w(=c3C_r`G`4x1}92|19M$x$*<hotJqgP^hH
zoB`h$==VZ`9>Sq=BjEER;kVc1v%NQ*^f<c;VSI@SVM}#vn?;Uk3Vp#6<;X$M9!hP0
zafv~<l=Hi1aWI2Z{vtc#Q3z7kmS-##2^zKueIwaER!Y+?%EyPK-cSiJt+wh5l%$-@
zs6xD&K$nvU&>)NorKv8SZH!L%DRJlaK4G|J3VGUO|43R&g>SI^5)k&)t&3t>C|X!<
zh%9r)ZS*Z6^m~W80axCgG$|IPMNos8vrIxME>z=CV=UTP;wpx<1zOxC+F7LFHaV+~
zVsut8ED#oOH6+Zt8gr$$H{W0zu~L-7!k@G0eiK+HGm;)$7N451&eI*6KGr%Bcx;BB
z?`xHO--Nd}LIIJ+o(S=i^4>7jb7zK8LFB1uZ0q6*sRsx4?3So`wId%T)zDy*>EF(b
zOS-|*^TzpTdWK7si4&Wbt$UzH7%txeWEYt$12@cx2DeORHoUfDGciX>BSKuFyHQwf
zQzAiEh!?y~bw5VOSWdx@jk&HJ8nprv$qr8^6%WPL&1CeE_BSg6CBvn))Qx%#M5eh8
zBfg%zniF1J+S@0Jz!R*<I%{H34B^aDJ--AXWTie~hVsVv+(x+Vi+XvA6k?U?(`EKZ
z1w1WNAJd;Ss*D)e!|ZJ|474b<LG5`=TUd?8C(oFl47*X79H-Q&dvyz=ib8g6OPuz?
z1#{NZ`mv<i2I;D)KGx@)0bhk3Cz#UM$vStgc6yh1pw4aC;-$=opa~9Ib5N}y8R20g
z%0(Zt)xujW3%l>cdB5HoI+e~X){C5G&!QPreBp%Rj=x|Zi+0y5gd`D$(-9Ed0qrCh
zxs7p|TV$~W3u<Dz;5oda`TH=n{{8mI$jBBW3dUlGd%Z6Wk}3F@mFSwqUZ`xVJNkCy
zbm_H?Zz;rwFXgl`3=Z3lZH_C1Qx!GmtCcF`zw?%ZE${0+uYKiP0!=VlHp&bP+C(Qi
zHm-cn=o1n<RP(}MIww&u!}#_D)mFHFHERfvrjRR!ToeQ^i09$O8``JZ->wM|P%%o%
zfA4V@fJgPG42U4Upzo3ELk};;P4XIhEZ88U-Z}(<V3?V{1hj?7U7HVki6M<B(8_EO
zyQ+F*G1G|d8JOK4z>4*Ic%Ms^eY_e8y_rZrdgJT)+tjM>gON)?T^Dk<*2|te%7&x^
zBwMyew~C9(j|SX_n;D=o+ae!B#62p9YX)SN1w?!_h-g`+=O<dQW<cdRzwsB)n)E@e
zX8N3&Abue0L&DSO*n9oas}nsR=c6Sb-PgYeYA#TPS{r!hCaCql+fWCWx)~iqN22ir
z=<xsm`I~_M2=E>mb|-1@)fsz1gDbQ(QchRZJn~ixWjl(-F%PsTX}J(Sl#~?f@!H`~
zj1p#SX4bOJl5(XX-M-(6m=hy`MrYzF8KKePH+ukA@Y03ummWJ<b0(Iok=$3%w{~Ju
z$C}(rOFy%_2g?P?!14rvSmrjNHIk{`d9*_L8sH<Jmq%Xxx>jVn#(YlX(Xm?l&~=^|
z`Q-hR11hhvyZL5E3?h8HT9Jj20W2Cz8@W3{H8ydxM>z<knti5-uB%p#Z?SsK*rd<^
zWl<6H9{r-yZQ<;$NwRIYlz#w?tW9==3L`VR0Yo4i-ah|hvz~dYL~|=8XcViS{fp!4
z#zp>GwC>?2lS=j=Aq*eKuyRPGK{&Jx_PtIqU<<JkkUmxy!r{peGPKvNpX5S7Ael&p
z4gM1L_U`>IavWW<kyU4mY5DZX&cyaB#)xC_>%94G3Xr05o-ouq2BdBwZu>;|GQubm
zx0<ok3Y%-H3-8Dt!v?bIC-!<3jF%16DJkVa7|@)}sBOJKI=hf@9R8$%C*Rcf-aN%c
zygkR9EZoJ>#rsph7`_B_ROFB4=XJph0}jd|pj#9~UFUrZZ23LoUT@>ob>ewXh>Avp
zxenE(&uLuIaal*Lo>eLK(n@0xke0+27!2M+qqo3c`>h~HjJ<U&E))3$nuehonWs8x
z>L@F=2`aVzL$z@gA1j2<V}#fPywqOJ7MD?Yi6&pD#?#YSJH5DEHVmUi_o2q9l8=>=
z&toOA2Y+E#1e^eXmBrT|Ulf1<_$dVV=_!Cd`OS~-PdwmC_@kxpM~i@WxAsd*MeTSg
zhZAnRv4chSwFMnq0yw@z+Ww&W)@@Tv&g7iL+r>fvhx_Mo2y#AQ0Ni<c+YkTq@QYWg
z$*-TOUKBjLy~!)J{&3EA;wkv)gCm*@59yEK?Y8Xv9rS`*mLXv9%CljZSO2HRp;C&V
z_zGM9PJbg@34*KgkSXw+l{;lpBw9@wUl@)bkS)^7;&Yn~o<*Kk{{KQGfmY)mB5}FR
zwEiKIL2CIokzt&_v4gzY|G^#@U%~y8{cg_`^?%6z4~@t&-2SN%d?)-L8a);JnF`75
zjzKUj@_Z&qa6O{&GU0nhqdpJr4-=@hr@7ys9-KU7yn(*E87lpU^%E)ybFv1tcZ!PT
zP~?t9zxTgYj}4hkK*@k3La#mveO^nU$LmEBk55Y~P<$JX25!KXZch3fzgiiNVsyK6
z<Fhat$HtFFY`MJ#h7~Nt!-&#;!|T@A2KYo5(y`RNnjBw7snj3V)M%3fV_dF2esoQZ
zzOv-n`fIk7QL2@=bg>UwC=s4F9G8HNr&g2P1}ka`yhobDj$<#<H)};xeKI4jp4XmR
zM>ZiQ*$r|HOmjXuexa*71`U5wO8%TmWt8Qh{cQO?T%P0Uw+_>26{L%3om4($`75^p
zu;7mYuN+;21e=$RZhCgvdxak?w!y1Rhssc>FA>_rS$2&Y9<=KQ)xNG;`g{fx_%p;n
ze&M-wH_jw3n|dmbN<k^%VHL@~K>_=dZU^^ZbEpMIAx|0>$}k}K7VOkNYDOZGT@%)F
zf8Bbkn!OY8sXo;m<EhY4bW|;QwR!D!mIbE~E$I*>zfuMaGtpicR?tB7fHFXWDp`y<
z#H(*<^&q~<daboQVWYWUe}rxS&dkoB0Z>nlp0x&VnNp#uWfN!QdtV+WUf}w&kCk#X
zeI|WWYmoNU<}osfvyW^AX^?UUlQ2|5oD~A`7*7#h1qyVqc&UY0C`t&mlt8+XLUN#5
z64c=wqxm<G_s=P=^1U?tNLG%Oyi?lY4$Lyp>oZ9~DXl4Mfa{C-+e*~oh=lb`@Tkwe
zWnwi|BEei0^jmhde(!v}20QMETC6E7LlMzC7DD2He+eMI1SHXCf`8=74@8slQ`=ko
zm?MHx=f#ThExEuh)L{x?{Z-Jg{z@5QWh}eQRS0=XkT#cp&OVw?M4~Sdq$oV?SY=vK
z7Mqa#2H{8K9|{bp@3kN2JyxOlPRn0W0`snMBX2~qBPa5!w)G~GBp#^b-kIbOiPS=6
z+#!bwLkl&dgrCU}PqL_of%oIkWO1!n0~5|U%&SuWbtuPp+h(wcaa6Cb5Vy#%2{Gb%
zYE6RCA{4?9{T1>bM(=+YSW!N)-&u9vTMxfO=gIqj5c{5}WMHwBp3-lN5JL%Uu-yNg
z1I!=#PTCMiG|1Y$V}s~#I+^Ix&QtTSM-=SB#PoBQx<rPaeSj2Qu+i?mnJ-y4Dy~0Q
z`^=eoQ!GU{6;d?WK$8axdwtj%b_qD4dnNTax3zabn{D5Tu-bJ@Eu@b)Knb}gQ=`af
z+*Fo-0A$6FCaCxjB?aW5ov}t55E+;_`bA0U!E)8)CHe;VY09}<;ntjY&xkh$;^I@&
z83^iBLt!xM)VE7OHa-~XGRN4GZup`iNXw4Qa9iYyz4I7T#&r+0yu>d2RlFC`9eiH;
zWhMVS5QAcHZWX1ZeZ`vyE`3S9LXdi+ejSq@Y4Hy`;Ju&%wN`;feN$c8wQfGV3%H4D
za-6yZB)q|H0>u9Eghr?&Irqn-C@HpZ?)RQ*hq;nedJwN<Qhd%%(YIReiQ1dMes|cl
zn%SuLt;5lyZhK3gqMrViTLl&eD>{|Ty?9kPA*3Dx?<tp{CfWl6F9Byid<aYBZ_m`?
zlY8;wwOUr%Oh;|>wmrX)Z~LpTA6i7#EVX_m=MJ=rANHYet+q5MeKYFP^10AMZ^lcA
zD^r&-oMjBMjPepZe$O!$xReihzy(*M`~kFhzfDV~x4hJQqM{VGUbB#s>xH*&HLpL<
zm84yt@MJ9xy{P10y>tt(eyio4U<0NUG*c!Q-@T7Wd*l(PWhsSH3^zt>P$rY8KYv?D
zl=@VoJN8Fvm#I-3^KLf)5!(Z1U~K+QL5?gSF)>rD%HYm>Gg`x91AokW&w&+J2$!vz
zwMGrBrqLa@N?0~ZHcA}Mde?8@=D^LA|8FC3*l(u9LLSK7CE!w91l7f(T0Rs`Ze3R%
z5%Po9Wb0o`Uv6Xepf#^uiFrmn3`eN;spaoJFYS`zoLwu2L{{W%=W`0I3d#^5IRuE#
z@nXWdH38IAlDnBEA}w5#F?TUk<5+})*M?lw7lU&x{uQ|+cJ@7r=KuinE@?m^>qXI=
z)?7`#9;U-71W9^ppQBvDYFV3=y7f%?Ts1s1QtG!%ULNQ^^YRkF>)$X8_``1Dk&p&p
zoK;Ux#>)|5^dqsTtKyFG{A9+e1RVKuC5Vd9W$JDbNse7x$M57<`}4gNuHF8^hc3<e
z`usD&nx3eq+_g;k6dX92Y;S@6W&oQ^V3YoU`PFvrSOh?g{!yaF#PGR-FRpuWYV(aS
z?VJ68*uP-Ea?|po0r;Nc0r4vN?_!?a#<|<}b9|=X#SlEe3k>}!U;KA5WUa)wSAWWP
z{#^{iQz`=1-{s%^DFzJS{9Dbx)%@R8(@-#tNZl5hL(G{Y%Lswc;wfJc1YOxdY?#%_
zfc*hDcq^zoo!&#gxqFq)uT97#{~Z0M9SYuS$g1(Prnl{75>)pYGV$&+#7@CusxoSh
zMC3qmEW0cArY%g)6v03Sw#^cs_<i`P@FhUNm9f~$^__@gZm=?yMpU)9+nOTWyvL}d
zr=`Tu9Ifdk*gzGMYp+;ph*Ft@+qcID7Mn4u<0VM}r7l#RiS!%RW@apUX{1U8iyg14
z6gHDd<O)FeoZ7eAkL+aW_vu%j>~6SARRi^$^0ek&tQ2f{AJtCY*p%LVWfOvctgsjB
zR%6EPqNPG8WyAM4==2l$Z)5Ki)p8y!J)PGi6G1AZR|?z_WGu3B8{`fpeYc1{lS~aB
zszM$w9F4{q`pvm3t#h?=jiY&xP#}{JtyQ>^iV@`lIGf8E`0c*K!p5~rK;6hK9rp-+
z-X_9kAx|t7Pi@2IAqjPiy3<%(YN*Z|jFetrAw_8@3l8oy@Sfj7&mBYls<4FbQtUtx
z6%%sJ%F~GNYLaGQTe<cYCGMj%GDSQ&S^+f{%5Ps<OgiD%Ti&af#pi>CMF|WPRre0D
zl2O%B#$c-j8CR?9HK6v_O_GHeCsK3O%bHOfpgS|HC=QM<-TF??yk9eZ&sk%9`LH$0
zv`Ev`QAlaBXNpvog4Z6%PYq;1vjPi?Z%$uv*PqaMv%8Vscq}Etfo329gKTWmgV)d6
zEAsnaf8LMs9QKQAJ@o~Db~d4`esRl$eoB?k!acKw^kT5NgFTq*YnEwAE2f>xGJgTh
zMpmzy{xNcm;aaod@jLm(Tt4%+rUer#oQL{H3~K&(0VnQc-7uFk>Ah0##j+35Z{;x)
z&8#x!g?UzN-(N~<*&;ULmZI^aS@(}oN3`1YkA~{X`!{QS<5?qDRfY&oFqJMqiAUXr
z^pDyVb56%&Th9#138juLqh+-B&1S!^*<nBJUEe7Pg*?QO>8T?~F(hpD5mW*>?Sw2e
z=9U<|H7hXW$UfBHWw869%Rwqxx4dZDAt$7-&OSq{rsT`o1}{$xPtI6gw-U^fE0K-g
zSB*37Njn^2w5Z~D``TbfIRCR6mA3?0ILcHs$$WwpDX+%Uc%V@bBt$;d4H8HD3?v{z
zKcT!+TUBt(gp^hKz?D>mgVxHs1kCbG+({&np?4ZTP$UymQ_$2oObnzAYVRL9@AyRH
zta=G3W)Fzd{!UEVO>?JDwUbSKPk3{-H@t=`<MGHRJ`P{W=1(eI1}j5pTr_@1Wo=x<
z{IbQb&Z&bmRZ}t;Z~us#W0r4B)p<^;%hgeq8Dko@_!1bjkOO{p2FKEnAYR1+PK#}*
zdcw<#B6r<Gski96FR}a}+j~8%Iyq|*+{VL;LdMc;WQE0{oc#ywZ-@tgp#)sWMG#vQ
zwT?o<lTO~v#|25zLub$U)Xbb3pP=H0o?T_C?58cS*cQ{6EU)_@K6doNh83tHbFTs!
zp)yyf5t$f~QZ7YWETg{AuGzpc<b-t++v{+J*$p)1kY)+j6I<XKC$YcTweMvnE42CW
z+UvcI?&Mx6aj^zZ%sJiYb~ut_uaJc^;2_zB>e_sc=TTP;#aj71Eym)=nQ^^}7EQt7
zp3uu=G5(Be4yKoyu!3DOl(6!NoZ_Fz^U3wgeG+bWJN0qng+ckP{=UwZ>PhA1hm0Rh
zKz79-j-vGS7s3o^$|n&SY471?GF-xY*!AAVjS~FVKBg1lNcqNsoBC+~_wo#srJ^L@
zHfljR29lmCuJ)GVsf=&(O#-K{*?V3p`)aCWc3Ke)%#CxCX@r}ajH`yoy*Kf^wjsu0
znAXE;>JphgH<T;mS$`Pr|GrJb3U(N=tS8xf2{?@nGs$G84)JT&8(3FQPp|ChyRWFc
z0A}X^gV+VR5F%o0Tefqk`B3M1Psa8n-Fm5hk_hec+LaJ@R4_xF72GK64PQZ*W3^$*
z48B+UTb6j7>s`#-ZVU-E1Ca?04I&T@87fugGczvKUUYAk{ajsn#KXF_yDwJ6mG@UB
z;PoSjX1B>DCr8dctt9F|I>*U?uN@6!%=InY1@1}n7F-bS8|?noBQc0-H-VgKZkUwi
zecGNu;5xHaNmV_ns*P-J*X?U1%kAtLsoqZY`Rc71;a;!6Mk?g`7|<k?@^w?PPPJ^^
zdzg3UM7WoV@$|BvNW^Yi`JMMSY}y;g!hvi^83+W_9vM@w=nw*RAnA0_)$Cc6eF|vp
z{y#tB{e-eKajCW9rL-SM7-z3Oy*BY-z)h`R37?A)qpZ|hg$$+APNgF16g?`&dpN_n
zt$oY;Cm}JM{*ilGzZIRLixeTnAU)*3b?5gzLI%~>ee^M_dnNu`_T!OJ+h)b#;k=TK
z>u6r(6ezn4IBZ|nHNVy}xte65_rkcWJ1Nf>gqTtE7!mZ~HlzH&KA<p`mNMyf3FwNJ
zqXX33BzH&YS|+b#b92qU12NX@nx?i*H@1*pqja6p!_l|0&pf>r%zNAjhc^sV4?rZ0
zRsuI=h}wNCKLH<hB&)ZSKe`x<C&_ZXo!|-MR`#lfu-U<AG@BhbKpyfajapU-QXO3G
z9c88`<N1g57$Avxv>!AJ^*G(;89Rjqjk@<(gpXb+ui#Mngh5J+!l*iwW}5|c2S153
z-Lp_WlcQp~IJTrfV^8WRB1q$&5aW*0XqpY8U`0%+jLN<ZlA0Kfre!20Qx3Xvl>~WG
ztlgR!f|=gPFT%2d91_n%^gj|pJ3=3_7me{K6d!k5qsVKFe;n_qG`bI8@6mgA>BdIB
zn2)kaeVHVXpUW)us=?g-ItbkUMKLWn6;YS0H=cc{7B<A}CL@6#cLfz*kh=#pVW6NH
zGmje5g_WhpuW19Z91h7*Boh%{BYdHpu}cOFkp;tt&zEeSG7Q}{!ea2y4A%M9t8alb
zhV}J^TD>e*J-|_WYM@{jn}M}N2vj~x-*`u1Ji!*ZO*Dkt8gsWHTR87n5_FL;+TRm1
zwWeJ+1m#_sk?1X{H~mzZo<1&4Q%K#SwS5;mfY&(@%@jbtQb^{5-zG#s2Ee&t7^PeB
zoc%b@?M;%ruaX0g2WZEBUZgB#f*V#|J7}quXozc{q@5j`Sf41PqMXNkJ#cH0?e+vR
z)>+-=)WADMJya*Et~cbuz7j~Az>wcxCE%kr1hG=ZGTo*GcCX6tKVDcxzq!YIy~~<a
zsdR>`_jqw7jF)!2F-%#=t@)W=aJ?;p7tgmnKk3;I57I{UB_z5fZZ3cI5YGInX!U&}
z&T62p+Xm<8hm^2EZl}>@a1uNn+?-z&xxWY+DVP8x%&yk%zsKYp^@nr!!nQm{qvg2k
zN>8dA=391s3`>dSodgSN(L)liJXca?*m&D60lJy8ImC|P)8F;qR3AIe)1+V;KlhN$
zX<?3TVij#eBp6T$4vvRXC>gNlCaotfAs>AenM_Jfr=e4#FHXtAmo<!8omCDIhw`23
zTB(rwl>7?JC<kcp9iNG-7WX;uX(}jLy~(sE;f1r-K*~f)aisn#?|eB!xzsbU0rOlD
zAmkDtLudu4RO~U@D2yt5u*Q>RmCWpYy-+a8SqC(9H}Gx-%FnAxhgYzC`>3}T$wD?`
zot{)*X0FT6ipzfM0@`jmK3OzQ;?I&;+?m~B52CHO4kYG`%j(Lu1thGdnpeO@#nN_R
z0Km=I|Fk>8sdk*(Nh%C+$p*|cO$lm~E!+hJO052oI8RXA`;*tX_Mi8E{~_>m4GcEf
z`yfsM<Y^i1<NE_g03zyWwKE2+oTB0(FOz+HkCRpu3FAtAL#o%9=|I|ZrDyV%fxI%3
z=MpC&g@0%p*?f8^B=vBB^Ahj~5O{=j$XL)^=0DD<pOSu))_!kC^+v);X-!d_QFaf^
zd~<S&OIlBhV|1Ebx4htkAdl{*j9Q<9MwNgYv;2pxT4bWPwMw&5>E5uZbE3Jg7ey#`
zUM&1%a(3QroB<U%ti`Y#NrXbMN$##hE-kJ^%RsW6DjxcahrOH(!J2(Mb)mdpPN@J2
zcjL+uMia#_LJ?h7%-=kT58?!cfKXjga-&x}Mg8|+iHmS}*>Y?5W2CWab4fSmZqN%o
zz169;(fjdSS!}fk(EChosMKWgHH4Cq9qjdY*(#J?YvbmJXRQTax8`~t{@XzZ#5P*^
z-AY7_B64d~5RTp4EOuU0qZ&+6Y3*A)qxPbCR4%uh<Aq*QG43YLi^HsEXim>ls8h;^
zDWJ@X&YtS($a-x$7L#$U)SiBgLl`{Z5<nE@kK8=e+%*%XE8SQFegk^j>Z6O=5T^SJ
z&gvx&1bM}EoIQ0fnKkXZzTR%5n3k2wKUT07z7f*qmZ5GW&7#E^iB&jgPfC}IA-lat
zCeA!qt{ZU)Xu1Dgx)qDAD;at6#qJVN2)}~<xmSum=M}cYGgA8bqmg!peX&6vm=YPM
zkw2-G#gi$T<S^5|^2o|VZ7kK9Gwf*5zrw&+fsaOvb8NnJJWe~`V9u+gWk(}v!E&8g
zKsvRo1F^A`nQKxh0P!=(ARZd(ee~*J5m*Kq*yti97T>EI{8Vso{dD-J+2r1AzIFCt
zCZL?c-D&GHyAHPa_6p^^4WAo~Y9t3Dt`A2Ec*bqD$KbT#?h5*Scj_Cga+;hgd{gAQ
z+;8*MZL$aPst{%e)2~~GJ6Wfz7;U)HGP)-#uHZWC_uGCwOsLO$`EM*#Nhz&<Iq-gk
zQXm_eLj5&kf#^tQgK1=Mw#d>tXM)j#Tv0?^97Ad&*@4htYoomv+%VVRlv0mZRP>!*
zm5H9yE2WS*XgCQhiu>7f72~e_=ZZVLWqO~3F9BQBbS0}_-%ni_Pmiptdp|DHqhsl)
z9@9e2*kL(<seNSR(8d0xu7(5h>|xWLp~mg|G-?YUzAild@4VA*B$p*wP8Op$Ut!6P
zWD=aBc~I#qdR)rkC;efUfSj1QxD#-FKuG91Oe*_sgfqCdg2<_(RO9()M$b$eyR<r~
zzTj}G;bj_ig-Wmh4DQ1a<v=5oRY%|{`kE1Hiy~34-i}uD?{DjPdywv?MT^|hA`uuH
zHKIoYu8<1_TMDsTH%U9f-~}*vMdN8cW)za0pq<u&^x{IcNt2QFJ?&~Xpl!trIy=%?
ziJZAl2y=M>i^7jZoOt^u1o|Y^z#KACd80m=al!z%&U}d#Q?`x~NBqfq26|N#3Lo^J
zschY{!zRQ-Gq^lXs$IK>N;x->OAM99HI{s_MWYYIJnc%taWBrIM@LZ!sh*`J!_T)2
zx${DwLt9A+@L1`@ToZaDC8t=}8r@fVV4Q*uT<O46y;>=wOv3Cc(5=Ip#rl@5jXUK1
z$*iDcHd1-1rJLg!Il1jsvcPbLCvnlc07~FHlK%1``y8=HPMXLXBq+xqJ?v!CHrld0
z`C6Wql!r!t6+MW@kl!<zeeBD1p#qwsvLlT|so59usC2BlOjQ3GkSh;7D08($Kxq^Q
z7^GCl4Qj&DV%WTRKUW|{U{;!<CBB_jE$o(!2~G8k35PQklvWVV>?+PU*7$Zcvfg^*
z@}9B=DID7#%f?UABQ_IaGv#Vp4AZm(%SUn6h1yq$Zxd)9bb2s&9*q2OJ1I*u+@c=j
zUzz;2d5eqvnf>6HT)Xr(>8p$E0v{+o&~Gu+_81O`ZVf49T)_;X-1D=PQ8n`-7=~GW
zA1@xr10&i%E<o_Jyy&Pt7;tIj&X@9ZOgs>sSdtz#Bz7iym4V6H9>^_`aDcWlujUZE
z!9Y>=Uuy4wE5?81{C`B<yXo$#(}Od=RZrEnL-~I_+ge^LYs((_P^<}_#SSOX9SEwn
zqP|`N&Ld5Aifg2#B#Nzd?iPH&b9^fAWmY&h3g^|Cw<0w<=23(g$2~^m$~?&-lRa=@
zaa$emP^GRGfgFLy<&kw?bJAX1$6Qbg07xzYZv<B=WY86ME)hOEF<cI*?B8^)9wWi)
zHjjkJU5@{fgswM&dPVJTioYrTruduUf1Tn~wO4a)>^WxK^zqw7H!S-l07)7CM#LzK
zQOz4|q5e&={38D=Zc@+j3hQRrGVP3N`a8<z5mwIJ3;6l{bBcU#d1m3Z-q7qr(bPIY
z!^9C-vC@m48jlK-OorcHzWTj5KsJ*7CwICocK1$gM_wn#C4ju6xsI+A1)=*wzxDYK
zf;BPuN8u+iDw6yeN@m{4lhyIn33>--#xzffak-AZQf<04@zK~$!t_ykQ9u>t)C_tw
zi9HFO<_#ct%Ny3+X1)C}lLt|dR4sP}>@0Z0;O_F~DtSlVb`i5V^RxPsjs)Kdzu|}4
zCTy|PV#_1P`V>OZcjrv*lmvE+bko%f<P4cmZ0#t4a1cL{OcAORIugy2I6rtLcjV_~
z?LzKqV1GyAy4jtU5YnmMw3x0Am9>*DEWg%Goc0s>b9_=Pt<FX{q33Zf!@pH3@R3z7
z^Ktga%v!~pTuwicjkW#;xDk1=w;YWXGizDKCd1%(13!`Cv@s>wZl3P=dl5Vylh2y{
zM#!EfIgF?3c}jj1*LWVB3w{Aby;tk*;SP*jWVh@wDs3i+w>b{2-Zz$Dk0vsSPr8Ql
zZr1x4f5!xMI1aUrZX!+;bO?I}iyT%#AZ+qGhcKlcI<UsH$Il9wSg7^ZXlm=%<W-ph
zM_y5w^OWBdXizs?&&IfkeZ&2OkRMB{`|=-}z8J;n^Q?2WC%H%M5-VlWAd1f)-tcQ}
zm62C$ntx(h1Wi+e65FwVTB6#g)$>2G6iMX+^3Y|c&%b7Ba@W}TCzkN18o&1DFO~bX
z#D=l7rhi~ZCz^_Q%{1TKeO+Zk@eiZmS0fetiIs0#D~N*xI;i;JgJ@K>?5P|OQaX78
zU02D}8b#=i7`ON+bz7HRvbT#(&B>iJ8Hwy>-6TD8*{-C?D==5wb!rFN=_ifm7gcd^
z=vt{L82_{<(TVMf46!Wvd7Is1mdI#&j=-kk#lNyfsULf<EcgGaQK1`tM-u#0?vJJV
zPu)MBGinixf^JF6UC8Im@S@RKVouxiatXSp9vnfatEx=FC#=;N6NBbgBKyTW39SHf
zTb+MN+6XP<x+W*Slh?9_#%|Ls_QT$OgAniDJCE~LEbw<pHLAq<*yW`ydC2b$xtH_J
zaQZLY62*}(yIao<YiZj}y8s)Ggc<yg+_SRu+kfSWUMrc1C7)D%f(ptxu*Y$(*36z=
z0;KMp+*ElF>9MW*a^d-M_ilOBceg#KhWQ~Wsa618VQ(v7%#6<brHjm%=ou<X&22R`
zRcULW5))?!W;cnT+6Rc=6d7l#o_zVLz)oC{v1FU{Iy=pJCQN++q!4qZ2>`e%ZzZ`6
z{A6z^=+U%fxSU9zt_MYP)9+y*7M5{)`RP*Sj6RR<QamSI)<{6XG$Lal4BnmKV?K}T
z^hZ-09rm6H#kwnktML`6Ct;)UGWyEcwx?GTelB5a<Lj5>0rsCx=tGnS+#cO8I-gkB
z6()NT0X)yS6ONQs7V@gBo^+`r5$~rzgp1`FAkK919>0qbQ?wW4xda5susFPok)8zr
z5FSri%}f}bv?OYCh&W&gd97g)&-*(=;vdf#*k`VdR-E}gK6l+Tn&2{j_z|e`WRpec
z?&iPd;FK2@vPH_@PGzt`cYpPtW!8<in@->G8Qx%*eu%}F-q3vFOPr!8_Nkua;b7{;
zXX@K)Rd3(3pU(T83Jlo+uE2e=0iuaJLC@ro6jKhKy?V~9MEWyo@We$?v=w0HX=j1{
zO#?P|Cy*nu%ItzLuQ~bJOB@tJ1#}m{_~^}gu8F6Op%C$Fe0(9cyodIt8L){|)H^)e
z{Gks_L8C^0ey)cj)|*^UaK}FDlhJCIapEmUvd0s0AF6s{q)m2m?{q!zpI1x)05$|$
z|7Ds|uYTF*+tr9_7VysF(T=BdhT<i@LuhPPgZyW~s_XGTEtKHrNt~AGGv}`YyDD!r
z>6~`0pYX)5CxX3>L0_o%SR>u<`GwUw-P*JMkYExpsm%V%I-{P)qlO$lop0Tr4m7ns
zU75wYv}AgEJq6s-P7K7gNhu$j;jp|uuAhf-hR-*6*1yhUzA7&5xb5TG#yXv;#F7X#
z5UQ(oZ!MhUt=!g`!wiacCA~LyQi13u@#-?L66UjAxNe;p-ztqzor`u5?1&HfP=7BT
zw_)s&b00ol`S(&s5i8#_OK=|e>iQ*Mg_6^3YG6jU7q8_8w`Z^PAu<jdP^wcZv7{31
zAfPh>d{e9r8fy!r7=4B`sU;l$PBN1_nxXrkknJuqk>OFN9fT--N7r31DXqEKTbxU@
z#gj`UB~f41v|QxSPJ}lZOf<mdgHDPDX!0t2AiJfJbd~q(E0%nb{q|<pTjHUE7No>e
z@a5C8@roC(V|-!Ddd~LN#PN~bG>u~%Mf=>QgWF+YL%1Ac7x_ASRR+!xmAy`oUS*+*
zq>^Ylg>hqXdJC{x6%3Z28R;e{!zsO+acAu?nWR8>YXk^(>c}mK$I%GU9~m@ms^@J7
zDygQJs8ip1wDSJeCE!F@?^O5xaSsu<j4bH>lQqZ|7lW31?vrm%(h04TjuuoCcQc$l
z>iZm-rygDxsyq=awbKe%2&xp>Uq{{k+GXoHaX%)RISa<8@5fyHxwv}r=yP<9S18qj
zz6Q_4c#djxFl8p;dy%u7Ts88|AZu^^(L+yrbL9`w2_gDRx7F>!xpE;4iwM>4gp=E8
zjF@UUuIuz#PE|HA+gH7Znv&gmM)~_PWVH--vg~%Ju#3$%Qydg2+}}$-t{A7cEMEdz
zgkG%4agAf0M0%OygSq^XU6J|S5UW~|q}n)cdBzx4%5_5{F4$*Hqh<&1wh?|$-?R*_
zbY}*UVuD%>pL&S7-C@|_D`4UCZ&=!odGMe*Z>%^Lg^cPem(wfI+*CEUx7L2(TMVP}
zH_@mB36D&CGI{+FcwIfnStF}xG(E*BH<?Yfp{H=!s9P+G0RHl8II{$;#6JDICwS*H
zhl`o4gA+?*(*s$P8&Q27mPr9!D<iZ1#ZzL2TcW)n=N3e;UcP~aI;r0WUJ7ZzxDjd|
zxD0h!(0!oX_Q{%$<gH4n$-yUS#2p0(I?@VRT_;g{;e^C@2!@p(8~MseEO+lg0L7%(
zQ^yPR*N@AOq8th=n2r$ufH3H`&@G4K8>ubdL)hZLW)@T1a-t8<$Q0Rgd!F!U=bC8i
zs%JO~)TQkyL>&^y%#asN7{3|kS-5RI5IY+Im0OG<G}&1hJb4OWNMFURX^!_Xs20$e
zE$c_M>BX)Yggr;B#P#rv!cFv1hDh{drN?+yj17+E(Z1?+NRc#>CG+@4wFL=ULvAbn
z&U6Rd_yTDrkw;0Bxgd}reyaeY$M2)QQ<~xRM_jQC#mx8mx8tOkoV_&Av?L1ZTF*GT
z$h7gTTUGcj?!P?GT=R}%%|O6A8wYhV5@w3mw>F)|k=vs+PAY|Nivp`j%u=^o_w!ok
z64oaJ24ip~Dly^$SH-fZki8d%)e-Sbz3(e|uknh*Pcvi-@}+^KHe2o<^{-Zo(gz$9
zY{ECF8nxBBt3J;>8LJ*5<U*U)A!))55cR!|CDtW+2-}QQ=%7hWl}NEf+z+s8J)jh_
zu$kNwD1$55v{5;kR6+CG&DJ?+XU{(743_g=crB|g2{%N!HYLv|)<*?Q<QiBF3&Mdt
zsDet(RQ=%MHjdW*umP0>lv~&H{nn6eITN6`WCxXR!hWjtv8DSv9!m%5U1`4$=Ac9`
z8<G}BxM4SDio<kAY(uM92B{vwA%ebH-%e?T)TNCFw+`X3#VO1%NHxXw^=?{)GNwH=
zd7hwI2pw`m8NU=s3}iG&^%1CXYmbuQ#zs|pJY?;R%)hViusvV?TC1#&SEOe@4>fuU
zD<qfF&yQPH7jTtP>+bHh7wofNG*ob(NoZc<QwFBx_e=}lm&YI$l$b(ZUDa~tXXn^k
zw0-w<Bkf4=65xpKpe19{uT5Kh&3AteWwg}wEi*{3$I#II5|998Fyu9sYhWKUFKl)z
zguq6}!;yygL7L0PV*a|Wtf&j2;g}Nw?bqyP4?UvV@>v?uh&``0#z93b3`Ht23itro
z#q7p0%sn5v@LkOK5+L?)sPX1}*gfhK71*uxbp1^Oytzc<3R(OHQ_kCnURFa2fgu`<
z$!%S#umcvFh&WB=+ee?xYDF&rHj7arF3E~y+Kkg*M+c+BlXt5>B$RY4#h+*Cl+bnv
z=~fp-_;%TA#Xa!B@E9XoyZ1S7xRC9V8TDsPEi?<vI{BH?<|xJqrf(D<rs}z<8Z)3!
zxw@45NzYoV1g?^^hkgK;;T2Q~i5B~=j`3;UsgBUhYh0>4M9-4dQewCZ6~O9G$6^4@
zXk714PdI6J8kQ~igLSJC8wy3|z%gK%7WMvtE*6QE=yavK@p+j}F%1p-8XmfRa#YK<
z?f_h>yD^^+_7rXnjjYd60e<zFk1Gn;KeV28hDuUm-%Rr^NI9H!YrJP@@UPT+<2m&u
z79A=WbwNotxid9_cyt#)%F%HnG`s5B9fk4|A)TrFy`pOx;bvJ<Mdx--gLawroQTBK
z=WHY#5bvX<m}42+IKb-ZM&YWVvirbWYN0fB1ISjbU$L^=^k)XogMLvq?$p{W;u~)l
zJK0cCL)1yWFWb+1JXRlc)<G`d4-K8Q{4{%I4QrfU)8g0Yg=M^np4H@WHqllr&u>nM
zE0m9WbP1rmTCa2qiun}(e9jBORwJ+qaR7m6lJ=bt37fD4pG6bTNahTSI_&nhqH$hb
z^BBv{u%z7XcuGx4DM%@`8^bie1Lx-AQrimUx=MARV$WKdPNg%#K5}lju#XElpf~R}
z1FuVsbz+1eL55Of{SghVZ1p(~XRg*;^COF#X{nus#TR~$wL^4Yk|Z8iNs0E|v*MuU
zoIop#TqjY7t0mb95JPqMIa{nPla%gnBx4D)Z`2bF%(O%`RDWAf8qTQ6y?xK%5>N=f
z8tE1WmVI{A1`<I}QitDgxH!+@w)vdLi0yUO6xx0>H$atsKDn;0$nPeQ76s%P<c!OV
z@2Z;>u7=W24O{|JG|Xm^@VCtzrJ+8PUq0HmB@M_ddo~(yTOjM=LoR03K#<hR{-xH)
zs;^z6q8s`iLSv4~!dE?vvU78jAtczSv4>z>nccZLY2(Io>yXzU`JA$nw^elbZGmYP
z#ZI22UNkChPW4+Y^_)o%4w#!3y_Nafu>G&_&l`pFExddaFVyu&aLV<?S+*!Ahm<(8
zZXH}pjN=DWgE&9}uENoD0s*y0?wGHX4|Ja#-a5!yor5FJdYw-CMA7;!hWM}AyQY&4
z%J*I$W%pMh=~MMWg22X^Qm*VI{$~l;UK(r+_c)Uaru&n`oMOqV14uD70*(<=+tyKm
z!;Po6mdIa3dKxO3N7{?*O%U&G&^gfQ8-*oxWv>Q}<+V83*oW&Cn(g0kd-d5bU`j{D
zEtT08X=u5uq8v!+>Z4@2c`<%eTbOC|N@GF&$=u}gxw@781A##eq0NSY7_Fw<+l?K(
z1X`6f9U6^^jE2wdd?4W%!wL{WC7EON>=LjzxZcMtIt|EAj0?_qYdi}sk}5u>l2Fj#
zg#g)+b*o|pLzj?VTm{8b04_EA|5eHM(|=onAi(d~3&=aX_oT8N#N`k%`(1Ut;u2sP
z2G=*fwMKlT4%z1QC=X7m@h{SS^Pnq@t&Xu&d^VVAoy@nINf)VlPPw>a{@C}!FaQ^v
z{^M*y-FpEMl74%O7Whpw4T3<s@YW=ahnlJP4R}uaK2KoOmOmLcQJMx^JFWaor-Yqk
zrEk(MfY|@}cq7->RY&wzPBqO{?N5D=$>x-ZN4TFDnO9Yv&mI&$-g^0o4NQcXKY6G1
zZS4LB1q5@w_*bR-rZ4X+qxS#+ff$;<D7aA8>%XoPKGeSi_;qnf^%p;SV7*>^aU8AT
zJ3D1gc_NMbahtgnKq%?_uVtEvUwe4{62NI5yOm|So+JQhu6nIE_;_&cd-K&er?9_x
zldDoSj+^<9vZSPDti`f_-bnPzU$0Q;!RZ>a?2fEaE#u00$R`f0N4aAs)x1;$n%mdd
zbrziUr~3s~i<OdDpc;LmQm){yp*NgHGb`?~kEXZ@HnFKFVO%-GqEwy?N2+1s<{6!D
zv46L!E+*%TNX7%pc2tgyTjw@8=)VeC-RC;ta(sx0DSzPh+&yG><hYFDcC_xx4-ePq
z;sPrF*;H9?IY_eFMmIWgcgSHriZRuwPF701msIq&JDnt?SLK=dB>g#}`>m17KN~-j
zLDiJMiT{FFcB*8&kjDe-TuAJoZ%dVcIYOgTwQ<<nmEIfv>yq~w<(BD*%-ykjQ$?%L
zZq&^lMB=@^5klX<;#BB5Y+P3?@Y=LMY{wN19d5D%a`xb<sHpgnIiA`yh<@jf7VqWw
zz7e47OSeP*&xYmps39zwqdy;0Vgyy2bFSWRx&+WQ#!CI9X8~bTFA}?$)+jFy-}1bQ
zI1c$|6Mj^e9s?!~dH-1N)MEMWR?^(mQH8_;k7u8=!|6R{mju<b!SmeDw<ekX*{~+n
z#H|Z45g%x8JqpJyF!i`U+PLyKXH2l^<(8S-8{HfK{^D>_pq&PuKv$wZhicTXzs0z9
zep7n#>QnCz+qL|?`OOZkmMXJoE|UKjbPvUpt@=j%_o^O!Lr~OD<IDtno6i-~j4sm6
zK@*#V)i4XVax9MCAGiKj8SmpJkvCl%r5<aQB(emT=(TB*+cc179Xtw~4XPD4d%6+<
zy@nPnhUzXVDdo2Jx7W0Y_&eZ6awIr>$@r$cdcREkpN)O#JELq(9&R}r?-{>=&}z3f
zX0MQZOb~qo6ZuTujuEpZbI!lR>iOF|(7LYE+Ap4{&pC?!Kf8j;-^@YyZ{oiocKfE5
z$Y|h}%-)SWqJig+&-N&(rkB$vKlfn&pYH8<5QD<}sP?6;1J%-EW9)VP(l&W=k#WBJ
zor3K!od1b9xI;UBJ-WhU`puVft2yPHK&OAXu}NQKaSu@ZH(q7-|8Do%9`a&#o!t}$
z%X5N9wslBYsTgG)(m7hP7$!xt>Z@NFGpI=<ndi&R$xqj=)^t*x`V|~seq-Ma)i_-c
zsd|8)7`2`0(f(hb__#}Q?MA8Xzg{<^CA-%j@2!&WV{s@%N+3G@p?G8Np=ol1;^*=z
z0Dxr!^%vQ|e+l4l&k#=)-66gcrv9tzKIIqIxOc1kcP;<45>I;Q;8M1e-!KsXk>8XQ
z5FEm0f1~}YDgh~;FV+7^l|YjD*Fx~GLs~dsGPit_@t-m7y67K%lrHbX{#KTF3ZOXb
z`Kt*LG?(fGh!n7QM2>xu32wUJ@0^A3h{SDi79Dih%zo)=^W>MR&+3}me#-Qe(SNvX
zd-lnV`z7Q*I{;?@@{2-EDe~Muph)~@=St%hjDbn^`&9kr$4a0EQ@io;Izc4|<C`(K
zj$ubdEst?M{}X$_?jM`s_iQnK^LgbT-B7`YMG?`Xr<1Z<%7uHjw@^aeo<rq_>a>7A
zm1=M`e;B6w`~UI;t|qQW9B!`~{0X#JY4rx4RxQf${tMdGNVuZ&So_XO^W5v^8;MR~
z0Kg}iSmuIzE_O50JslQ@$;4X&dZr4^EEq&_hhTd>stdQZCdnw1Fwn}n^ak<%vOb$E
z$zwxchd)86v2V2rGh`oy@*{i00dO^C{fuGaPa>%Z;rRrk9q(d$&Cpdp3dHal@><w?
zgpJm2wbm}1m#Ml~M7NhPZ+=EQotRm|>*wTo`2?=Y$8Fxu8RgZNa`5a0g06!|jrQDf
zDw9l9xWg9{;wY{Bd<ZA==-2NCu)}5PKRAxm*Fr?|SZ8c03vUq9PpOl>Aj&Z>>Luif
zw?RZ=#RxQ6YPZXC&Q!MRr$8?X$1=kVSc9=Fkv^O3#>+bapKH2X6qK4k!N&QMJGD%(
z5HwN!ayuw!fK?+{!!%qpO|v{RCz3LdvM4b;>k1`u$H7-BdkSPXA8g`ocIu!Z*5}gf
zl<?fi$H{>MO3azRXyWl$V%g_A##nf8*KZ9o#ZQB*o<X9!LmYXFkq*plCgw;Vp0NI!
zxKtmzE_w0;rF4_WE!=5&A}t69C<Jl%PS#&?-EE3XzhpA~>|N^G9g#Iy9Id$!r;6d&
zD7zF?v{(gGlu&R|7`e|r9203XmwfC^Lo8b2XW5<YT&hbcSz`S;TExRvwugeP0h|sI
z=y_8pE)I>M5+JlRtg$mtZ)O>i5^lM}Nw=6C*(a<i9pdd~ncp3*Wa3FR^(hi68$}Xo
zH&R}LZ&413Qrn@ZtWQ`84hriTs3L)e9rj-WLPK!{ZZl4)ux5Q}5_F+VcA;;$AWtlo
zP5oX-<q==(<&6L#+;8R&g15k+4qn|-9MBR3z37v~b#pGMw^Y~N*HW>bwGh_((resW
zQ}i8HY#iu8g91TEvg`AcDWs?iaauQ|t>#0Wv35CQtg#`n&ZW+}7%iq~L3Pv6@%0VH
zag1eJTH!Nt+@yll++^+gEq$W~a(|{cefMGl;}YRlV--y3wMh?}cx?JG5<HgOhr{s1
z?9fTc^PRvM<LpRb!5ZI6$sE5XD7IK+{UbNeAZVT)Hi^|N!s=rn9J8*#B(6x|flELH
zWkt@yj8X>eRLagt#h9x>0W6%ipc|-a%FQ7<=XbLQ33_m#3iH2rKyeWPuTiehDuVGJ
zr??gNn)Qf`r;$W9Oq!bpXO1++>n6FO43(qPMKYzfoz=H0*@oHcEGh(>uj_87>lt@-
zIJeZ>QtiX5w7(8MP!2pclOiPw&80c#UX$w^n+ejRJ67+sa6i`;cV^gFtyn5GqcMs8
z$WFUC#y490Qj)w*tgmx)ABZ7=MM=aZJ=0zE*<z$0(Pe`7y>RLw!S0DRSGz0BLHKh=
z%^^Jfu||}3T6j`e&{UM8sGhUPw=t4D9lz|YUa<r9=uAG&bv9Wo*}Sgz!de54pP$~#
z{A6%?J11Qz<o%tITBhgg2qwcP2XqwPa`cMl*)CO<gG<P7m6w1>r1vX^COr!k125lX
z7U`96?z3s;0=*JCW)poNb}Lmgy**KRlT7TW-g>?CItcq539AXm^M}TW^!IRC=QSsz
zUB~Vqe=sqUrpBg@>DJgM@|mSn?3F=+4uD7*vdAcYXlykIJX~A!wqFs*EK@pLPBrg4
zD?0{i5p159l2g>@4GWe`kokPAJ`<WI|Dd`{6h7-J;3{evwjh__7ipAexG{pfy{+FH
zp|k3A++Ih_>z3;!l=e|9(K0X&5sxVQhyxl`n)aMx_BK!`H!Rj?O{7q-feYrk`ID?q
zkNFlk@j!`H${@TPGAm=zac72Ayz!+KQ;fwEH^-ADsbkMb>`n@)Z`i%#b*tmXRgu`B
z%;XMdAl~)81egz9EO9ibX5KjN#AQrOG&TsaiyGO~S?ezzLgO3PX;_ODwIeW?)q2E=
zJ$rj3N;SXs(E?+D2`^Yk>?UV13n_a^i7EWW`|C34z~X8*T@N>PMD0?vZzh2Xl3kYJ
zh>0RutyHxbtXI<QE;9o*RSMO~kFTao{m7*TWMEh>BRgW)9La`{ma8DWIQ;Ovt2^X!
z)06aTn`czGnZd9a=79#0aST6LPMmtN?QY_Ek^uGRtaT;1<+ZVyja%;~4Kg}XIzA0X
zTmp2aw^b>19#VxF?GJ_j_IIzH>OT&M{~l1@>DGEJzYjT5F#4mbnDirZbs_zKk6g*W
z5)}RmwHCIqI}HN@Mpp`c1TINS=YV;_?)r8^&7bdQGyRO1MjYMozh2d5F6h4Hc4uU>
z>)yXj>Uzw#*+**M*2VbgBF~JwSAPY^`ykC3#<-<N{fz?jQ`UZkS#I;r7V}qo>)Qc<
zhnZ>s3UR^8TO^s#ok{@)e`0r;_fYEmEiw2bD@}M})_&12lwFpdAqlkv@K$8a<6LSD
zFtL8kIpa80CxQgNq!_Vf;J!f|8&!X6q&iNq$M3-!)Z_C`2IKbZX1EP-eFe=eO6nP<
zls5>>I$*`i74Uoj1Ntda+Ii$d{p%T=f>Y<*loIkQWw~s#Lz<1!Z!1&ns_5{x$4l%u
z@QpJ)<DTH}Ow%e&^Q<-=ER@1(_CG+Sf9Dkki)8n};jhRdE61`Q3bW`PnD{zMvZ%}R
z%({-+tH|aJfCU~C!1<#Nw9u+O2GTr}LDZ7rlQsHj(E?tm7m9>8gq!d~qN;+?aVLl5
z%9jA5>4n=&Wi~3Cd2{z<8Rzs<Zj*dK!y?jmkeo%6Mb1n`oQ+yrx|EDD#a$}6k99C~
zK<lJ3<I~55fvIDyS<g=#H!lI0pes1{^_fDF1LhJ)h4~75TZ+3&>U1M#ZqCGCi_G8v
zeO27FlDh=NA*kttJ&bg2`J(J5$4|c-pf?c>G>KGDQ%f}^U*HSBL@NCyhRk3_jj$mc
z#<A2a7SOq@1y5hSnWy&Exc|}Kbw@RwZR;qAB1MS;Qk9Sd0tAO%L>VBIgl1^c6zLt2
zqM)GC2|c0r8ahe|p-7cp#n7ZkN2w}Zk@CEAMQ1JN{d4b|_1?TY=Z}-Uz9hfj{`NZg
za?aV=CsH-#9MMJaqCp7M%$LcMdw-_6y+k^sJ>asbkxOF!WU#)CaHj$A?UmC)&OKR`
z8%256XmCV%ES2r*thdUilP|$r3Q)75WVALvoYI&0USRb8g;hK)U)dNM``EW|d^3ey
zFQ329dsVRrqbJru7=0dvIlmB#mjR~W?2BTMEo#EJ9(^DRO*9Xue7h$HLtRs|&!dyp
zj85$k`vgCGddFIGcJSF~knMd{+Q_>vo?ndezZmSNpdyG~Rpn@r(t9=3h`k-ftgKFn
z4Rh+t(rrU_G?xa*E?_EDQRmCE5;?J~y~dHe2lv*X#mE_bO)qP@Gll7H^Y7pXh!&sd
zX=&K|4Y>Fm<6}g)wiggDTcl|^V40sv>k=hIsQJv?0c+%kHRH<Y6KrIaHXTiL7q+GH
zlLn8^WosCQ_nqapUXeHU!xEbeEMT%q1c;>iaX9<Oe(A?^>pPunJY+kb^hB#@6=NAK
zLKJ53c&{~Ad>BlY2Gzq)UqIFu74v|V|Kj<S0Ip}WXU=})u7MKrigZPQC*B;V(aBTy
zL5IcDZ3n#R77|<{We0`>`y23&(dh+aM0yZe<WjdxPV*h=oq1)^L^Y`kc_<J^-?(yj
zWnR5-<o*inIo^V-^C-S*ynW}nh$ZlzWKbNJ=`U-dgqX?X0UQkv+9Xpg=@&HnaTY90
z<+bMGXMtSJS7<L#C_ivg#iiXOGi5XxjfIq=FO#9;v2>2{@ifnnI@!63p+@4eTMu5m
zKc$&zzo}O_ybwRkb|TWeD%(k^?5@aVMivkpTux^hdu)M8dvv64NjuSgx5qHA<5`=H
zQ0e=VrW{%MbduQ<357cmBe~(nk?)v8a0>Dm%9T59Tl;~lvA)~yA@6ZTs@KDr>l|I8
zZESqq1~+^KEOcx{c0;S=;*Ij~#DZuYa2b34!Rzd^K6icL@6!i!$dGs&kVa%co#~?8
zu!G)>0(eK!i(q|TueWnekEU=r+SJK<=gifis)QUHa323V$EnO)ksL5Ja7o8<%pqV`
z&dIMvb3J9oSi4FltCqo4GQ}U9Vd#Q)U(zAZxgKpLBse9+F&-wH`ySrP=VpmG1mxPe
z&QSjADt{`~jO$j~C-5!@-w(6vtL)Aa>b}Wt*MGC4-Tzf~lZq>(9em~tO#YxAhmUR!
z+4l3|r{L#h>fF;UI;&Bm(Y9J{!hYeL(+_EX7XM?>Zd+2T`LgnT#bt+pc>@yw;L1xd
zfP%R2OamVL$oxU=)!g&#N@HLpXVw7*uzXsHkdP4QA0_7qzzCpES1h^AbFBT@sH;VO
z)S!4aaezZfxJU}7p@Yau!AVgE%V0k;(csNeBoVb4%GjGwEi3m@WF7^=jR_dozpvCP
z(46kq{DsobDM3N^6!YtPhwVcB!PARHMT~M<WY5s~JqqS*Y)q>5sSQ@58>4z}xiONO
z37$0wKZ8zso^gp13lZ%+XefQa^0@^2!q<V$tb>($?Ltzg2Fymay{sEb`0mM5sTn%r
zxn@j~KJ^f76dlNdZ)vP9JRSGDfvA>a*myM>3(^ydtF0HaF>nvo2<7R8L*;XTs~2_$
zKkRx+X0J-P<Y$sjrwxiqh!Ko=WJkoxuG_c-7TcADON$ZYF)3v1;zJn8j~84%^K0dC
zd(5h4ORiIg=8(MIBT4#7p~&V+H!a0XUth(@m5gy}J%*a<=h`eO=|;~~axBvY^hPyE
za~4zb<ykL9yr&NVgE>z^$M^+KdZ~x`9|Fkx$bxk=xLdTj{V1|?1GFV2w2(BL5<MX4
zkB`HpS!aYTEiB$yHQQK^-1ZXBv$c6yjT_WaUb|G8J@dAfBhvY5(U}yR`WLq-3W08q
z&+_ruhC#~<ji(l8F;~^;Ab?l8JBTZ#VXLxy62&*zHH+t3;(YOM*{$^oWXsNHr6h~v
z6%-Wo6&Vc+hjS}>>X8^Xhc~G78^XOAiRj|cV~80d34AG8VF)p)RnElyk_MX5P_5B+
z`5IT;J+a`AE)`=>Tk<r`MSv>ZLq>L^At5`GcwzU~CO455Q<fj%AI>U1cfK<AY)$qZ
zZ7HFqD=c*bDLv8f&dJNo<ry%^DySJF0?YHem|=e2YC#W=YH4%Uj?=x=UW^LqZVx0p
z5xDPQ`Ox)%+i>blRr2car*vn3xc)(YAGb~JIC1tYE+It8ckTg3DQx*pWt4sHt)b}n
zoGU0*!i*ao(=5hLGs;$X@x7`9iKN=ajS8!F@$DSzk(e7%6t>UKRM*nwLRwFeSnVbP
zSndl=A2~{~+Wo<yzJ)63T4(3gY&2|L6YcpTw`RqyNbJN`O@+P`tKBG=nM9a!`?{#&
zJ2N2=(el||+JHw+`y{PQhZdr6rdkEIiA_jQew&;-&UYpkVv1oh##~UQ4lwJ6=5!_t
zo;OD?MUb31b0=_(9Hl+3JPj||&ov$2>2CK8lSpW)Yzx!<_|Hk{;*)<}p2*cp&po^D
z0rWf@^TV9~Di?Q0jr9L17xU}#Bed~bb=D>grw;)?wr;Hdk#N&B_}|<|B$J6!mJRnD
zab-c(1w^ama=`9e-!dUt>%n=Diwzw}<RT}WS*djo!0MprWbZIn+P7#iA`u*v#~Za=
zIu5B`&Ie=j6r!@~{V3t&`oNntDz5Y{NT*m>rG4p~A0dkvYbboFyNiYgoZDXC-g=$d
z#7~~eZ#$AIG6D2(84~%l2Ky>k4T({y<}Nuq04tQj6Qa*O)C?41rc@XUY~kUX7_pK%
zWu~?6a`0);Hn3<}W7bE{M9@s+hLBu|p*hq?^rf{+Of(m@hI_TL?;7w4O&D}$-mSY;
z7m^ls*(0{Zd6Fd$BxjY`omq7}=TxwYUyfAfGauTt6u137=U=8?tz&L$VR5@ROAP#E
zo<ml%Rt=Z<;aS&e25-;WLI<*nxZ)7*l~XA|0Vtpm2D?j|d}jexxBIk!?U`H0XcJd-
zUEKTcE4Y|dCFFqNW(Zr2h@sI8kvwiBp6RV_JQwQ~S?LNvS9cA&Weuk6C#!0cm1f$a
zr73HIU({XHU}K^obGbo^>rCu-C{3WhGN}*E-|ZKK_(ZnJ8R0GyobH3XT(nXjj1ltt
z=CvpC74xoH#IHpy5t|e!USRYJgnDkhj%?^s2o=|2O?}g6tz)RzFDKIXl*v^>0n-}~
z&#C4V#s))zf-{7%Q#aLVlYtATbb-3~d6*q!IyGeP-PNyOWu|uqSGRc=3Zj78vK2gO
zFJ<d0P9?e`%uv0uj%ef2<~o7=D*LY11y#@qJz?>?i(B`2PUkAbEaMnr3}2$Izarr5
zl|kU#jhDwo9B074obZX9hFL`sPx?O++DO_?ded9e6%_wZJ-V#Gd(L`Q1Zff~!eY7q
zo(9b`YA$T%spbyR^H=nmjmvoD&sH+3vrst5W;~CIq#ptj@OBoa35ETFf*M+eFm+qP
zFOu4DPo0C12kA5_eB?4@T&_C(5Ie>6zS(;1>~48b%0_TtqryYGyVgSXCy3&@4CKDC
z*OSzJTU{UZR~uI5m-A?SYGLqH#axzGmH(vd86^)bJHMeMLNqId+)i>1EEeM6-ptqE
zE!w}ZB}2-yU8>kL9i&`|WlM}$O$mM8p3qssJMdthUuER{4rfFD02eS4_U@*>S%nw4
zr#U_WmnkSD!Vbw{RX;Z46B!@1)DKs(kB@5Qd9RfaG5_F^ld4+Y99E7KN{Q4c?(J>(
z*xZkai#_6$wy0IUWw0x-<aOJ6CN`>q4whYVU|BOXklZ4m%+9nXy~M(n_HLwHPkE(s
zOCJw`O9mh-L^F_iJP<C{q4rHCx{qN`{&S~Ve^UEvEBv1omH&5{qW_6@?A(g)^1wy%
zR0PE9yD4E?`&<3pH!nT@@Yht#c3+*0VR*ON=MiitZ+3KA$+4s8obZ;yi2pn+T;0E)
zt>lz=skZrxVkT?!L<XEi`HSujo*}h7DeOle=r_P`uzBo^HC^6~q4&h{-FMiA=2!dn
z3haIboOGXi@@GW_vn}hobjDjf1K9B0WG$b_;J>20{LRa{AA55~KR!z|qF<ftqH^9|
zxF$~o{d|_o@kVyU?<yjXhJ|F!&p9sC2Q)({e!uV`DOi29SMf(6f<EIM+6Tg^Cd?ae
zw?1bXl=>33?6ke`NSk;GKvuK<>z@@A#1{_9t&@#huPASSH)-`hpc&clTi?7i`or`y
zMdDW{=l!a_xLgE{(fwR=f9!TR=yykM9SsY%TR-n-Lhk1VE07MpB^5b;1fs>`N5;?e
zX6RCiXPax)Ll<eDv9o|<6YiJ(tf2g*Q=flUQ2yH6+<#L0KR8vHc6wArbIWBoqtgG4
zy{(i^$c$jO4#XewLN}H+1W~A`R#8maPTha%Os;+Vp}pT$ioG1RDyx=uEUzo1rtNj$
za%jPEsX+*ZnHzf;ke(nCm&;vyYv>Sgl2EF{?%i?2WV7d~%Gpij^0rVZdEZINH=pio
zS9Q~D6ixac0&J5SHMzBSZYImCURzo8a|%A#XE}IZ7oav^BQnzov}#1idzZAaiYuV*
zw9t#jLbZ52=m*c{m_}7&g+~pL40nqxLQe(-1_nlliKj3-E(TSoC1us@-51OV8(z_J
zTu-`N^h=Fy<jvf2gLek?GzY^HUUja|KTfVX$MMqeZwCkvt}VkXc&6(wrEqmviwM>X
zUssU#!djuZ!;u${QCkhWG{x9GO(;#|N<Z5y-;U&<axE`xA5!WCfz!IXHwZD_{1am4
zroibgrn1C)T;zG2O^N5%?=qx%EZ?85AAR?WSZ~E6maoA(VHx03Igbu9OmNbRagL=~
zm;1aR6G^cK<4RD-5NsgeR7#{Ds_`wqQsD&pFlBAp1!nJ6S#-PDqnhZ&m2|8N2nxDZ
zS2^zW_i7kg3*IX;iQ?x%vY+JdP0b?wOl{GAOOn^tL3v=<NcIL%QBw`ZR+lvp%^|-w
z_23Laf*Fn~0mh3Kh*p3y&`Xz_l!aJ>nI$0n%#^lz!YIB|gy}G@L%=DyTiMPFjY%5%
z<>8rg)1f*3&H>k8n{EtEKata1tn>VJ5rr3EbKuWifzgOTc+JO$bV>#9i?L2lOCiM<
znvRjiT(t*H+BIJV@x_(iVA{rXZ{qp`J{BBr4hacor3!cgdfNXYn>4GGQ69{w%m}?O
zyT0#Hjf^Re@eaMJ(ho1!x`1?@jW0LxECnY}f4pGuN$X1I-pg&@I~NZDLWcnN@U&s&
zn|OcGNJ$%pvg`PQCRRt{MvWP!-cPRPS@$8pO6+6q{pioBtEW~dp4TNZjr1t9L~Pa0
z{m~1Kf5>i?$TM|fuc*Nup%e%7wCnXk`{`^?Zf?GA6XA1^8`{A^zoBW9FVZJ&ynRgI
zET*bUyzmwu+Wuf-9dU%R9C>^1*!_M})`60$GX@h%iQiD4$EO3_jp7gb!W#H@?MxG5
z#5k58cAPsx?@V9+z`G$mO85H2q-uz>M(f<wJMN$(lxB~IZT^wv7uhR-=Zhs_HoD^h
zMIXSb-%y$F>=bV^dWs7CP5LiK8cK5Nk#yAoLq@)!%&z%|_K<qJA>6^NqP60tVPtvO
zsG#%iw2JQC!_0c=){T~4*eUb$;}^bHBpKd%%_A*&|4X-ne=RC)-evl$Jm_b#S-yh3
zs1j<}GanN)`&pIIGdD$IxalKvk;ryUO(T2<6nE3y7D+Vsr^tGX3kH%D9<7Be`Cm6~
zh=v3_Ab&+ZhDatl8AO!BVCY1Z=|L<on3&{(HGR^%oa2Dx7haH%s5jA)%FW|cZq-}A
zYuv40babzVqr21NyJ8eR@OTgM#a@T7U?A7bMp~QXT5I|b0l|4aO{|aLoXeKIxx;)5
z{T6v==Q^#rlR`4|a@bEWI5~2D3JIy<WT}pq>%<)bsy%1}?e$yRE@t|Rk2M9CY96GX
z*JJznhA677+;W~T;p6nM6%w0WLfEvN`DI`Nsype{KoS+bBR0l+b$bt43+c49&B<WK
zmuLibB~uCrGP%>nFL2R70*+y~#A9vgqKDN+aW~_>n8UNf99}mkhH($8ow;!a>Kqk$
zGla<UO`p9bI{kWkI&K8_h2drq_6QubM;vCMyLgpr4>EdrgKoZF=RrEiLjp?&G&`v=
zmTN!jN`XSccu=7*q2_R+yjR4C*zlV}07pKq45>_hy*XC)k*)h1tzuVHsD*!uH+RyE
zEp@3$s)=)g<lY}H*Vz71{L;z$Z>&s&N1X7|f<6psO%`=tcMU99!G6Y=Lx5Jqe9?<H
z<jA|e&&xZNtX7iGqb2xw^{w5p$-ZBwpUhEa2*h-Js_mW#twj#|RoO%+S#N?qt}{U|
z9f1O&nb<FEZ-$f#@i_|dDYbvx373gjE3eqY9C*iENON>DnN8bug`Y6i0pT;El3>QE
zrkHJywpLyh1>XULM6kW6YF3YY7`d+Xr`BYKafaKPoXxq)L8~H}Hc~M|BUN!`h^!PR
zRj8tuV~%eyHN_X(JD<<(ll|6{ujjs#f>y{FSVPkqeRgZa;0pdl_L}*G1;-rKm>t>Y
zMEiU<Vw)QhsW<I~M_4Ez<THJaEu}kXW~)8A+ZEBBV`$ziN$L;gwTeOt&nW04Z8#w&
z3W^P4i3X3`Qx{l%>$zen#O6$v24nlFFV4>pMV<HgWWedo1KHU&=1FCVDI?W6G%R{E
z3L)J>l1W02O|vArRU)WWH2sDRHYz9C-2pNb<-igURE8rktE*FlD63)n?ClQ$pvP(7
z9-OAu)<N@yg)o@|{f$qXaW1;o7lkV~Uk5e%)5V3%n^>;J4N2H(hVkgxxMb@Dc`wn_
z_=(!e6^JlRp^#Z!`GO7Yd*X{M`$hG0>YFsb^|XfPl138Kio~^OWFTHHNsanvfuFAh
z^{8HkTKA$lhPp{>MEg8_bk^6e?=!%*CxHZ-7TRQnNV-<0h}mV=`I?QFFldD#dd5cT
zRPY4fslZ|o)0f``g;tz7<|61)fsWNA4?X!IU{^|!q%3&gd=dQ#2acfxT?XtkFM`mB
z(JMSIbl0!TDV|IG6+lsz`|r%ZslObZBXNe2swnwUhS>~tm}Vst?;$`h1d*qNhVcmJ
zh64qqs6*UF#|{vO0Ga9w>2vEQyo(F4eMx+VZHBI8m}kHh4Z_04YINU4&vj$9%JrMd
z7%l^iAv{yo$A<b)`Njq}cFy-Mrxp@c0;8=z_U%SgQ5Vlpo`HdpoI=70I1405s$Wf<
zW@2b^ookokx1Ks0OjZ7wnN6p3)FV#d@eRxU2R&TMgjLd;YnaEGyIc+nA)D{sPA8T-
z8kbLJik%5(bqRU?Adx*-*&(61E!8;lYJr0Wbzcfei6oC<Y{TqXh_d`H*qqUdFynPW
zfA4Z?!>qK_L%_{iXqab(N?cHeA#PVKYeT&<t4N$k>;U_yfz1yA$JkFdhc~7fca%+a
zM9t+aYm3w^he(#M7SSb)pc8HSLa3-68;Uu1N=TBSzZ)}5JW7mmj|}g@73j2i>0Fvl
ze!lne;m}&b5=2l$KqDCzt{e#`-QAhg5E?SWAsHyaS%JSbOJTD+l4fS+nNJ>m3;S*q
zUit;@@-b>dM`Wj)qusdW37z6a?s1Q3YIx1L#01Q}y?)8=A1ViI4~2ccfgBVqTX0h?
zpiiZE5J*B8u~S$;U)h>QYN@%sq;xnR(Po5Ve05sg;4$uJ@gu8Z*ZTdre_ByR&}eW}
zBp-E12`5L_kN>S0Jbsczy957BVqVhUOjaZO9Ct4r*DiNR@LutSE2OdHG3~XY4e}>s
zas_CyYbf}ovU{?p+<D@=BrbkXcDQeUqqU-&X3@TPHUHDlXYXH+F~Vt)$p@uZH#ql?
zP_J5e)tho7=E+}_0AHV0svlCUGkg3U6vJ0sAr{OUyrl#jpHJ^#+-=|K4&ONfDK?4k
z?hSg_dNf`F7!o8vUxzmPXY9cd+At9_{(kgX=$$w)fGQ>cY_!ZdDJcCNWcfkhm{Z?e
z@V?o@w~AkmK(Yr0&d+V?MCxuw0QmJ;v5yPGJ=zZe-_biq1c87PU2?d~Ti6frf5;k8
zW#uIQH|f7g|HqK_S!RUjbn)ZHozgj^+h;qzI&PzM2pG738~T+b$H*9HpjJp=vDmmj
zJ%jbaYMb#1@9W+THPTFbrk4N?C|$Z6=hdJyn4Z!<n6{xYURZb}aYpbC%Iij^_E@r7
z*f^s$UG`9aqJcFCZ7Hsx8*6nhrK5{i$IwGBTpw@=yOLB|Zr;`sx0U|gN&}oMb?O|9
zy~toX6!6`80$~6Cz8@9<@Q{nINbl~N#Z{{x7U0<5m;L*)f5FQhC$1E9H8DoFsrua^
hC7X!AXf64jsIInDtHw_$>0#+Cu#QgvQ8I@k{{>;MQJnw)
diff --git a/thys/SC_DOM_Components/document/root.bib b/thys/SC_DOM_Components/document/root.bib
new file mode 100644
--- /dev/null
+++ b/thys/SC_DOM_Components/document/root.bib
@@ -0,0 +1,747 @@
+@STRING{j-fac = "Formal Aspects of Computing" }
+@STRING{pub-springer={Springer-Verlag} }
+@STRING{pub-springer:adr={Heidelberg} }
+@STRING{s-lncs = "Lecture Notes in Computer Science" }
+
+@Book{ nipkow.ea:isabelle:2002,
+ author = {Tobias Nipkow and Lawrence C. Paulson and Markus Wenzel},
+ title = {Isabelle/HOL---A Proof Assistant for Higher-Order Logic},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2283,
+ doi = {10.1007/3-540-45949-9},
+ abstract = {This book is a self-contained introduction to interactive
+ proof in higher-order logic (HOL), using the proof
+ assistant Isabelle2002. It is a tutorial for potential
+ users rather than a monograph for researchers. The book has
+ three parts.
+
+ 1. Elementary Techniques shows how to model functional
+ programs in higher-order logic. Early examples involve
+ lists and the natural numbers. Most proofs are two steps
+ long, consisting of induction on a chosen variable followed
+ by the auto tactic. But even this elementary part covers
+ such advanced topics as nested and mutual recursion. 2.
+ Logic and Sets presents a collection of lower-level tactics
+ that you can use to apply rules selectively. It also
+ describes Isabelle/HOL's treatment of sets, functions and
+ relations and explains how to define sets inductively. One
+ of the examples concerns the theory of model checking, and
+ another is drawn from a classic textbook on formal
+ languages. 3. Advanced Material describes a variety of
+ other topics. Among these are the real numbers, records and
+ overloading. Advanced techniques are described involving
+ induction and recursion. A whole chapter is devoted to an
+ extended example: the verification of a security protocol.
+ },
+ year = 2002,
+ acknowledgement={brucker, 2007-02-19},
+ bibkey = {nipkow.ea:isabelle:2002}
+}
+
+@Misc{ dom-specification,
+ year = 2016,
+ month = {DOM Living Standard -- Last Updated 20 October 2016},
+ day = 20,
+ url = {https://dom.spec.whatwg.org/},
+ organization = {Web Hypertext Application Technology Working Group
+ (WHATWG)},
+ note = {An archived copy of the version from 20 October 2016 is
+ available at
+ \url{https://git.logicalhacking.com/BrowserSecurity/fDOM-idl/}.}
+}
+
+@InProceedings{ brucker.ea:core-dom:2018,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {A Formal Semantics of the Core {DOM} in {Isabelle/HOL}},
+ booktitle = {Proceedings of the Web Programming, Design, Analysis, And
+ Implementation (WPDAI) track at WWW 2018},
+ location = {Lyon, France},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-fdom-2018},
+ year = {2018},
+ abstract = {At its core, the Document Object Model (DOM) defines a
+ tree-like data structure for representing documents in
+ general and HTML documents in particular. It forms the
+ heart of any rendering engine of modern web browsers.
+ Formalizing the key concepts of the DOM is a pre-requisite
+ for the formal reasoning over client-side JavaScript
+ programs as well as for the analysis of security concepts
+ in modern web browsers. In this paper, 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. },
+ keywords = {Document Object Model, DOM, Formal Semantics,
+ Isabelle/HOL},
+ classification= {conference},
+ areas = {formal methods, software},
+ public = {yes}
+}
+@Article{ klein:operating:2009,
+ author = {Gerwin Klein},
+ title = {Operating System Verification --- An Overview},
+ journal = {S\={a}dhan\={a}},
+ publisher = pub-springer,
+ year = 2009,
+ volume = 34,
+ number = 1,
+ month = feb,
+ pages = {27--69},
+ abstract = {This paper gives a high-level introduction to the topic of
+ formal, interactive, machine-checked software verification
+ in general, and the verification of operating systems code
+ in particular. We survey the state of the art, the
+ advantages and limitations of machine-checked code proofs,
+ and describe two specific ongoing larger-scale verification
+ projects in more detail.}
+}
+
+
+@InProceedings{ gardner.ea:securing:2009,
+ author = {Ryan W. Gardner and Sujata Garera and Matthew W. Pagano
+ and Matthew Green and Aviel D. Rubin},
+ title = {Securing medical records on smart phones},
+ booktitle = {ACM workshop on Security and privacy in medical and
+ home-care systems (SPIMACS)},
+ year = 2009,
+ isbn = {978-1-60558-790-5},
+ pages = {31--40},
+ location = {Chicago, Illinois, USA},
+ doi = {10.1145/1655084.1655090},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ abstract = {There is an inherent conflict between the desire to
+ maintain privacy of one's medical records and the need to
+ make those records available during an emergency. To
+ satisfy both objectives, we introduce a flexible
+ architecture for the secure storage of medical records on
+ smart phones. In our system, a person can view her records
+ at any time, and emergency medical personnel can view the
+ records as long as the person is present (even if she is
+ unconscious). Our solution allows for efficient revocation
+ of access rights and is robust against adversaries who can
+ access the phone's storage offline.}
+}
+
+@InProceedings{ raad.ea:dom:2016,
+ author = {Azalea Raad and Jos{\'{e}} Fragoso Santos and Philippa
+ Gardner},
+ title = {{DOM:} Specification and Client Reasoning},
+ booktitle = {Programming Languages and Systems - 14th Asian Symposium,
+ {APLAS} 2016, Hanoi, Vietnam, November 21-23, 2016,
+ Proceedings},
+ pages = {401--422},
+ year = 2016,
+ crossref = {igarashi:programming:2016},
+ doi = {10.1007/978-3-319-47958-3_21},
+ abstract = {We present an axiomatic specification of a key fragment of
+ DOM using structural separation logic. This specification
+ allows us to develop modular reasoning about client
+ programs that call the DOM.}
+}
+
+
+@InProceedings{ bohannon.ea:featherweight:2010,
+ author = {Aaron Bohannon and Benjamin C. Pierce},
+ title = {Featherweight {F}irefox: {F}ormalizing the Core of a Web
+ Browser},
+ booktitle = {Usenix Conference on Web Application Development
+ (WebApps)},
+ year = 2010,
+ month = jun,
+ url = {http://www.cis.upenn.edu/~bohannon/browser-model/},
+ abstract = {We offer a formal specification of the core functionality
+ of a web browser in the form of a small-step operational
+ semantics. The specification accurately models the asyn-
+ chronous nature of web browsers and covers the basic as-
+ pects of windows, DOM trees, cookies, HTTP requests and
+ responses, user input, and a minimal scripting lan- guage
+ with first-class functions, dynamic evaluation, and AJAX
+ requests. No security enforcement mechanisms are
+ included{\^a}instead, the model is intended to serve as a
+ basis for formalizing and experimenting with different
+ security policies and mechanisms. We survey the most
+ interesting design choices and discuss how our model re-
+ lates to real web browsers.}
+}
+
+@Proceedings{ joyce.ea:higher:1994,
+ editor = {Jeffrey J. Joyce and Carl-Johan H. Seger},
+ title = {Higher Order Logic Theorem Proving and Its Applications
+ (HUG)},
+ booktitle = {Higher Order Logic Theorem Proving and Its Applications
+ (HUG)},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ abstract = {Theorem proving based techniques for formal hardware
+ verification have been evolving constantly and researchers
+ are getting able to reason about more complex issues than
+ it was possible or practically feasible in the past. It is
+ often the case that a model of a system is built in a
+ formal logic and then reasoning about this model is carried
+ out in the logic. Concern is growing on how to consistently
+ interface a model built in a formal logic with an informal
+ CAD environment. Researchers have been investigating how to
+ define the formal semantics of hardware description
+ languages so that one can formally reason about models
+ informally dealt with in a CAD environment. At the
+ University of Cambridge, the embedding of hardware
+ description languages in a logic is classified in two
+ categories: deep embedding and shallow embedding. In this
+ paper we argue that there are degrees of formality in
+ shallow embedding a language in a logic. The choice of the
+ degree of formality is a trade-off between the security of
+ the embedding and the amount and complexity of the proof
+ effort in the logic. We also argue that the design of a
+ language could consider this verifiability issue. There are
+ choices in the design of a language that can make it easier
+ to improve the degree of formality, without implying
+ serious drawbacks for the CAD environment.},
+ volume = 780,
+ year = 1994,
+ doi = {10.1007/3-540-57826-9},
+ isbn = {3-540-57826-9},
+ acknowledgement={brucker, 2007-02-19}
+}
+
+
+@Misc{ whatwg:dom:2017,
+ key={whatwg},
+ author={{WHATWG}},
+ url={https://dom.spec.whatwg.org/commit-snapshots/6253e53af2fbfaa6d25ad09fd54280d8083b2a97/},
+ month=mar,
+ year=2017,
+ day=24,
+ title={{DOM} -- Living Standard},
+ note={Last Updated 24 {March} 2017},
+ institution = {WHATWG},
+}
+
+@Misc{ whatwg:html:2017,
+ key={whatwg},
+ author={{WHATWG}},
+ url={https://html.spec.whatwg.org/},
+ month=apr,
+ year=2017,
+ day=13,
+ title={{HTML} -- Living Standard},
+ note={Last Updated 13 {April} 2017},
+ institution = {WHATWG},
+}
+
+
+@Misc{ w3c:dom:2015,
+ key={w3c},
+ author={{W3C}},
+ url={https://www.w3.org/TR/dom/},
+ month=nov,
+ year=2015,
+ day=19,
+ title={{W3C} {DOM4}},
+ institution = {W3C},
+}
+
+
+@Proceedings{ igarashi:programming:2016,
+ editor = {Atsushi Igarashi},
+ title = {Programming Languages and Systems - 14th Asian Symposium,
+ {APLAS} 2016, Hanoi, Vietnam, November 21-23, 2016,
+ Proceedings},
+ series = {Lecture Notes in Computer Science},
+ volume = 10017,
+ year = 2016,
+ doi = {10.1007/978-3-319-47958-3},
+ isbn = {978-3-319-47957-6}
+}
+
+
+
+
+
+
+@InProceedings{ gardner.ea:dom:2008,
+ author = {Philippa Gardner and Gareth Smith and Mark J. Wheelhouse
+ and Uri Zarfaty},
+ title = {{DOM:} Towards a Formal Specification},
+ booktitle = {{PLAN-X} 2008, Programming Language Technologies for XML,
+ An {ACM} {SIGPLAN} Workshop colocated with {POPL} 2008, San
+ Francisco, California, USA, January 9, 2008},
+ year = 2008,
+ crossref = {plan-x:2008},
+ url = {http://gemo.futurs.inria.fr/events/PLANX2008/papers/p18.pdf},
+ abstract = {The W3C Document Object Model (DOM) specifies an XML up-
+ date library. DOM is written in English, and is therefore
+ not compo- sitional and not complete. We provide a first
+ step towards a compo- sitional specification of DOM. Unlike
+ DOM, we are able to work with a minimal set of commands and
+ obtain a complete reason- ing for straight-line code. Our
+ work transfers O{\^a}Hearn, Reynolds and Yang{\^a}s
+ local Hoare reasoning for analysing heaps to XML, viewing
+ XML as an in-place memory store as does DOM. In par-
+ ticular, we apply recent work by Calcagno, Gardner and
+ Zarfaty on local Hoare reasoning about a simple tree-update
+ language to DOM, showing that our reasoning scales to DOM.
+ Our reasoning not only formally specifies a significant
+ subset of DOM Core Level 1, but can also be used to verify
+ e.g. invariant properties of simple Javascript programs.}
+}
+
+
+
+@InProceedings{ jang.ea:establishing:2012,
+ author = {Dongseok Jang and Zachary Tatlock and Sorin Lerner},
+ title = {Establishing Browser Security Guarantees through Formal
+ Shim Verification},
+ booktitle = {Proceedings of the 21th {USENIX} Security Symposium,
+ Bellevue, WA, USA, August 8-10, 2012},
+ pages = {113--128},
+ year = 2012,
+ crossref = {kohno:proceedings:2012},
+ url = {https://www.usenix.org/conference/usenixsecurity12/technical-sessions/presentation/jang},
+ abstract = { Web browsers mediate access to valuable private data in
+ domains ranging from health care to banking. Despite this
+ critical role, attackers routinely exploit browser
+ vulnerabilities to exfiltrate private data and take over
+ the un- derlying system. We present Q UARK , a browser
+ whose kernel has been implemented and verified in Coq. We
+ give a specification of our kernel, show that the
+ implementation satisfies the specification, and finally
+ show that the specification implies several security
+ properties, including tab non-interference, cookie
+ integrity and confidentiality, and address bar integrity.
+ }
+}
+
+@Proceedings{ kohno:proceedings:2012,
+ editor = {Tadayoshi Kohno},
+ title = {Proceedings of the 21th {USENIX} Security Symposium,
+ Bellevue, WA, USA, August 8-10, 2012},
+ publisher = {{USENIX} Association},
+ year = 2012,
+ timestamp = {Thu, 15 May 2014 09:12:27 +0200}
+}
+
+
+
+@Proceedings{ plan-x:2008,
+ title = {{PLAN-X} 2008, Programming Language Technologies for XML,
+ An {ACM} {SIGPLAN} Workshop colocated with {POPL} 2008, San
+ Francisco, California, USA, January 9, 2008},
+ year = 2008,
+ timestamp = {Fri, 18 Jan 2008 13:01:04 +0100}
+}
+
+
+@Article{ brucker.ea:extensible:2008-b,
+ abstract = {We present an extensible encoding of object-oriented data models into HOL. Our encoding is supported by a datatype package that leverages the use of the shallow embedding technique to object-oriented specification and programming languages. The package incrementally compiles an object-oriented data model, i.e., a class model, to a theory containing object-universes, constructors, accessor functions, coercions (casts) between dynamic and static types, characteristic sets, and co-inductive class invariants. The package is conservative, i.e., all properties are derived entirely from constant definitions, including the constraints over object structures. As an application, we use the package for an object-oriented core-language called IMP++, for which we formally prove the correctness of a Hoare-Logic with respect to a denotational semantics.},
+ address = {Heidelberg},
+ author = {Achim D. Brucker and Burkhart Wolff},
+ doi = {10.1007/s10817-008-9108-3},
+ issn = {0168-7433},
+ issue = {3},
+ journal = {Journal of Automated Reasoning},
+ keywords = {object-oriented data models, HOL, theorem proving, verification},
+ language = {USenglish},
+ pages = {219--249},
+ pdf = {https://www.brucker.ch/bibliography/download/2008/brucker.ea-extensible-2008-b.pdf},
+ publisher = {Springer-Verlag},
+ title = {An Extensible Encoding of Object-oriented Data Models in HOL},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-extensible-2008-b},
+ volume = {41},
+ year = {2008},
+}
+
+@PhDThesis{ brucker:interactive:2007,
+ abstract = {We present a semantic framework for object-oriented specification languages. We develop this framework as a conservative shallow embedding in Isabelle/HOL. Using only conservative extensions guarantees by construction the consistency of our formalization. Moreover, we show how our framework can be used to build an interactive proof environment, called HOL-OCL, for object-oriented specifications in general and for UML/OCL in particular.\\\\Our main contributions are an extensible encoding of object-oriented data structures in HOL, a datatype package for object-oriented specifications, and the development of several equational and tableaux calculi for object-oriented specifications. Further, we show that our formal framework can be the basis of a formal machine-checked semantics for OCL that is compliant to the OCL 2.0 standard.},
+ abstract_de = {In dieser Arbeit wird ein semantisches Rahmenwerk f{\"u}r objektorientierte Spezifikationen vorgestellt. Das Rahmenwerk ist als konservative, flache Einbettung in Isabelle/HOL realisiert. Durch die Beschr{\"a}nkung auf konservative Erweiterungen kann die logische Konsistenz der Einbettung garantiert werden. Das semantische Rahmenwerk wird verwendet, um das interaktives Beweissystem HOL-OCL f{\"u}r objektorientierte Spezifikationen im Allgemeinen und insbesondere f{\"u}r UML/OCL zu entwickeln.\\\\Die Hauptbeitr{\"a}ge dieser Arbeit sind die Entwicklung einer erweiterbaren Kodierung objektorientierter Datenstrukturen in HOL, ein Datentyp-Paket f{\"u}r objektorientierte Spezifikationen und die Entwicklung verschiedener Kalk{\"u}le f{\"u}r objektorientierte Spezifikationen. Zudem zeigen wir, wie das formale Rahmenwerk verwendet werden kann, um eine formale, maschinell gepr{\"u}fte Semantik f{\"u}r OCL anzugeben, die konform zum Standard f{\"u}r OCL 2.0 ist.},
+ author = {Achim D. Brucker},
+ keywords = {OCL, UML, formal semantics, theorem proving, Isabelle, HOL-OCL},
+ month = {mar},
+ note = {ETH Dissertation No. 17097.},
+ pdf = {https://www.brucker.ch/bibliography/download/2007/brucker-interactive-2007.pdf},
+ school = {ETH Zurich},
+ title = {An Interactive Proof Environment for Object-oriented Specifications},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker-interactive-2007},
+ year = {2007},
+}
+
+@InCollection{ brucker.ea:standard-compliance-testing:2018,
+ talk = {talk:brucker.ea:standard-compliance-testing:2018},
+ abstract = {Most popular technologies are based on informal or
+ semiformal standards that lack a rigid formal semantics.
+ Typical examples include web technologies such as the DOM
+ or HTML, which are defined by the Web Hypertext Application
+ Technology Working Group (WHATWG) and the World Wide Web
+ Consortium (W3C). While there might be API specifications
+ and test cases meant to assert the compliance of a certain
+ implementation, the actual standard is rarely accompanied
+ by a formal model that would lend itself for, e.g.,
+ verifying the security or safety properties of real
+ systems.
+
+ Even when such a formalization of a standard exists, two
+ important questions arise: first, to what extend does the
+ formal model comply to the standard and, second, to what
+ extend does the implementation comply to the formal model
+ and the assumptions made during the verification? In this
+ paper, we present an approach that brings all three
+ involved artifacts - the (semi-)formal standard, the
+ formalization of the standard, and the implementations -
+ closer together by combining verification, symbolic
+ execution, and specification based testing.},
+ keywords = {standard compliance, compliance tests, DOM},
+ location = {Toulouse, France},
+ author = {Achim D. Brucker and Michael Herzberg},
+ booktitle = {{TAP} 2018: Tests And Proofs},
+ language = {USenglish},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ number = 10889,
+ editor = {Cathrine Dubois and Burkhart Wolff},
+ title = {Formalizing (Web) Standards: An Application of Test and
+ Proof},
+ categories = {holtestgen, websecurity},
+ classification= {conference},
+ areas = {formal methods, software engineering},
+ public = {yes},
+ year = 2018,
+ doi = {10.1007/978-3-319-92994-1_9},
+ pages = {159--166},
+ isbn = {978-3-642-38915-3},
+ pdf = {http://www.brucker.ch/bibliography/download/2018/brucker.ea-standard-compliance-testing-2018.pdf},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-standard-compliance-testing-2018}
+}
+
+
+@InCollection{ brucker.ea:interactive:2005,
+ keywords = {symbolic test case generations, black box testing, white
+ box testing, theorem proving, interactive testing},
+ abstract = {HOL-TestGen is a test environment for specification-based
+ unit testing build upon the proof assistant Isabelle/HOL\@.
+ While there is considerable skepticism with regard to
+ interactive theorem provers in testing communities, we
+ argue that they are a natural choice for (automated)
+ symbolic computations underlying systematic tests. This
+ holds in particular for the development on non-trivial
+ formal test plans of complex software, where some parts of
+ the overall activity require inherently guidance by a test
+ engineer. In this paper, we present the underlying methods
+ for both black box and white box testing in interactive
+ unit test scenarios. HOL-TestGen can also be understood as
+ a unifying technical and conceptual framework for
+ presenting and investigating the variety of unit test
+ techniques in a logically consistent way. },
+ location = {Edinburgh},
+ author = {Achim D. Brucker and Burkhart Wolff},
+ booktitle = {Formal Approaches to Testing of Software},
+ language = {USenglish},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ number = 3997,
+ doi = {10.1007/11759744_7},
+ isbn = {3-540-25109-X},
+ editor = {Wolfgang Grieskamp and Carsten Weise},
+ pdf = {http://www.brucker.ch/bibliography/download/2005/brucker.ea-interactive-2005.pdf},
+ project = {CSFMDOS},
+ title = {Interactive Testing using {HOL}-{TestGen}},
+ classification= {workshop},
+ areas = {formal methods, software},
+ categories = {holtestgen},
+ year = 2005,
+ public = {yes},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-interactive-2005}
+}
+
+
+@Article{ brucker.ea:theorem-prover:2012,
+ author = {Achim D. Brucker and Burkhart Wolff},
+ journal = j-fac,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ language = {USenglish},
+ categories = {holtestgen},
+ title = {On Theorem Prover-based Testing},
+ year = 2013,
+ issn = {0934-5043},
+ pages = {683--721},
+ volume = 25,
+ number = 5,
+ classification= {journal},
+ areas = {formal methods, software},
+ public = {yes},
+ doi = {10.1007/s00165-012-0222-y},
+ keywords = {test case generation, domain partitioning, test sequence,
+ theorem proving, HOL-TestGen},
+ abstract = {HOL-TestGen is a specification and test case generation
+ environment extending the interactive theorem prover
+ Isabelle/HOL. As such, HOL-TestGen allows for an integrated
+ workflow supporting interactive theorem proving, test case
+ generation, and test data generation.
+
+ The HOL-TestGen method is two-staged: first, the original
+ formula is partitioned into test cases by transformation
+ into a normal form called test theorem. Second, the test
+ cases are analyzed for ground instances (the test data)
+ satisfying the constraints of the test cases. Particular
+ emphasis is put on the control of explicit test-hypotheses
+ which can be proven over concrete programs.
+
+ Due to the generality of the underlying framework, our
+ system can be used for black-box unit, sequence, reactive
+ sequence and white-box test scenarios. Although based on
+ particularly clean theoretical foundations, the system can
+ be applied for substantial case-studies. },
+ pdf = {http://www.brucker.ch/bibliography/download/2012/brucker.ea-theorem-prover-2012.pdf},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-theorem-prover-2012}
+}
+
+
+@Article{ brucker.ea:afp-core-dom:2018,
+ 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.},
+ author = {Achim D. Brucker and Michael Herzberg},
+ date = {2018-12-26},
+ file = {https://www.brucker.ch/bibliography/download/2018/brucker.ea-afp-core-dom-outline-2018.pdf},
+ filelabel = {Outline},
+ issn = {2150-914x},
+ journal = {Archive of Formal Proofs},
+ month = {dec},
+ note = {\url{http://www.isa-afp.org/entries/Core_DOM.html}, Formal proof development},
+ pdf = {https://www.brucker.ch/bibliography/download/2018/brucker.ea-afp-core-dom-2018.pdf},
+ title = {The Core {DOM}},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-afp-core-dom-2018-a},
+ year = {2018},
+}
+
+@Misc{ whatwg:dom:2019,
+ key = {whatwg},
+ author = {{WHATWG}},
+ url = {https://dom.spec.whatwg.org/commit-snapshots/7fa83673430f767d329406d0aed901f296332216/},
+ month = feb,
+ year = 2019,
+ day = 11,
+ title = {{DOM} -- Living Standard},
+ note = {Last Updated 11 {February} 2019},
+ institution = {WHATWG}
+}
+
+@Misc{ bidelman:self-contained:2017,
+ author = {Eric Bidelman},
+ title = {Shadow DOM v1: Self-Contained Web Components},
+ month = may,
+ day = 12,
+ year = 2017,
+ url = {https://developers.google.com/web/fundamentals/getting-started/primers/shadowdom}
+}
+
+
+
+@Article{ brucker.ea:afp-shadow-sc-dom:2020,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {Shadow SC DOM: A Formal Model of the Safelty Composable Document Object Model with Shadow Roots},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ date = {2020-09-28},
+ note = {\url{http://www.isa-afp.org/entries/Shadow_SC_DOM.html}, Formal proof development},
+ issn = {2150-914x},
+ abstract = { In this AFP entry, we extend our formalization of the safely composable DOM with \emph{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. },
+ public = {yes},
+ classification= {formal},
+ categories = {websecurity},
+ pdf = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-shadow-sc-dom-2020.pdf},
+ filelabel = {Outline},
+ file = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-shadow-sc-dom-outline-2020.pdf},
+ areas = {formal methods, security, software engineering},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-afp-shadow-sc-dom-2020}
+}
+
+@Article{ brucker.ea:afp-dom-components:2020,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {A Formalization of Web Components},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ date = {2020-09-28},
+ note = {\url{http://www.isa-afp.org/entries/DOM_Components.html}, Formal proof development},
+ issn = {2150-914x},
+ public = {yes},
+ classification= {formal},
+ categories = {websecurity},
+ pdf = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-dom-components-2020.pdf},
+ filelabel = {Outline},
+ file = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-dom-components-outline-2020.pdf},
+ areas = {formal methods, security, software engineering},
+ 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. },
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-afp-dom-components-2020}
+}
+
+@Article{ brucker.ea:afp-sc-dom-components:2020,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {A Formalization of Safely Composable Web Components},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ date = {2020-09-28},
+ note = {\url{http://www.isa-afp.org/entries/SC_DOM_Components.html}, Formal proof development},
+ issn = {2150-914x},
+ public = {yes},
+ classification= {formal},
+ categories = {websecurity},
+ pdf = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-sc-dom-components-2020.pdf},
+ filelabel = {Outline},
+ file = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-sc-dom-components-outline-2020.pdf},
+ areas = {formal methods, security, software engineering},
+ 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.
+ },
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-afp-sc-dom-components-2020}
+}
+
+
+
+@Article{ brucker.ea:afp-core-sc-dom:2020,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {The Safely Composable {DOM}},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ date = {2020-09-28},
+ note = {\url{http://www.isa-afp.org/entries/Core_SC_DOM.html}, Formal proof development},
+ issn = {2150-914x},
+ 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 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. },
+ public = {yes},
+ classification= {formal},
+ categories = {websecurity},
+ pdf = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-core-sc-dom-2020.pdf},
+ filelabel = {Outline},
+ file = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-core-sc-dom-outline-2020.pdf},
+ areas = {formal methods, security, software engineering},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-afp-core-sc-dom-2020}
+}
+
+@Article{ brucker.ea:afp-shadow-dom:2020,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {Shadow DOM: A Formal Model of the Document Object Model with Shadow Roots},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ date = {2020-09-28},
+ note = {\url{http://www.isa-afp.org/entries/Shadow_DOM.html}, Formal proof development},
+ issn = {2150-914x},
+ abstract = { In this AFP entry, we extend our formalization of the core DOM with \emph{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. },
+ public = {yes},
+ classification= {formal},
+ categories = {websecurity},
+ pdf = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-shadow-dom-2020.pdf},
+ filelabel = {Outline},
+ file = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-shadow-dom-outline-2020.pdf},
+ areas = {formal methods, security, software engineering},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-afp-shadow-dom-2020}
+}
+
+
+
+
+@InCollection{ brucker.ea:web-components:2019,
+ abstract = {The trend towards ever more complex client-side web applications is unstoppable. Compared to
+ traditional software development, client-side web development lacks a well-established component
+ model, i.e., a method for easily and safely reusing already developed functionality. To address this
+ issue, the web community started to adopt shadow trees as part of the Document Object Model (DOM):
+ shadow trees allow developers to "partition" a DOM instance into parts that should be safely
+ separated, e.g., code modifying one part should not, unintentionally, affect other parts of the DOM.
+
+ While 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 this paper, 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.},
+ keywords = {Web Component, Shadow Tree, DOM, Isabelle/HOL},
+ location = {Amsterdam, The Netherlands},
+ author = {Achim D. Brucker and Michael Herzberg},
+ booktitle = {Formal Aspects of Component Software (FACS)},
+ language = {USenglish},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ number = 12018,
+ isbn = {3-540-25109-X},
+ doi = {10.1007/978-3-030-40914-2_3},
+ editor = {Sung-Shik Jongmans and Farhad Arbab},
+ pdf = {http://www.brucker.ch/bibliography/download/2019/brucker.ea-web-components-2019.pdf},
+ title = {A Formally Verified Model of Web Components},
+ classification= {conference},
+ areas = {formal methods, software},
+ year = 2020,
+ public = {yes},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-web-components-2019}
+}
+
+
+
+@PhdThesis{herzberg:web-components:2020,
+ author = {Michael Herzberg},
+ title = {Formal Foundations for Provably Safe Web Components},
+ school = {The University of Sheffield},
+ year = {2020}
+}
+
diff --git a/thys/SC_DOM_Components/document/root.tex b/thys/SC_DOM_Components/document/root.tex
new file mode 100644
--- /dev/null
+++ b/thys/SC_DOM_Components/document/root.tex
@@ -0,0 +1,255 @@
+\documentclass[10pt,DIV16,a4paper,abstract=true,twoside=semi,openright]
+{scrreprt}
+\usepackage[USenglish]{babel}
+\usepackage[numbers, sort&compress]{natbib}
+\usepackage{isabelle,isabellesym}
+\usepackage{booktabs}
+\usepackage{paralist}
+\usepackage{graphicx}
+\usepackage{amssymb}
+\usepackage{xspace}
+\usepackage{xcolor}
+\usepackage{listings}
+\lstloadlanguages{HTML}
+\usepackage[]{mathtools}
+\usepackage[pdfpagelabels, pageanchor=false, plainpages=false]{hyperref}
+\lstdefinestyle{html}{language=XML,
+ basicstyle=\ttfamily,
+ commentstyle=\itshape,
+ keywordstyle=\color{blue},
+ ndkeywordstyle=\color{blue},
+}
+\lstdefinestyle{displayhtml}{style=html,
+ floatplacement={tbp},
+ captionpos=b,
+ framexleftmargin=0pt,
+ basicstyle=\ttfamily\scriptsize,
+ backgroundcolor=\color{black!2},
+ frame=lines,
+}
+\lstnewenvironment{html}[1][]{\lstset{style=displayhtml, #1}}{}
+\def\inlinehtml{\lstinline[style=html, columns=fullflexible]}
+ \newsavebox{\fstlst}
+ \newsavebox{\sndlst}
+\usepackage[caption=false]{subfig}
+
+\pagestyle{headings}
+\isabellestyle{default}
+\setcounter{tocdepth}{1}
+\newcommand{\ie}{i.\,e.\xspace}
+\newcommand{\eg}{e.\,g.\xspace}
+\newcommand{\thy}{\isabellecontext}
+\renewcommand{\isamarkupsection}[1]{%
+ \begingroup%
+ \def\isacharunderscore{\textunderscore}%
+ \section{#1 (\thy)}%
+ \endgroup%
+}
+
+\title{A Formalization of Safely Composable Web Components}
+\author{Achim~D.~Brucker \and Michael~Herzberg}%
+\publishers{
+ \footnotemark[1]~Department of Computer Science, University of Exeter, Exeter, UK\texorpdfstring{\\}{, }
+ \texttt{a.brucker@exeter.ac.uk}\\[2em]
+ %
+ \footnotemark[2]~ Department of Computer Science, The University of Sheffield, Sheffield, UK\texorpdfstring{\\}{, }
+ \texttt{msherzberg1@sheffield.ac.uk}
+}
+\begin{document}
+ \maketitle
+ \begin{abstract}
+ \begin{quote}
+ 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 \emph{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.
+
+ \bigskip
+ \noindent{\textbf{Keywords:} Web Components, DOM}
+ \end{quote}
+ \end{abstract}
+
+
+\tableofcontents
+\cleardoublepage
+
+\chapter{Introduction}
+The trend towards ever more complex client-side web applications is
+unstoppable. Compared to traditional software development, client-side
+web development lacks a well-established component model which allows
+easily and safely reusing implementations. The Document Object Model
+(DOM) essentially defines a tree-like data structure (the \emph{node
+tree}) for representing documents in general and HTML documents in
+particular.
+
+\emph{Shadow trees} are a recent addition to the DOM
+standard~\cite{whatwg:dom:2019} to enable web developers to partition
+the node tree into ``sub-trees.'' The vision of shadow trees is to
+enable web developers to provide a library of re-usable and
+customizable widgets. For example, let us consider a multi-tab view
+called \emph{Fancy Tab}, which is a simplified version
+of~\cite{bidelman:self-contained:2017}.
+
+\begin{figure}[b]
+ \begin{lrbox}{\fstlst}%
+ \begin{minipage}{.34\linewidth}
+ \centering
+ \includegraphics[width=\linewidth]{fancytabs-normal}
+ \end{minipage}
+ \end{lrbox}
+ \begin{lrbox}{\sndlst}%
+ \begin{minipage}{.63\linewidth}
+ \begin{html}[basicstyle=\ttfamily\scriptsize]
+<fancy-tabs>
+ <button slot="title">Politics</button>
+ <button slot="title" selected>Sports</button>
+ <button slot="title">Culture</button>
+ <section>content panel 1</section>
+ <ul>
+ <li>News Item 1 <button>Share</button></li>
+ <li>News Item 2 <button>Share</button></li>
+ <li>News Item 3 <button>Share</button></li>
+ </ul>
+ <section>content panel 3</section>
+</fancy-tabs>
+ \end{html}
+ \end{minipage}
+ \end{lrbox}
+ \subfloat[\label{fig:running-example-user}
+ User view
+ ]{\usebox{\fstlst}}%
+ \hfill%
+ \subfloat[\label{fig:running-example-consumer}
+ Consumer view
+ ]{\usebox{\sndlst}}
+ \caption{A simple example: a fancy tab component.}\label{fig:running-example}
+\end{figure}
+
+The left-hand side of \autoref{fig:running-example} shows the rendered
+output of the widget in use while the right-hand side shows the HTML
+source code snippet. It provides a custom HTML tag
+\inlinehtml{<fancy-tabs>} using an HTML template that developers can
+use to include the widget. Its children will be rendered inside the
+widget, more precisely, inside its \emph{slots} (elements of type
+\inlinehtml{slot}). It has a slot called ``title'' and a default
+slot, which receives all children that do not specify a ``slot''
+attribute.
+
+It is important to understand that slotting does \emph{not change} the
+structure of the DOM (\ie, the underlying pointer graph): instead,
+slotting is implemented using special element attributes such as
+``slot,'' which control the final rendering. The DOM standard
+specifies methods that inspect the effect of these attributes such as
+\texttt{assigned\_slot}, but the majority of DOM methods do not
+consider the semantics of these attributes and therefore do not
+traverse into shadow trees.
+
+This provides an important boundary for client-side code. For example,
+a JavaScript program coming from the widget developer that changes the
+style attributes of the ``Previous Tab'' and ``Next Tab'' buttons in the lower
+corners of the widget will not affect buttons belonging to other parts
+coming from outside, \ie, the application of the widget consumer.
+Similarly, a JavaScript program that changes the styles of buttons
+outside of Fancy Tab, such as the navigation buttons, will not have
+any effect on them, even in the case of duplicate identifiers.
+
+Sadly, the DOM standard neither defines the concept of web components
+nor specifies the safety properties that they should guarantee, not
+even informally. Consequently, the standard also does not discuss how
+or even if the methods for modifying the node tree respect component
+boundaries. Thus, shadow roots are only the very first step in
+defining a safe web component model.
+
+Earlier~\cite{brucker.ea:core-dom:2018,brucker.ea:afp-core-sc-dom:2020},
+we presented a formalization of the ``flat'' DOM (called Core DOM)
+without any support for shadow trees or components. We then extended
+this formalisation with support for shadow trees and
+slots~\cite{brucker.ea:afp-shadow-sc-dom:2020}.
+
+In this AFP entries, we use the basis provided by our earlier work for
+defining a \emph{formally verified model of web components} in general
+and, in particular, the notion of \emph{weak} and \emph{strong
+ component safety}. For all methods that query, modify, or transform
+the DOM, we formally analyze their level of component safety. In more
+detail, the contribution of this AFP entry is four-fold:
+\begin{enumerate}
+\item We provide a formal model of web components and their safety
+ guarantees to web developers, enabling a compositional development
+ of web applications,
+\item for each method, we formally verify that it is either weakly or
+ strongly component safe, or we provide a proof showing
+ that it is not component safe,
+\item we fill the gaps in the standard by explicitly formalizing
+ invariants that are left out in the standard. These invariants are
+ required to ensure that methods in the standard preserve a valid
+ node tree. Finally,
+\item we present a formal model of the DOM with shadow roots including
+ the methods for querying, modifying, and transforming DOM instances
+ with shadow roots.
+\end{enumerate}
+Overall, our work gives web developers the guarantee that their code
+will respect the component boundaries as long as they abstain from or
+are careful when using certain DOM methods such as
+\texttt{appendChild} or \texttt{ownerDocument}.
+
+The rest of this document is automatically generated from the
+formalization in Isabelle/HOL, i.e., all content is checked by
+Isabelle (we refer readers interested in a more high-level
+presentation of the work to \cite{herzberg:web-components:2020,
+ brucker.ea:web-components:2019}. The structure follows the theory
+dependencies (see \autoref{fig:session-graph}).
+
+
+\paragraph{Important Note:} This document describes the formalization
+of the \emph{Safely Composable Web Components} (based on the SC DOM),
+which deviated in one important aspect from the official DOM standard:
+in the SC DOM, the shadow root is a sub-class of the document class
+(instead of a base class). This modification results in a stronger notion
+of web components that provide improved safety properties for the composition of web
+components. While the SC DOM still passes the compliance test suite as
+provided by the authors of the DOM standard, its data model is
+different. We refer readers interested in a formalisation of the
+standard compliant DOM to the AFP entries
+``Core\_DOM''~\cite{brucker.ea:afp-core-dom:2018},
+``Shadow\_DOM''~\cite{brucker.ea:afp-shadow-dom:2020}, and
+``COM\_Components''~\cite{brucker.ea:afp-dom-components:2020}.
+
+\begin{figure}
+ \centering
+ \includegraphics[width=.8\textwidth]{session_graph}
+ \caption{The Dependency Graph of the Isabelle Theories.\label{fig:session-graph}}
+\end{figure}
+
+\clearpage
+
+\chapter{Safely Composable Web Components}
+\label{cha:components}
+\input{Core_DOM_DOM_Components.tex}
+\input{Core_DOM_SC_DOM_Components.tex}
+\input{Shadow_DOM_DOM_Components.tex}
+\input{Shadow_DOM_SC_DOM_Components.tex}
+
+{\small
+ \bibliographystyle{abbrvnat}
+ \bibliography{root}
+}
+\end{document}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: t
+%%% End:
diff --git a/thys/Shadow_SC_DOM/ROOT b/thys/Shadow_SC_DOM/ROOT
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/ROOT
@@ -0,0 +1,14 @@
+chapter AFP
+
+session "Shadow_SC_DOM" (AFP) = "Core_SC_DOM" +
+ options [timeout = 1200]
+ directories
+ classes
+ monads
+ tests
+ theories
+ Shadow_DOM
+ Shadow_DOM_Tests
+ document_files
+ "root.tex"
+ "root.bib"
diff --git a/thys/Shadow_SC_DOM/Shadow_DOM.thy b/thys/Shadow_SC_DOM/Shadow_DOM.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/Shadow_DOM.thy
@@ -0,0 +1,12913 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>The Shadow DOM\<close>
+theory Shadow_DOM
+ imports
+ "monads/ShadowRootMonad"
+ Core_SC_DOM.Core_DOM
+begin
+
+
+
+abbreviation "safe_shadow_root_element_types \<equiv> {''article'', ''aside'', ''blockquote'', ''body'',
+ ''div'', ''footer'', ''h1'', ''h2'', ''h3'', ''h4'', ''h5'', ''h6'', ''header'', ''main'',
+ ''nav'', ''p'', ''section'', ''span''}"
+
+
+subsection \<open>Function Definitions\<close>
+
+
+
+subsubsection \<open>get\_child\_nodes\<close>
+
+locale l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ CD: l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+definition get_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) shadow_root_ptr \<Rightarrow> unit
+ \<Rightarrow> (_, (_) node_ptr list) dom_prog" where
+ "get_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr _ = get_M shadow_root_ptr RShadowRoot.child_nodes"
+
+definition a_get_child_nodes_tups :: "(((_) object_ptr \<Rightarrow> bool) \<times> ((_) object_ptr \<Rightarrow> unit
+ \<Rightarrow> (_, (_) node_ptr list) dom_prog)) list" where
+ "a_get_child_nodes_tups \<equiv> [(is_shadow_root_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r, get_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast)]"
+
+definition a_get_child_nodes :: "(_) object_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog" where
+ "a_get_child_nodes ptr = invoke (CD.a_get_child_nodes_tups @ a_get_child_nodes_tups) ptr ()"
+
+definition a_get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" where
+ "a_get_child_nodes_locs ptr \<equiv>
+ (if is_shadow_root_ptr_kind ptr
+ then {preserved (get_M (the (cast ptr)) RShadowRoot.child_nodes)} else {}) \<union>
+ CD.a_get_child_nodes_locs ptr"
+
+definition first_child :: "(_) object_ptr \<Rightarrow> (_, (_) node_ptr option) dom_prog"
+ where
+ "first_child ptr = do {
+ children \<leftarrow> a_get_child_nodes ptr;
+ return (case children of [] \<Rightarrow> None | child#_ \<Rightarrow> Some child)}"
+end
+
+global_interpretation l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs defines
+ get_child_nodes = l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_child_nodes and
+ get_child_nodes_locs = l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_child_nodes_locs
+ .
+
+locale l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_known_ptr known_ptr +
+ l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_get_child_nodes_defs get_child_nodes get_child_nodes_locs +
+ CD: l_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ and get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes known_ptr_impl: "known_ptr = ShadowRootClass.known_ptr"
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+ assumes get_child_nodes_impl: "get_child_nodes = a_get_child_nodes"
+ assumes get_child_nodes_locs_impl: "get_child_nodes_locs = a_get_child_nodes_locs"
+begin
+lemmas get_child_nodes_def = get_child_nodes_impl[unfolded a_get_child_nodes_def get_child_nodes_def]
+lemmas get_child_nodes_locs_def = get_child_nodes_locs_impl[unfolded a_get_child_nodes_locs_def
+ get_child_nodes_locs_def, folded CD.get_child_nodes_locs_impl]
+
+lemma get_child_nodes_ok:
+ assumes "known_ptr ptr"
+ assumes "type_wf h"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ shows "h \<turnstile> ok (get_child_nodes ptr)"
+ using assms[unfolded known_ptr_impl type_wf_impl]
+ apply(auto simp add: get_child_nodes_def)[1]
+ apply(split CD.get_child_nodes_splits, rule conjI)+
+ using ShadowRootClass.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t CD.get_child_nodes_ok CD.known_ptr_impl CD.type_wf_impl
+ apply blast
+ apply(auto simp add: CD.known_ptr_impl a_get_child_nodes_tups_def get_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok
+ dest!: known_ptr_new_shadow_root_ptr intro!: bind_is_OK_I2)[1]
+ by(auto dest: get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok split: option.splits)
+
+lemma get_child_nodes_ptr_in_heap:
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ by(auto simp add: get_child_nodes_def invoke_ptr_in_heap dest: is_OK_returns_result_I)
+
+lemma get_child_nodes_pure [simp]:
+ "pure (get_child_nodes ptr) h"
+ apply (auto simp add: get_child_nodes_def a_get_child_nodes_tups_def)[1]
+ apply(split CD.get_child_nodes_splits, rule conjI)+
+ apply(simp)
+ apply(split invoke_splits, rule conjI)+
+ apply(simp)
+ by(auto simp add: get_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: bind_pure_I)
+
+lemma get_child_nodes_reads: "reads (get_child_nodes_locs ptr) (get_child_nodes ptr) h h'"
+ apply (simp add: get_child_nodes_def a_get_child_nodes_tups_def get_child_nodes_locs_def
+ CD.get_child_nodes_locs_def)
+ apply(split CD.get_child_nodes_splits, rule conjI)+
+ apply(auto intro!: reads_subset[OF CD.get_child_nodes_reads[unfolded CD.get_child_nodes_locs_def]]
+ split: if_splits)[1]
+ apply(split invoke_splits, rule conjI)+
+ apply(auto)[1]
+ apply(auto simp add: get_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ intro: reads_subset[OF reads_singleton] reads_subset[OF check_in_heap_reads]
+ intro!: reads_bind_pure reads_subset[OF return_reads] split: option.splits)[1]
+ done
+end
+
+interpretation i_get_child_nodes?: l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr DocumentClass.type_wf
+ DocumentClass.known_ptr get_child_nodes get_child_nodes_locs Core_DOM_Functions.get_child_nodes
+ Core_DOM_Functions.get_child_nodes_locs
+ by(simp add: l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_child_nodes_is_l_get_child_nodes [instances]: "l_get_child_nodes type_wf known_ptr
+ get_child_nodes get_child_nodes_locs"
+ apply(auto simp add: l_get_child_nodes_def instances)[1]
+ using get_child_nodes_reads get_child_nodes_ok get_child_nodes_ptr_in_heap get_child_nodes_pure
+ by blast+
+
+
+paragraph \<open>new\_document\<close>
+
+locale l_new_document_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ CD: l_new_document_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes
+ get_child_nodes_locs get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> bool"
+ and get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_child_nodes_new_document:
+ "ptr' \<noteq> cast new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr
+ \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+ apply(auto simp add: get_child_nodes_locs_def)[1]
+ using CD.get_child_nodes_new_document
+ apply (metis document_ptr_casts_commute3 empty_iff is_document_ptr_kind_none
+ new_document_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t option.case_eq_if shadow_root_ptr_casts_commute3 singletonD)
+ by (simp add: CD.get_child_nodes_new_document)
+
+lemma new_document_no_child_nodes:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_child_nodes (cast new_document_ptr) \<rightarrow>\<^sub>r []"
+ apply(auto simp add: get_child_nodes_def)[1]
+ apply(split CD.get_child_nodes_splits, rule conjI)+
+ using CD.new_document_no_child_nodes apply auto[1]
+ by(auto simp add: DocumentClass.a_known_ptr_def CD.known_ptr_impl known_ptr_def
+ dest!: new_document_is_document_ptr)
+end
+interpretation i_new_document_get_child_nodes?:
+ l_new_document_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr get_child_nodes get_child_nodes_locs
+ DocumentClass.type_wf DocumentClass.known_ptr Core_DOM_Functions.get_child_nodes
+ Core_DOM_Functions.get_child_nodes_locs
+ by(unfold_locales)
+declare l_new_document_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma new_document_get_child_nodes_is_l_new_document_get_child_nodes [instances]:
+ "l_new_document_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs"
+ using new_document_is_l_new_document get_child_nodes_is_l_get_child_nodes
+ apply(simp add: l_new_document_get_child_nodes_def l_new_document_get_child_nodes_axioms_def)
+ using get_child_nodes_new_document new_document_no_child_nodes
+ by fast
+
+paragraph \<open>new\_shadow\_root\<close>
+
+locale l_new_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes
+ get_child_nodes_locs get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> bool"
+ and get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_child_nodes_new_shadow_root:
+ "ptr' \<noteq> cast new_shadow_root_ptr \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
+ \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+ apply(auto simp add: get_child_nodes_locs_def)[1]
+ apply (metis document_ptr_casts_commute3 insert_absorb insert_not_empty is_document_ptr_kind_none
+ new_shadow_root_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t option.case_eq_if shadow_root_ptr_casts_commute3 singletonD)
+ apply(auto simp add: CD.get_child_nodes_locs_def)[1]
+ using new_shadow_root_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t apply blast
+ apply (smt insertCI new_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t singleton_iff)
+ apply (metis document_ptr_casts_commute3 empty_iff new_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t singletonD)
+ done
+
+lemma new_shadow_root_no_child_nodes:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_child_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []"
+ apply(auto simp add: get_child_nodes_def )[1]
+ apply(split CD.get_child_nodes_splits, rule conjI)+
+ apply(auto simp add: CD.get_child_nodes_def CD.a_get_child_nodes_tups_def)[1]
+ apply(split invoke_splits, rule conjI)+
+ using NodeClass.a_known_ptr_def known_ptr_not_character_data_ptr known_ptr_not_document_ptr
+ known_ptr_not_element_ptr local.CD.known_ptr_impl apply blast
+ apply(auto simp add: is_document_ptr_def cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: option.splits document_ptr.splits)[1]
+ apply(auto simp add: is_character_data_ptr_def cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: option.splits document_ptr.splits)[1]
+ apply(auto simp add: is_element_ptr_def cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: option.splits document_ptr.splits)[1]
+ apply(auto simp add: a_get_child_nodes_tups_def)[1]
+ apply(split invoke_splits, rule conjI)+
+ apply(auto simp add: is_shadow_root_ptr_def split: shadow_root_ptr.splits
+ dest!: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_is_shadow_root_ptr)[1]
+ apply(auto intro!: bind_pure_returns_result_I)[1]
+ apply(drule(1) new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_in_heap)
+ apply(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)[1]
+ apply (metis check_in_heap_ptr_in_heap is_OK_returns_result_E old.unit.exhaust)
+ using new_shadow_root_children
+ by (simp add: new_shadow_root_children get_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def)
+end
+interpretation i_new_shadow_root_get_child_nodes?:
+ l_new_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr get_child_nodes get_child_nodes_locs
+ DocumentClass.type_wf DocumentClass.known_ptr Core_DOM_Functions.get_child_nodes
+ Core_DOM_Functions.get_child_nodes_locs
+ by(unfold_locales)
+declare l_new_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def[instances]
+
+locale l_new_shadow_root_get_child_nodes = l_get_child_nodes +
+ assumes get_child_nodes_new_shadow_root:
+ "ptr' \<noteq> cast new_shadow_root_ptr \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
+ \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+ assumes new_shadow_root_no_child_nodes:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_child_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []"
+
+lemma new_shadow_root_get_child_nodes_is_l_new_shadow_root_get_child_nodes [instances]:
+ "l_new_shadow_root_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs"
+ apply(simp add: l_new_shadow_root_get_child_nodes_def l_new_shadow_root_get_child_nodes_axioms_def instances)
+ using get_child_nodes_new_shadow_root new_shadow_root_no_child_nodes
+ by fast
+
+paragraph \<open>new\_element\<close>
+
+locale l_new_element_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_new_element_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma get_child_nodes_new_element:
+ "ptr' \<noteq> cast new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+ by (auto simp add: get_child_nodes_locs_def CD.get_child_nodes_locs_def new_element_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t new_element_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ new_element_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t new_element_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t split: prod.splits if_splits option.splits
+ elim!: bind_returns_result_E bind_returns_heap_E intro: is_element_ptr_kind_obtains)
+
+lemma new_element_no_child_nodes:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []"
+ apply(auto simp add: get_child_nodes_def a_get_child_nodes_tups_def
+ split: prod.splits elim!: bind_returns_result_E bind_returns_heap_E)[1]
+ apply(split CD.get_child_nodes_splits, rule conjI)+
+ using local.new_element_no_child_nodes apply auto[1]
+ apply(auto simp add: invoke_def)[1]
+ using case_optionE apply fastforce
+ apply(auto simp add: new_element_ptr_in_heap get_child_nodes\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def check_in_heap_def
+ new_element_child_nodes intro!: bind_pure_returns_result_I
+ intro: new_element_is_element_ptr elim!: new_element_ptr_in_heap)[1]
+proof -
+ assume " h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr"
+ assume "h \<turnstile> new_element \<rightarrow>\<^sub>h h'"
+ assume "\<not> is_shadow_root_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr)"
+ assume "\<not> known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr)"
+ moreover
+ have "known_ptr (cast new_element_ptr)"
+ using new_element_is_element_ptr \<open>h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr\<close>
+ by(auto simp add: known_ptr_impl ShadowRootClass.a_known_ptr_def DocumentClass.a_known_ptr_def
+ CharacterDataClass.a_known_ptr_def ElementClass.a_known_ptr_def)
+ ultimately show "False"
+ by(simp add: known_ptr_impl CD.known_ptr_impl ShadowRootClass.a_known_ptr_def is_document_ptr_kind_none)
+qed
+end
+
+interpretation i_new_element_get_child_nodes?:
+ l_new_element_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr DocumentClass.type_wf
+ DocumentClass.known_ptr get_child_nodes get_child_nodes_locs Core_DOM_Functions.get_child_nodes
+ Core_DOM_Functions.get_child_nodes_locs
+ by(unfold_locales)
+declare l_new_element_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma new_element_get_child_nodes_is_l_new_element_get_child_nodes [instances]:
+ "l_new_element_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs"
+ using new_element_is_l_new_element get_child_nodes_is_l_get_child_nodes
+ apply(auto simp add: l_new_element_get_child_nodes_def l_new_element_get_child_nodes_axioms_def)[1]
+ using get_child_nodes_new_element new_element_no_child_nodes
+ by fast+
+
+
+subsubsection \<open>delete\_shadow\_root\<close>
+
+locale l_delete_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma get_child_nodes_delete_shadow_root:
+ "ptr' \<noteq> cast shadow_root_ptr \<Longrightarrow> h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow>
+r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+ by(auto simp add: get_child_nodes_locs_def CD.get_child_nodes_locs_def delete_shadow_root_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ delete_shadow_root_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t delete_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t delete_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ split: if_splits intro: is_shadow_root_ptr_kind_obtains
+ intro: is_shadow_root_ptr_kind_obtains delete_shadow_root_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t delete_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ simp add: shadow_root_ptr_casts_commute3 delete_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ intro!: delete_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t dest: document_ptr_casts_commute3
+ split: option.splits)
+end
+
+locale l_delete_shadow_root_get_child_nodes = l_get_child_nodes_defs +
+ assumes get_child_nodes_delete_shadow_root:
+ "ptr' \<noteq> cast shadow_root_ptr \<Longrightarrow> h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow>
+r \<in> get_child_nodes_locs ptr' \<Longrightarrow> r h h'"
+
+interpretation l_delete_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr DocumentClass.type_wf
+ DocumentClass.known_ptr get_child_nodes get_child_nodes_locs Core_DOM_Functions.get_child_nodes
+ Core_DOM_Functions.get_child_nodes_locs
+ by(auto simp add: l_delete_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+
+lemma l_delete_shadow_root_get_child_nodes_get_child_nodes_locs [instances]: "l_delete_shadow_root_get_child_nodes get_child_nodes_locs"
+ apply(auto simp add: l_delete_shadow_root_get_child_nodes_def)[1]
+ using get_child_nodes_delete_shadow_root apply fast
+ done
+
+
+subsubsection \<open>set\_child\_nodes\<close>
+
+locale l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ CD: l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+definition set_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) shadow_root_ptr \<Rightarrow> (_) node_ptr list
+ \<Rightarrow> (_, unit) dom_prog" where
+ "set_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr = put_M shadow_root_ptr RShadowRoot.child_nodes_update"
+
+definition a_set_child_nodes_tups :: "(((_) object_ptr \<Rightarrow> bool) \<times> ((_) object_ptr \<Rightarrow> (_) node_ptr list
+ \<Rightarrow> (_, unit) dom_prog)) list" where
+ "a_set_child_nodes_tups \<equiv> [(is_shadow_root_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r, set_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast)]"
+
+definition a_set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_set_child_nodes ptr children = invoke (CD.a_set_child_nodes_tups @ a_set_child_nodes_tups) ptr children"
+
+definition a_set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> (_, unit) dom_prog set"
+ where
+ "a_set_child_nodes_locs ptr \<equiv>
+ (if is_shadow_root_ptr_kind ptr then all_args (put_M (the (cast ptr)) RShadowRoot.child_nodes_update) else {}) \<union>
+ CD.a_set_child_nodes_locs ptr"
+end
+
+global_interpretation l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs defines
+ set_child_nodes = l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_child_nodes and
+ set_child_nodes_locs = l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_set_child_nodes_locs
+ .
+
+locale l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_known_ptr known_ptr +
+ l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_set_child_nodes_defs set_child_nodes set_child_nodes_locs +
+ CD: l_set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> bool"
+ and set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ and set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> (_, unit) dom_prog set"
+ and set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> (_, unit) dom_prog"
+ and set_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> (_, unit) dom_prog set" +
+ assumes known_ptr_impl: "known_ptr = ShadowRootClass.known_ptr"
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+ assumes set_child_nodes_impl: "set_child_nodes = a_set_child_nodes"
+ assumes set_child_nodes_locs_impl: "set_child_nodes_locs = a_set_child_nodes_locs"
+begin
+lemmas set_child_nodes_def = set_child_nodes_impl[unfolded a_set_child_nodes_def set_child_nodes_def]
+lemmas set_child_nodes_locs_def =set_child_nodes_locs_impl[unfolded a_set_child_nodes_locs_def
+ set_child_nodes_locs_def, folded CD.set_child_nodes_locs_impl]
+
+lemma set_child_nodes_writes: "writes (set_child_nodes_locs ptr) (set_child_nodes ptr children) h h'"
+ apply (simp add: set_child_nodes_def a_set_child_nodes_tups_def set_child_nodes_locs_def)
+ apply(split CD.set_child_nodes_splits, rule conjI)+
+ apply (simp add: CD.set_child_nodes_writes writes_union_right_I)
+ apply(split invoke_splits, rule conjI)+
+ apply(auto simp add: a_set_child_nodes_def)[1]
+ apply(auto simp add: set_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: writes_bind_pure
+ intro: writes_union_right_I writes_union_left_I split: list.splits)[1]
+ by (metis is_shadow_root_ptr_implies_kind option.case_eq_if)
+
+lemma set_child_nodes_pointers_preserved:
+ assumes "w \<in> set_child_nodes_locs object_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms(1) object_ptr_kinds_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: all_args_def set_child_nodes_locs_def CD.set_child_nodes_locs_def split: if_splits)
+
+lemma set_child_nodes_types_preserved:
+ assumes "w \<in> set_child_nodes_locs object_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ using assms(1) type_wf_preserved[OF writes_singleton2 assms(2)] type_wf_impl
+ by(auto simp add: all_args_def a_set_child_nodes_tups_def set_child_nodes_locs_def CD.set_child_nodes_locs_def
+ split: if_splits option.splits)
+end
+
+interpretation
+ i_set_child_nodes?: l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr DocumentClass.type_wf
+ DocumentClass.known_ptr set_child_nodes set_child_nodes_locs Core_DOM_Functions.set_child_nodes
+ Core_DOM_Functions.set_child_nodes_locs
+ apply(unfold_locales)
+ by (auto simp add: set_child_nodes_def set_child_nodes_locs_def)
+declare l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_child_nodes_is_l_set_child_nodes [instances]: "l_set_child_nodes type_wf
+set_child_nodes set_child_nodes_locs"
+ apply(auto simp add: l_set_child_nodes_def instances)[1]
+ using set_child_nodes_writes apply fast
+ using set_child_nodes_pointers_preserved apply(fast, fast)
+ using set_child_nodes_types_preserved apply(fast, fast)
+ done
+
+
+
+paragraph \<open>get\_child\_nodes\<close>
+
+locale l_set_child_nodes_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs
+ get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_child_nodes set_child_nodes_locs
+ set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + CD: l_set_child_nodes_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+begin
+
+lemma set_child_nodes_get_child_nodes:
+ assumes "known_ptr ptr"
+ assumes "type_wf h"
+ assumes "h \<turnstile> set_child_nodes ptr children \<rightarrow>\<^sub>h h'"
+ shows "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+proof -
+ have "h \<turnstile> check_in_heap ptr \<rightarrow>\<^sub>r ()"
+ using assms set_child_nodes_def invoke_ptr_in_heap
+ by (metis (full_types) check_in_heap_ptr_in_heap is_OK_returns_heap_I is_OK_returns_result_E
+ old.unit.exhaust)
+ then have ptr_in_h: "ptr |\<in>| object_ptr_kinds h"
+ by (simp add: check_in_heap_ptr_in_heap is_OK_returns_result_I)
+
+ have "type_wf h'"
+ apply(unfold type_wf_impl)
+ apply(rule subst[where P=id, OF type_wf_preserved[OF set_child_nodes_writes assms(3),
+ unfolded all_args_def], simplified])
+ by(auto simp add: all_args_def assms(2)[unfolded type_wf_impl] set_child_nodes_locs_def
+ CD.set_child_nodes_locs_def split: if_splits)
+ have "h' \<turnstile> check_in_heap ptr \<rightarrow>\<^sub>r ()"
+ using check_in_heap_reads set_child_nodes_writes assms(3) \<open>h \<turnstile> check_in_heap ptr \<rightarrow>\<^sub>r ()\<close>
+ apply(rule reads_writes_separate_forwards)
+ apply(auto simp add: all_args_def set_child_nodes_locs_def CD.set_child_nodes_locs_def)[1]
+ done
+ then have "ptr |\<in>| object_ptr_kinds h'"
+ using check_in_heap_ptr_in_heap by blast
+ with assms ptr_in_h \<open>type_wf h'\<close> show ?thesis
+ apply(auto simp add: type_wf_impl known_ptr_impl get_child_nodes_def a_get_child_nodes_tups_def
+ set_child_nodes_def a_set_child_nodes_tups_def del: bind_pure_returns_result_I2 intro!: bind_pure_returns_result_I2)[1]
+ apply(split CD.get_child_nodes_splits, (rule conjI impI)+)+
+ apply(split CD.set_child_nodes_splits)+
+ apply(auto simp add: CD.set_child_nodes_get_child_nodes type_wf_impl CD.type_wf_impl
+ dest: ShadowRootClass.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t)[1]
+ apply(auto simp add: CD.set_child_nodes_get_child_nodes type_wf_impl CD.type_wf_impl
+ dest: ShadowRootClass.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t)[1]
+ apply(split CD.set_child_nodes_splits)+
+ by(auto simp add: known_ptr_impl CD.known_ptr_impl set_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ get_child_nodes\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.type_wf_impl ShadowRootClass.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t dest: known_ptr_new_shadow_root_ptr)[2]
+qed
+
+lemma set_child_nodes_get_child_nodes_different_pointers:
+ assumes "ptr \<noteq> ptr'"
+ assumes "w \<in> set_child_nodes_locs ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ assumes "r \<in> get_child_nodes_locs ptr'"
+ shows "r h h'"
+ using assms
+ apply(auto simp add: set_child_nodes_locs_def CD.set_child_nodes_locs_def
+ get_child_nodes_locs_def CD.get_child_nodes_locs_def)[1]
+ by(auto simp add: all_args_def elim!: is_document_ptr_kind_obtains is_shadow_root_ptr_kind_obtains
+ is_element_ptr_kind_obtains split: if_splits option.splits)
+
+end
+
+interpretation
+ i_set_child_nodes_get_child_nodes?: l_set_child_nodes_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr
+ DocumentClass.type_wf DocumentClass.known_ptr get_child_nodes get_child_nodes_locs
+ Core_DOM_Functions.get_child_nodes Core_DOM_Functions.get_child_nodes_locs set_child_nodes
+ set_child_nodes_locs Core_DOM_Functions.set_child_nodes Core_DOM_Functions.set_child_nodes_locs
+ using instances
+ by(auto simp add: l_set_child_nodes_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def )
+declare l_set_child_nodes_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_child_nodes_get_child_nodes_is_l_set_child_nodes_get_child_nodes [instances]:
+ "l_set_child_nodes_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs set_child_nodes set_child_nodes_locs"
+ apply(auto simp add: instances l_set_child_nodes_get_child_nodes_def l_set_child_nodes_get_child_nodes_axioms_def)[1]
+ using set_child_nodes_get_child_nodes apply fast
+ using set_child_nodes_get_child_nodes_different_pointers apply fast
+ done
+
+
+subsubsection \<open>set\_tag\_type\<close>
+
+locale l_set_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ CD: l_set_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_tag_name set_tag_name_locs +
+ l_type_wf type_wf
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and set_tag_name :: "(_) element_ptr \<Rightarrow> tag_name \<Rightarrow> (_, unit) dom_prog"
+ and set_tag_name_locs :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog set" +
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+begin
+lemmas set_tag_name_def = CD.set_tag_name_impl[unfolded CD.a_set_tag_name_def set_tag_name_def]
+lemmas set_tag_name_locs_def = CD.set_tag_name_locs_impl[unfolded CD.a_set_tag_name_locs_def
+ set_tag_name_locs_def]
+
+lemma set_tag_name_ok:
+ "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (set_tag_name element_ptr tag)"
+ apply(unfold type_wf_impl)
+ unfolding set_tag_name_impl[unfolded a_set_tag_name_def] using get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok
+ using CD.set_tag_name_ok CD.type_wf_impl ShadowRootClass.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t by blast
+
+lemma set_tag_name_writes:
+ "writes (set_tag_name_locs element_ptr) (set_tag_name element_ptr tag) h h'"
+ using CD.set_tag_name_writes .
+
+lemma set_tag_name_pointers_preserved:
+ assumes "w \<in> set_tag_name_locs element_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms
+ by(simp add: CD.set_tag_name_pointers_preserved)
+
+lemma set_tag_name_typess_preserved:
+ assumes "w \<in> set_tag_name_locs element_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ apply(unfold type_wf_impl)
+ apply(rule type_wf_preserved[OF writes_singleton2 assms(2)])
+ using assms(1) set_tag_name_locs_def
+ by(auto simp add: all_args_def set_tag_name_locs_def
+ split: if_splits)
+end
+
+interpretation i_set_tag_name?: l_set_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf set_tag_name
+ set_tag_name_locs
+ by(auto simp add: l_set_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_set_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_set_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma set_tag_name_is_l_set_tag_name [instances]: "l_set_tag_name type_wf set_tag_name set_tag_name_locs"
+ apply(auto simp add: l_set_tag_name_def)[1]
+
+ using set_tag_name_writes apply fast
+ using set_tag_name_ok apply fast
+ using set_tag_name_pointers_preserved apply (fast, fast)
+ using set_tag_name_typess_preserved apply (fast, fast)
+ done
+
+paragraph \<open>get\_child\_nodes\<close>
+
+locale l_set_tag_name_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ CD: l_set_tag_name_get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_tag_name set_tag_name_locs
+ known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_tag_name_get_child_nodes:
+ "\<forall>w \<in> set_tag_name_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+ apply(auto simp add: get_child_nodes_locs_def)[1]
+ apply(auto simp add: set_tag_name_locs_def all_args_def)[1]
+ using CD.set_tag_name_get_child_nodes apply(blast)
+ using CD.set_tag_name_get_child_nodes apply(blast)
+ done
+end
+
+interpretation
+ i_set_tag_name_get_child_nodes?: l_set_tag_name_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf
+ set_tag_name set_tag_name_locs known_ptr DocumentClass.known_ptr get_child_nodes
+ get_child_nodes_locs Core_DOM_Functions.get_child_nodes
+ Core_DOM_Functions.get_child_nodes_locs
+ by unfold_locales
+declare l_set_tag_name_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_tag_name_get_child_nodes_is_l_set_tag_name_get_child_nodes [instances]:
+ "l_set_tag_name_get_child_nodes type_wf set_tag_name set_tag_name_locs known_ptr get_child_nodes
+ get_child_nodes_locs"
+ using set_tag_name_is_l_set_tag_name get_child_nodes_is_l_get_child_nodes
+ apply(simp add: l_set_tag_name_get_child_nodes_def
+ l_set_tag_name_get_child_nodes_axioms_def)
+ using set_tag_name_get_child_nodes
+ by fast
+
+
+subsubsection \<open>get\_shadow\_root\<close>
+
+locale l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+definition a_get_shadow_root :: "(_) element_ptr \<Rightarrow> (_, (_) shadow_root_ptr option) dom_prog"
+ where
+ "a_get_shadow_root element_ptr = get_M element_ptr shadow_root_opt"
+
+definition a_get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ where
+ "a_get_shadow_root_locs element_ptr \<equiv> {preserved (get_M element_ptr shadow_root_opt)}"
+end
+
+global_interpretation l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ defines get_shadow_root = a_get_shadow_root
+ and get_shadow_root_locs = a_get_shadow_root_locs
+ .
+
+locale l_get_shadow_root_defs =
+ fixes get_shadow_root :: "(_) element_ptr \<Rightarrow> (_, (_) shadow_root_ptr option) dom_prog"
+ fixes get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_get_shadow_root_defs get_shadow_root get_shadow_root_locs +
+ l_type_wf type_wf
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+ assumes get_shadow_root_impl: "get_shadow_root = a_get_shadow_root"
+ assumes get_shadow_root_locs_impl: "get_shadow_root_locs = a_get_shadow_root_locs"
+begin
+lemmas get_shadow_root_def = get_shadow_root_impl[unfolded get_shadow_root_def a_get_shadow_root_def]
+lemmas get_shadow_root_locs_def = get_shadow_root_locs_impl[unfolded get_shadow_root_locs_def a_get_shadow_root_locs_def]
+
+lemma get_shadow_root_ok: "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_shadow_root element_ptr)"
+ unfolding get_shadow_root_def type_wf_impl
+ using ShadowRootMonad.get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok by blast
+
+lemma get_shadow_root_pure [simp]: "pure (get_shadow_root element_ptr) h"
+ unfolding get_shadow_root_def by simp
+
+lemma get_shadow_root_ptr_in_heap:
+ assumes "h \<turnstile> get_shadow_root element_ptr \<rightarrow>\<^sub>r children"
+ shows "element_ptr |\<in>| element_ptr_kinds h"
+ using assms
+ by(auto simp add: get_shadow_root_def get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap dest: is_OK_returns_result_I)
+
+lemma get_shadow_root_reads: "reads (get_shadow_root_locs element_ptr) (get_shadow_root element_ptr) h h'"
+ by(simp add: get_shadow_root_def get_shadow_root_locs_def reads_bind_pure reads_insert_writes_set_right)
+end
+
+interpretation i_get_shadow_root?: l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ using instances
+ by (auto simp add: l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+locale l_get_shadow_root = l_type_wf + l_get_shadow_root_defs +
+ assumes get_shadow_root_reads: "reads (get_shadow_root_locs element_ptr) (get_shadow_root element_ptr) h h'"
+ assumes get_shadow_root_ok: "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_shadow_root element_ptr)"
+ assumes get_shadow_root_ptr_in_heap: "h \<turnstile> ok (get_shadow_root element_ptr) \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h"
+ assumes get_shadow_root_pure [simp]: "pure (get_shadow_root element_ptr) h"
+
+lemma get_shadow_root_is_l_get_shadow_root [instances]: "l_get_shadow_root type_wf get_shadow_root get_shadow_root_locs"
+ using instances
+ apply(auto simp add: l_get_shadow_root_def)[1]
+ using get_shadow_root_reads apply blast
+ using get_shadow_root_ok apply blast
+ using get_shadow_root_ptr_in_heap apply blast
+ done
+
+
+paragraph \<open>set\_disconnected\_nodes\<close>
+
+locale l_set_disconnected_nodes_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_disconnected_nodes set_disconnected_nodes_locs +
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma set_disconnected_nodes_get_shadow_root:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+ by(auto simp add: set_disconnected_nodes_locs_def get_shadow_root_locs_def all_args_def)
+end
+
+locale l_set_disconnected_nodes_get_shadow_root = l_set_disconnected_nodes_defs + l_get_shadow_root_defs +
+ assumes set_disconnected_nodes_get_shadow_root: "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+
+interpretation
+ i_set_disconnected_nodes_get_shadow_root?: l_set_disconnected_nodes_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ DocumentClass.type_wf set_disconnected_nodes set_disconnected_nodes_locs get_shadow_root get_shadow_root_locs
+ by(auto simp add: l_set_disconnected_nodes_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_set_disconnected_nodes_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_disconnected_nodes_get_shadow_root_is_l_set_disconnected_nodes_get_shadow_root [instances]:
+ "l_set_disconnected_nodes_get_shadow_root set_disconnected_nodes_locs get_shadow_root_locs"
+ apply(auto simp add: l_set_disconnected_nodes_get_shadow_root_def)[1]
+ using set_disconnected_nodes_get_shadow_root apply fast
+ done
+
+
+
+paragraph \<open>set\_tag\_type\<close>
+
+locale l_set_tag_name_get_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_tag_name_get_shadow_root:
+ "\<forall>w \<in> set_tag_name_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+ by(auto simp add: set_tag_name_locs_def
+ get_shadow_root_locs_def all_args_def
+ intro: element_put_get_preserved[where setter=tag_name_update and getter=shadow_root_opt])
+end
+
+locale l_set_tag_name_get_shadow_root = l_set_tag_name + l_get_shadow_root +
+ assumes set_tag_name_get_shadow_root:
+ "\<forall>w \<in> set_tag_name_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+
+interpretation
+ i_set_tag_name_get_shadow_root?: l_set_tag_name_get_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf
+ set_tag_name set_tag_name_locs
+ get_shadow_root get_shadow_root_locs
+ apply(auto simp add: l_set_tag_name_get_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)[1]
+ using l_set_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms
+ by unfold_locales
+declare l_set_tag_name_get_shadow_root\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_tag_name_get_shadow_root_is_l_set_tag_name_get_shadow_root [instances]:
+ "l_set_tag_name_get_shadow_root type_wf set_tag_name set_tag_name_locs get_shadow_root
+ get_shadow_root_locs"
+ using set_tag_name_is_l_set_tag_name get_shadow_root_is_l_get_shadow_root
+ apply(simp add: l_set_tag_name_get_shadow_root_def l_set_tag_name_get_shadow_root_axioms_def)
+ using set_tag_name_get_shadow_root
+ by fast
+
+
+paragraph \<open>set\_child\_nodes\<close>
+
+locale l_set_child_nodes_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_child_nodes
+ set_child_nodes_locs set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> bool"
+ and set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma set_child_nodes_get_shadow_root: "\<forall>w \<in> set_child_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+ apply(auto simp add: set_child_nodes_locs_def get_shadow_root_locs_def CD.set_child_nodes_locs_def all_args_def)[1]
+ by(auto intro!: element_put_get_preserved[where getter=shadow_root_opt and setter=RElement.child_nodes_update])
+end
+
+locale l_set_child_nodes_get_shadow_root = l_set_child_nodes_defs + l_get_shadow_root_defs +
+ assumes set_child_nodes_get_shadow_root: "\<forall>w \<in> set_child_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+
+interpretation
+ i_set_child_nodes_get_shadow_root?: l_set_child_nodes_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr
+ DocumentClass.type_wf DocumentClass.known_ptr set_child_nodes set_child_nodes_locs
+ Core_DOM_Functions.set_child_nodes Core_DOM_Functions.set_child_nodes_locs get_shadow_root
+ get_shadow_root_locs
+ by(auto simp add: l_set_child_nodes_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_set_child_nodes_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_child_nodes_get_shadow_root_is_l_set_child_nodes_get_shadow_root [instances]:
+ "l_set_child_nodes_get_shadow_root set_child_nodes_locs get_shadow_root_locs"
+ apply(auto simp add: l_set_child_nodes_get_shadow_root_def)[1]
+ using set_child_nodes_get_shadow_root apply fast
+ done
+
+
+paragraph \<open>delete\_shadow\_root\<close>
+
+locale l_delete_shadow_root_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma get_shadow_root_delete_shadow_root: "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_shadow_root_locs ptr' \<Longrightarrow> r h h'"
+ by(auto simp add: get_shadow_root_locs_def delete_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+end
+
+locale l_delete_shadow_root_get_shadow_root = l_get_shadow_root_defs +
+ assumes get_shadow_root_delete_shadow_root: "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_shadow_root_locs ptr' \<Longrightarrow> r h h'"
+interpretation l_delete_shadow_root_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ by(auto simp add: l_delete_shadow_root_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+
+lemma l_delete_shadow_root_get_shadow_root_get_shadow_root_locs [instances]: "l_delete_shadow_root_get_shadow_root get_shadow_root_locs"
+ apply(auto simp add: l_delete_shadow_root_get_shadow_root_def)[1]
+ using get_shadow_root_delete_shadow_root apply fast
+ done
+
+
+
+paragraph \<open>new\_character\_data\<close>
+
+locale l_new_character_data_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_shadow_root_new_character_data:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_shadow_root_locs ptr' \<Longrightarrow> r h h'"
+ by (auto simp add: get_shadow_root_locs_def new_character_data_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t new_character_data_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ split: prod.splits if_splits option.splits
+ elim!: bind_returns_result_E bind_returns_heap_E intro: is_element_ptr_kind_obtains)
+end
+
+locale l_new_character_data_get_shadow_root = l_new_character_data + l_get_shadow_root +
+ assumes get_shadow_root_new_character_data:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr
+ \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_shadow_root_locs ptr' \<Longrightarrow> r h h'"
+
+
+interpretation i_new_character_data_get_shadow_root?:
+ l_new_character_data_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ by(unfold_locales)
+declare l_new_character_data_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma new_character_data_get_shadow_root_is_l_new_character_data_get_shadow_root [instances]:
+ "l_new_character_data_get_shadow_root type_wf get_shadow_root get_shadow_root_locs"
+ using new_character_data_is_l_new_character_data get_shadow_root_is_l_get_shadow_root
+ apply(auto simp add: l_new_character_data_get_shadow_root_def
+ l_new_character_data_get_shadow_root_axioms_def instances)[1]
+ using get_shadow_root_new_character_data
+ by fast
+
+
+
+
+
+
+paragraph \<open>new\_document\<close>
+
+locale l_new_document_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_shadow_root_new_document:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_shadow_root_locs ptr' \<Longrightarrow> r h h'"
+ by (auto simp add: get_shadow_root_locs_def new_document_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t new_document_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ split: prod.splits if_splits option.splits
+ elim!: bind_returns_result_E bind_returns_heap_E intro: is_element_ptr_kind_obtains)
+end
+
+locale l_new_document_get_shadow_root = l_new_document + l_get_shadow_root +
+ assumes get_shadow_root_new_document:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr
+ \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_shadow_root_locs ptr' \<Longrightarrow> r h h'"
+
+
+interpretation i_new_document_get_shadow_root?:
+ l_new_document_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ by(unfold_locales)
+declare l_new_document_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma new_document_get_shadow_root_is_l_new_document_get_shadow_root [instances]:
+ "l_new_document_get_shadow_root type_wf get_shadow_root get_shadow_root_locs"
+ using new_document_is_l_new_document get_shadow_root_is_l_get_shadow_root
+ apply(auto simp add: l_new_document_get_shadow_root_def l_new_document_get_shadow_root_axioms_def instances)[1]
+ using get_shadow_root_new_document
+ by fast
+
+
+
+
+paragraph \<open>new\_element\<close>
+
+locale l_new_element_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_shadow_root_new_element:
+ "ptr' \<noteq> new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_shadow_root_locs ptr' \<Longrightarrow> r h h'"
+ by (auto simp add: get_shadow_root_locs_def new_element_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t new_element_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ new_element_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t split: prod.splits if_splits option.splits
+ elim!: bind_returns_result_E bind_returns_heap_E intro: is_element_ptr_kind_obtains)
+
+lemma new_element_no_shadow_root:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_shadow_root new_element_ptr \<rightarrow>\<^sub>r None"
+ by(simp add: get_shadow_root_def new_element_shadow_root_opt)
+end
+
+locale l_new_element_get_shadow_root = l_new_element + l_get_shadow_root +
+ assumes get_shadow_root_new_element:
+ "ptr' \<noteq> new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr
+ \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_shadow_root_locs ptr' \<Longrightarrow> r h h'"
+ assumes new_element_no_shadow_root:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_shadow_root new_element_ptr \<rightarrow>\<^sub>r None"
+
+
+interpretation i_new_element_get_shadow_root?:
+ l_new_element_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ by(unfold_locales)
+declare l_new_element_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma new_element_get_shadow_root_is_l_new_element_get_shadow_root [instances]:
+ "l_new_element_get_shadow_root type_wf get_shadow_root get_shadow_root_locs"
+ using new_element_is_l_new_element get_shadow_root_is_l_get_shadow_root
+ apply(auto simp add: l_new_element_get_shadow_root_def l_new_element_get_shadow_root_axioms_def instances)[1]
+ using get_shadow_root_new_element new_element_no_shadow_root
+ by fast+
+
+paragraph \<open>new\_shadow\_root\<close>
+
+locale l_new_shadow_root_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_shadow_root_new_shadow_root:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_shadow_root_locs ptr' \<Longrightarrow> r h h'"
+ by (auto simp add: get_shadow_root_locs_def new_shadow_root_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t new_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ split: prod.splits if_splits option.splits
+ elim!: bind_returns_result_E bind_returns_heap_E intro: is_element_ptr_kind_obtains)
+end
+
+locale l_new_shadow_root_get_shadow_root = l_get_shadow_root +
+ assumes get_shadow_root_new_shadow_root:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
+ \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_shadow_root_locs ptr' \<Longrightarrow> r h h'"
+
+interpretation i_new_shadow_root_get_shadow_root?:
+ l_new_shadow_root_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ by(unfold_locales)
+declare l_new_shadow_root_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma new_shadow_root_get_shadow_root_is_l_new_shadow_root_get_shadow_root [instances]:
+ "l_new_shadow_root_get_shadow_root type_wf get_shadow_root get_shadow_root_locs"
+ using get_shadow_root_is_l_get_shadow_root
+ apply(auto simp add: l_new_shadow_root_get_shadow_root_def l_new_shadow_root_get_shadow_root_axioms_def instances)[1]
+ using get_shadow_root_new_shadow_root
+ by fast
+
+
+subsubsection \<open>set\_shadow\_root\<close>
+
+locale l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+definition a_set_shadow_root :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr option \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_set_shadow_root element_ptr = put_M element_ptr shadow_root_opt_update"
+
+definition a_set_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_, unit) dom_prog) set"
+ where
+ "a_set_shadow_root_locs element_ptr \<equiv> all_args (put_M element_ptr shadow_root_opt_update)"
+end
+
+global_interpretation l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ defines set_shadow_root = a_set_shadow_root
+ and set_shadow_root_locs = a_set_shadow_root_locs
+ .
+
+locale l_set_shadow_root_defs =
+ fixes set_shadow_root :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr option \<Rightarrow> (_, unit) dom_prog"
+ fixes set_shadow_root_locs :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog set"
+
+
+locale l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_set_shadow_root_defs set_shadow_root set_shadow_root_locs +
+ l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and set_shadow_root :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr option \<Rightarrow> (_, unit) dom_prog"
+ and set_shadow_root_locs :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog set" +
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+ assumes set_shadow_root_impl: "set_shadow_root = a_set_shadow_root"
+ assumes set_shadow_root_locs_impl: "set_shadow_root_locs = a_set_shadow_root_locs"
+begin
+lemmas set_shadow_root_def = set_shadow_root_impl[unfolded set_shadow_root_def a_set_shadow_root_def]
+lemmas set_shadow_root_locs_def = set_shadow_root_locs_impl[unfolded set_shadow_root_locs_def a_set_shadow_root_locs_def]
+
+lemma set_shadow_root_ok: "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (set_shadow_root element_ptr tag)"
+ apply(unfold type_wf_impl)
+ unfolding set_shadow_root_def using get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok
+ by (simp add: ShadowRootMonad.put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ok)
+
+lemma set_shadow_root_ptr_in_heap:
+ "h \<turnstile> ok (set_shadow_root element_ptr shadow_root) \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h"
+ by(simp add: set_shadow_root_def ElementMonad.put_M_ptr_in_heap)
+
+lemma set_shadow_root_writes: "writes (set_shadow_root_locs element_ptr) (set_shadow_root element_ptr tag) h h'"
+ by(auto simp add: set_shadow_root_def set_shadow_root_locs_def intro: writes_bind_pure)
+
+lemma set_shadow_root_pointers_preserved:
+ assumes "w \<in> set_shadow_root_locs element_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms(1) object_ptr_kinds_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: all_args_def set_shadow_root_locs_def split: if_splits)
+
+lemma set_shadow_root_types_preserved:
+ assumes "w \<in> set_shadow_root_locs element_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ apply(unfold type_wf_impl)
+ using assms(1) type_wf_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: all_args_def set_shadow_root_locs_def split: if_splits)
+end
+
+interpretation i_set_shadow_root?: l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_shadow_root set_shadow_root_locs
+ by (auto simp add: l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+locale l_set_shadow_root = l_type_wf +l_set_shadow_root_defs +
+ assumes set_shadow_root_writes:
+ "writes (set_shadow_root_locs element_ptr) (set_shadow_root element_ptr disc_nodes) h h'"
+ assumes set_shadow_root_ok:
+ "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (set_shadow_root element_ptr shadow_root)"
+ assumes set_shadow_root_ptr_in_heap:
+ "h \<turnstile> ok (set_shadow_root element_ptr shadow_root) \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h"
+ assumes set_shadow_root_pointers_preserved:
+ "w \<in> set_shadow_root_locs element_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> object_ptr_kinds h = object_ptr_kinds h'"
+ assumes set_shadow_root_types_preserved:
+ "w \<in> set_shadow_root_locs element_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+
+lemma set_shadow_root_is_l_set_shadow_root [instances]: "l_set_shadow_root type_wf set_shadow_root set_shadow_root_locs"
+ apply(auto simp add: l_set_shadow_root_def instances)[1]
+ using set_shadow_root_writes apply blast
+ using set_shadow_root_ok apply (blast)
+ using set_shadow_root_ptr_in_heap apply blast
+ using set_shadow_root_pointers_preserved apply(blast, blast)
+ using set_shadow_root_types_preserved apply(blast, blast)
+ done
+
+paragraph \<open>get\_shadow\_root\<close>
+
+locale l_set_shadow_root_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_shadow_root_get_shadow_root:
+ "type_wf h \<Longrightarrow> h \<turnstile> set_shadow_root ptr shadow_root_ptr_opt \<rightarrow>\<^sub>h h' \<Longrightarrow>
+h' \<turnstile> get_shadow_root ptr \<rightarrow>\<^sub>r shadow_root_ptr_opt"
+ by(auto simp add: set_shadow_root_def get_shadow_root_def)
+
+lemma set_shadow_root_get_shadow_root_different_pointers:
+ "ptr \<noteq> ptr' \<Longrightarrow> \<forall>w \<in> set_shadow_root_locs ptr.
+(h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+ by(auto simp add: set_shadow_root_locs_def get_shadow_root_locs_def all_args_def)
+end
+
+interpretation
+ i_set_shadow_root_get_shadow_root?: l_set_shadow_root_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ set_shadow_root set_shadow_root_locs get_shadow_root get_shadow_root_locs
+ apply(auto simp add: l_set_shadow_root_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)[1]
+ by(unfold_locales)
+declare l_set_shadow_root_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+locale l_set_shadow_root_get_shadow_root = l_type_wf + l_set_shadow_root_defs + l_get_shadow_root_defs +
+ assumes set_shadow_root_get_shadow_root:
+ "type_wf h \<Longrightarrow> h \<turnstile> set_shadow_root ptr shadow_root_ptr_opt \<rightarrow>\<^sub>h h' \<Longrightarrow>
+h' \<turnstile> get_shadow_root ptr \<rightarrow>\<^sub>r shadow_root_ptr_opt"
+ assumes set_shadow_root_get_shadow_root_different_pointers:
+ "ptr \<noteq> ptr' \<Longrightarrow> w \<in> set_shadow_root_locs ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_shadow_root_locs ptr' \<Longrightarrow>
+r h h'"
+
+lemma set_shadow_root_get_shadow_root_is_l_set_shadow_root_get_shadow_root [instances]:
+ "l_set_shadow_root_get_shadow_root type_wf set_shadow_root set_shadow_root_locs get_shadow_root
+get_shadow_root_locs"
+ apply(auto simp add: l_set_shadow_root_get_shadow_root_def instances)[1]
+ using set_shadow_root_get_shadow_root apply fast
+ using set_shadow_root_get_shadow_root_different_pointers apply fast
+ done
+
+
+subsubsection \<open>set\_mode\<close>
+
+locale l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+definition a_set_mode :: "(_) shadow_root_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_set_mode shadow_root_ptr = put_M shadow_root_ptr mode_update"
+
+definition a_set_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> ((_, unit) dom_prog) set"
+ where
+ "a_set_mode_locs shadow_root_ptr \<equiv> all_args (put_M shadow_root_ptr mode_update)"
+end
+
+global_interpretation l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ defines set_mode = a_set_mode
+ and set_mode_locs = a_set_mode_locs
+ .
+
+locale l_set_mode_defs =
+ fixes set_mode :: "(_) shadow_root_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> (_, unit) dom_prog"
+ fixes set_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> (_, unit) dom_prog set"
+
+
+locale l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_type_wf type_wf +
+ l_set_mode_defs set_mode set_mode_locs +
+ l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and set_mode :: "(_) shadow_root_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> (_, unit) dom_prog"
+ and set_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> (_, unit) dom_prog set" +
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+ assumes set_mode_impl: "set_mode = a_set_mode"
+ assumes set_mode_locs_impl: "set_mode_locs = a_set_mode_locs"
+begin
+lemmas set_mode_def = set_mode_impl[unfolded set_mode_def a_set_mode_def]
+lemmas set_mode_locs_def = set_mode_locs_impl[unfolded set_mode_locs_def a_set_mode_locs_def]
+
+lemma set_mode_ok: "type_wf h \<Longrightarrow> shadow_root_ptr |\<in>| shadow_root_ptr_kinds h \<Longrightarrow>
+h \<turnstile> ok (set_mode shadow_root_ptr shadow_root_mode)"
+ apply(unfold type_wf_impl)
+ unfolding set_mode_def using get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok
+ by (simp add: ShadowRootMonad.put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok)
+
+lemma set_mode_ptr_in_heap:
+ "h \<turnstile> ok (set_mode shadow_root_ptr shadow_root_mode) \<Longrightarrow> shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ by(simp add: set_mode_def put_M_ptr_in_heap)
+
+lemma set_mode_writes: "writes (set_mode_locs shadow_root_ptr) (set_mode shadow_root_ptr shadow_root_mode) h h'"
+ by(auto simp add: set_mode_def set_mode_locs_def intro: writes_bind_pure)
+
+lemma set_mode_pointers_preserved:
+ assumes "w \<in> set_mode_locs element_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms(1) object_ptr_kinds_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: all_args_def set_mode_locs_def split: if_splits)
+
+lemma set_mode_types_preserved:
+ assumes "w \<in> set_mode_locs element_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ apply(unfold type_wf_impl)
+ using assms(1) type_wf_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: all_args_def set_mode_locs_def split: if_splits)
+end
+
+interpretation i_set_mode?: l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_mode set_mode_locs
+ by (auto simp add: l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+locale l_set_mode = l_type_wf +l_set_mode_defs +
+ assumes set_mode_writes:
+ "writes (set_mode_locs shadow_root_ptr) (set_mode shadow_root_ptr shadow_root_mode) h h'"
+ assumes set_mode_ok:
+ "type_wf h \<Longrightarrow> shadow_root_ptr |\<in>| shadow_root_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (set_mode shadow_root_ptr shadow_root_mode)"
+ assumes set_mode_ptr_in_heap:
+ "h \<turnstile> ok (set_mode shadow_root_ptr shadow_root_mode) \<Longrightarrow> shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ assumes set_mode_pointers_preserved:
+ "w \<in> set_mode_locs shadow_root_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> object_ptr_kinds h = object_ptr_kinds h'"
+ assumes set_mode_types_preserved:
+ "w \<in> set_mode_locs shadow_root_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+
+lemma set_mode_is_l_set_mode [instances]: "l_set_mode type_wf set_mode set_mode_locs"
+ apply(auto simp add: l_set_mode_def instances)[1]
+ using set_mode_writes apply blast
+ using set_mode_ok apply (blast)
+ using set_mode_ptr_in_heap apply blast
+ using set_mode_pointers_preserved apply(blast, blast)
+ using set_mode_types_preserved apply(blast, blast)
+ done
+
+
+paragraph \<open>get\_child\_nodes\<close>
+
+locale l_set_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_shadow_root_get_child_nodes:
+ "\<forall>w \<in> set_shadow_root_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+ by(auto simp add: get_child_nodes_locs_def set_shadow_root_locs_def CD.get_child_nodes_locs_def
+ all_args_def intro: element_put_get_preserved[where setter=shadow_root_opt_update])
+end
+
+interpretation i_set_shadow_root_get_child_nodes?:
+ l_set_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr DocumentClass.type_wf
+ DocumentClass.known_ptr get_child_nodes get_child_nodes_locs Core_DOM_Functions.get_child_nodes
+ Core_DOM_Functions.get_child_nodes_locs set_shadow_root set_shadow_root_locs
+ by(unfold_locales)
+declare l_set_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+locale l_set_shadow_root_get_child_nodes = l_set_shadow_root + l_get_child_nodes +
+ assumes set_shadow_root_get_child_nodes:
+ "\<forall>w \<in> set_shadow_root_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+
+lemma set_shadow_root_get_child_nodes_is_l_set_shadow_root_get_child_nodes [instances]:
+ "l_set_shadow_root_get_child_nodes type_wf set_shadow_root set_shadow_root_locs known_ptr
+get_child_nodes get_child_nodes_locs"
+ apply(auto simp add: l_set_shadow_root_get_child_nodes_def l_set_shadow_root_get_child_nodes_axioms_def
+ instances)[1]
+ using set_shadow_root_get_child_nodes apply blast
+ done
+
+paragraph \<open>get\_shadow\_root\<close>
+
+locale l_set_mode_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_mode_get_shadow_root:
+ "\<forall>w \<in> set_mode_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+ by(auto simp add: set_mode_locs_def get_shadow_root_locs_def all_args_def)
+end
+
+interpretation
+ i_set_mode_get_shadow_root?: l_set_mode_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ set_mode set_mode_locs get_shadow_root
+ get_shadow_root_locs
+ by unfold_locales
+declare l_set_mode_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+locale l_set_mode_get_shadow_root = l_set_mode + l_get_shadow_root +
+ assumes set_mode_get_shadow_root:
+ "\<forall>w \<in> set_mode_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+
+lemma set_mode_get_shadow_root_is_l_set_mode_get_shadow_root [instances]:
+ "l_set_mode_get_shadow_root type_wf set_mode set_mode_locs get_shadow_root
+ get_shadow_root_locs"
+ using set_mode_is_l_set_mode get_shadow_root_is_l_get_shadow_root
+ apply(simp add: l_set_mode_get_shadow_root_def
+ l_set_mode_get_shadow_root_axioms_def)
+ using set_mode_get_shadow_root
+ by fast
+
+paragraph \<open>get\_child\_nodes\<close>
+
+locale l_set_mode_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_mode_get_child_nodes:
+ "\<forall>w \<in> set_mode_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+ by(auto simp add: get_child_nodes_locs_def CD.get_child_nodes_locs_def set_mode_locs_def all_args_def)[1]
+end
+
+interpretation
+ i_set_mode_get_child_nodes?: l_set_mode_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_mode set_mode_locs known_ptr DocumentClass.type_wf
+ DocumentClass.known_ptr get_child_nodes
+ get_child_nodes_locs Core_DOM_Functions.get_child_nodes
+ Core_DOM_Functions.get_child_nodes_locs
+ by unfold_locales
+declare l_set_mode_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+locale l_set_mode_get_child_nodes = l_set_mode + l_get_child_nodes +
+ assumes set_mode_get_child_nodes:
+ "\<forall>w \<in> set_mode_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+
+lemma set_mode_get_child_nodes_is_l_set_mode_get_child_nodes [instances]:
+ "l_set_mode_get_child_nodes type_wf set_mode set_mode_locs known_ptr get_child_nodes
+ get_child_nodes_locs"
+ using set_mode_is_l_set_mode get_child_nodes_is_l_get_child_nodes
+ apply(simp add: l_set_mode_get_child_nodes_def
+ l_set_mode_get_child_nodes_axioms_def)
+ using set_mode_get_child_nodes
+ by fast
+
+
+subsubsection \<open>get\_host\<close>
+
+locale l_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_shadow_root_defs get_shadow_root get_shadow_root_locs
+ for get_shadow_root :: "(_::linorder) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+definition a_get_host :: "(_) shadow_root_ptr \<Rightarrow> (_, (_) element_ptr) dom_prog"
+ where
+ "a_get_host shadow_root_ptr = do {
+ host_ptrs \<leftarrow> element_ptr_kinds_M \<bind> filter_M (\<lambda>element_ptr. do {
+ shadow_root_opt \<leftarrow> get_shadow_root element_ptr;
+ return (shadow_root_opt = Some shadow_root_ptr)
+ });
+ (case host_ptrs of host_ptr#[] \<Rightarrow> return host_ptr | _ \<Rightarrow> error HierarchyRequestError)
+ }"
+definition "a_get_host_locs \<equiv> (\<Union>element_ptr. (get_shadow_root_locs element_ptr)) \<union>
+(\<Union>ptr. {preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr RObject.nothing)})"
+
+end
+
+global_interpretation l_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_shadow_root get_shadow_root_locs
+ defines get_host = "a_get_host"
+ and get_host_locs = "a_get_host_locs"
+ .
+
+locale l_get_host_defs =
+ fixes get_host :: "(_) shadow_root_ptr \<Rightarrow> (_, (_) element_ptr) dom_prog"
+ fixes get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_get_host_defs +
+ l_get_shadow_root +
+ assumes get_host_impl: "get_host = a_get_host"
+ assumes get_host_locs_impl: "get_host_locs = a_get_host_locs"
+begin
+lemmas get_host_def = get_host_impl[unfolded a_get_host_def]
+lemmas get_host_locs_def = get_host_locs_impl[unfolded a_get_host_locs_def]
+
+lemma get_host_pure [simp]: "pure (get_host element_ptr) h"
+ by(auto simp add: get_host_def intro!: bind_pure_I filter_M_pure_I split: list.splits)
+
+lemma get_host_reads: "reads get_host_locs (get_host element_ptr) h h'"
+ using get_shadow_root_reads[unfolded reads_def]
+ by(auto simp add: get_host_def get_host_locs_def intro!: reads_bind_pure
+ reads_subset[OF check_in_heap_reads] reads_subset[OF error_reads] reads_subset[OF get_shadow_root_reads]
+ reads_subset[OF return_reads] reads_subset[OF element_ptr_kinds_M_reads] filter_M_reads filter_M_pure_I
+ bind_pure_I split: list.splits)
+end
+
+locale l_get_host = l_get_host_defs +
+ assumes get_host_pure [simp]: "pure (get_host element_ptr) h"
+ assumes get_host_reads: "reads get_host_locs (get_host node_ptr) h h'"
+
+
+interpretation i_get_host?: l_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_shadow_root get_shadow_root_locs get_host
+ get_host_locs type_wf
+ using instances
+ by (simp add: l_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def get_host_def get_host_locs_def)
+declare l_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_host_is_l_get_host [instances]: "l_get_host get_host get_host_locs"
+ apply(auto simp add: l_get_host_def)[1]
+ using get_host_reads apply fast
+ done
+
+
+
+subsubsection \<open>get\_mode\<close>
+
+locale l_get_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+begin
+definition a_get_mode :: "(_) shadow_root_ptr \<Rightarrow> (_, shadow_root_mode) dom_prog"
+ where
+ "a_get_mode shadow_root_ptr = get_M shadow_root_ptr mode"
+
+definition a_get_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ where
+ "a_get_mode_locs shadow_root_ptr \<equiv> {preserved (get_M shadow_root_ptr mode)}"
+end
+
+global_interpretation l_get_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ defines get_mode = a_get_mode
+ and get_mode_locs = a_get_mode_locs
+ .
+
+locale l_get_mode_defs =
+ fixes get_mode :: "(_) shadow_root_ptr \<Rightarrow> (_, shadow_root_mode) dom_prog"
+ fixes get_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_get_mode_defs get_mode get_mode_locs +
+ l_type_wf type_wf
+ for get_mode :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, shadow_root_mode) prog"
+ and get_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and type_wf :: "(_) heap \<Rightarrow> bool" +
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+ assumes get_mode_impl: "get_mode = a_get_mode"
+ assumes get_mode_locs_impl: "get_mode_locs = a_get_mode_locs"
+begin
+lemmas get_mode_def = get_mode_impl[unfolded get_mode_def a_get_mode_def]
+lemmas get_mode_locs_def = get_mode_locs_impl[unfolded get_mode_locs_def a_get_mode_locs_def]
+
+lemma get_mode_ok: "type_wf h \<Longrightarrow> shadow_root_ptr |\<in>| shadow_root_ptr_kinds h \<Longrightarrow>
+h \<turnstile> ok (get_mode shadow_root_ptr)"
+ unfolding get_mode_def type_wf_impl
+ using ShadowRootMonad.get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok by blast
+
+lemma get_mode_pure [simp]: "pure (get_mode element_ptr) h"
+ unfolding get_mode_def by simp
+
+lemma get_mode_ptr_in_heap:
+ assumes "h \<turnstile> get_mode shadow_root_ptr \<rightarrow>\<^sub>r children"
+ shows "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ using assms
+ by(auto simp add: get_mode_def get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_in_heap dest: is_OK_returns_result_I)
+
+lemma get_mode_reads: "reads (get_mode_locs element_ptr) (get_mode element_ptr) h h'"
+ by(simp add: get_mode_def get_mode_locs_def reads_bind_pure reads_insert_writes_set_right)
+end
+
+interpretation i_get_mode?: l_get_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_mode get_mode_locs type_wf
+ using instances
+ by (auto simp add: l_get_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_get_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+locale l_get_mode = l_type_wf + l_get_mode_defs +
+ assumes get_mode_reads: "reads (get_mode_locs shadow_root_ptr) (get_mode shadow_root_ptr) h h'"
+ assumes get_mode_ok: "type_wf h \<Longrightarrow> shadow_root_ptr |\<in>| shadow_root_ptr_kinds h \<Longrightarrow>
+h \<turnstile> ok (get_mode shadow_root_ptr)"
+ assumes get_mode_ptr_in_heap: "h \<turnstile> ok (get_mode shadow_root_ptr) \<Longrightarrow> shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ assumes get_mode_pure [simp]: "pure (get_mode shadow_root_ptr) h"
+
+lemma get_mode_is_l_get_mode [instances]: "l_get_mode type_wf get_mode get_mode_locs"
+ apply(auto simp add: l_get_mode_def instances)[1]
+ using get_mode_reads apply blast
+ using get_mode_ok apply blast
+ using get_mode_ptr_in_heap apply blast
+ done
+
+
+
+subsubsection \<open>get\_shadow\_root\_safe\<close>
+
+locale l_get_shadow_root_safe\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_shadow_root_defs get_shadow_root get_shadow_root_locs +
+ l_get_mode_defs get_mode get_mode_locs
+ for get_shadow_root :: "(_) element_ptr \<Rightarrow> (_, (_) shadow_root_ptr option) dom_prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_mode :: "(_) shadow_root_ptr \<Rightarrow> (_, shadow_root_mode) dom_prog"
+ and get_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+definition a_get_shadow_root_safe :: "(_) element_ptr \<Rightarrow> (_, (_) shadow_root_ptr option) dom_prog"
+ where
+ "a_get_shadow_root_safe element_ptr = do {
+ shadow_root_ptr_opt \<leftarrow> get_shadow_root element_ptr;
+ (case shadow_root_ptr_opt of
+ Some shadow_root_ptr \<Rightarrow> do {
+ mode \<leftarrow> get_mode shadow_root_ptr;
+ (if mode = Open then
+ return (Some shadow_root_ptr)
+ else
+ return None
+ )
+ } | None \<Rightarrow> return None)
+ }"
+
+definition a_get_shadow_root_safe_locs ::
+ "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ where
+ "a_get_shadow_root_safe_locs element_ptr shadow_root_ptr \<equiv>
+(get_shadow_root_locs element_ptr) \<union> (get_mode_locs shadow_root_ptr)"
+end
+
+global_interpretation l_get_shadow_root_safe\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_shadow_root get_shadow_root_locs get_mode get_mode_locs
+ defines get_shadow_root_safe = a_get_shadow_root_safe
+ and get_shadow_root_safe_locs = a_get_shadow_root_safe_locs
+ .
+
+locale l_get_shadow_root_safe_defs =
+ fixes get_shadow_root_safe :: "(_) element_ptr \<Rightarrow> (_, (_) shadow_root_ptr option) dom_prog"
+ fixes get_shadow_root_safe_locs ::
+ "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_shadow_root_safe\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_shadow_root_safe\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_shadow_root get_shadow_root_locs get_mode get_mode_locs +
+ l_get_shadow_root_safe_defs get_shadow_root_safe get_shadow_root_safe_locs +
+ l_get_shadow_root type_wf get_shadow_root get_shadow_root_locs +
+ l_get_mode type_wf get_mode get_mode_locs +
+ l_type_wf type_wf
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_shadow_root_safe :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_safe_locs :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> (_, (_) shadow_root_ptr option) dom_prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_mode :: "(_) shadow_root_ptr \<Rightarrow> (_, shadow_root_mode) dom_prog"
+ and get_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+ assumes get_shadow_root_safe_impl: "get_shadow_root_safe = a_get_shadow_root_safe"
+ assumes get_shadow_root_safe_locs_impl: "get_shadow_root_safe_locs = a_get_shadow_root_safe_locs"
+begin
+lemmas get_shadow_root_safe_def = get_shadow_root_safe_impl[unfolded get_shadow_root_safe_def
+ a_get_shadow_root_safe_def]
+lemmas get_shadow_root_safe_locs_def = get_shadow_root_safe_locs_impl[unfolded get_shadow_root_safe_locs_def
+ a_get_shadow_root_safe_locs_def]
+
+lemma get_shadow_root_safe_pure [simp]: "pure (get_shadow_root_safe element_ptr) h"
+ apply(auto simp add: get_shadow_root_safe_def)[1]
+ by (smt bind_returns_heap_E is_OK_returns_heap_E local.get_mode_pure local.get_shadow_root_pure
+ option.case_eq_if pure_def pure_returns_heap_eq return_pure)
+end
+
+interpretation i_get_shadow_root_safe?: l_get_shadow_root_safe\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root_safe
+ get_shadow_root_safe_locs get_shadow_root get_shadow_root_locs get_mode get_mode_locs
+ using instances
+ by (auto simp add: l_get_shadow_root_safe\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_shadow_root_safe\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ get_shadow_root_safe_def get_shadow_root_safe_locs_def)
+declare l_get_shadow_root_safe\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+locale l_get_shadow_root_safe = l_get_shadow_root_safe_defs +
+ assumes get_shadow_root_safe_pure [simp]: "pure (get_shadow_root_safe element_ptr) h"
+
+lemma get_shadow_root_safe_is_l_get_shadow_root_safe [instances]: "l_get_shadow_root_safe get_shadow_root_safe"
+ using instances
+ apply(auto simp add: l_get_shadow_root_safe_def)[1]
+ done
+
+
+subsubsection \<open>set\_disconnected\_nodes\<close>
+
+locale l_set_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ CD: l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_disconnected_nodes set_disconnected_nodes_locs +
+ l_type_wf type_wf
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set" +
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+begin
+lemma set_disconnected_nodes_ok:
+ "type_wf h \<Longrightarrow> document_ptr |\<in>| document_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (set_disconnected_nodes document_ptr node_ptrs)"
+ using CD.set_disconnected_nodes_ok CD.type_wf_impl ShadowRootClass.type_wf_defs local.type_wf_impl
+ by blast
+
+lemma set_disconnected_nodes_typess_preserved:
+ assumes "w \<in> set_disconnected_nodes_locs object_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ using assms(1) type_wf_preserved[OF writes_singleton2 assms(2)]
+ apply(unfold type_wf_impl)
+ by(auto simp add: all_args_def CD.set_disconnected_nodes_locs_def
+ intro: put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_disconnected_nodes_type_wf_preserved split: if_splits)
+end
+
+interpretation i_set_disconnected_nodes?: l_set_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf
+ set_disconnected_nodes set_disconnected_nodes_locs
+ by(auto simp add: l_set_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_set_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_set_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma set_disconnected_nodes_is_l_set_disconnected_nodes [instances]:
+ "l_set_disconnected_nodes type_wf set_disconnected_nodes set_disconnected_nodes_locs"
+ apply(auto simp add: l_set_disconnected_nodes_def)[1]
+ apply (simp add: i_set_disconnected_nodes.set_disconnected_nodes_writes)
+ using set_disconnected_nodes_ok apply blast
+ apply (simp add: i_set_disconnected_nodes.set_disconnected_nodes_ptr_in_heap)
+ using i_set_disconnected_nodes.set_disconnected_nodes_pointers_preserved apply (blast, blast)
+ using set_disconnected_nodes_typess_preserved apply(blast, blast)
+ done
+
+
+paragraph \<open>get\_child\_nodes\<close>
+
+locale l_set_disconnected_nodes_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_disconnected_nodes set_disconnected_nodes_locs +
+ l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes
+ get_child_nodes_locs get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+
+lemma set_disconnected_nodes_get_child_nodes:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_child_nodes_locs ptr'. r h h'))"
+ by(auto simp add: set_disconnected_nodes_locs_def get_child_nodes_locs_def CD.get_child_nodes_locs_def
+ all_args_def)
+end
+
+interpretation i_set_disconnected_nodes_get_child_nodes?: l_set_disconnected_nodes_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf set_disconnected_nodes set_disconnected_nodes_locs known_ptr DocumentClass.type_wf
+ DocumentClass.known_ptr get_child_nodes get_child_nodes_locs Core_DOM_Functions.get_child_nodes
+ Core_DOM_Functions.get_child_nodes_locs
+ by(auto simp add: l_set_disconnected_nodes_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_set_disconnected_nodes_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_disconnected_nodes_get_child_nodes_is_l_set_disconnected_nodes_get_child_nodes [instances]:
+ "l_set_disconnected_nodes_get_child_nodes set_disconnected_nodes_locs get_child_nodes_locs"
+ apply(auto simp add: l_set_disconnected_nodes_get_child_nodes_def)[1]
+ using set_disconnected_nodes_get_child_nodes apply fast
+ done
+
+
+paragraph \<open>get\_host\<close>
+
+locale l_set_disconnected_nodes_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_disconnected_nodes_get_host:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_host_locs. r h h'))"
+ by(auto simp add: CD.set_disconnected_nodes_locs_def get_shadow_root_locs_def get_host_locs_def all_args_def)
+end
+
+interpretation i_set_disconnected_nodes_get_host?: l_set_disconnected_nodes_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf DocumentClass.type_wf set_disconnected_nodes set_disconnected_nodes_locs get_shadow_root
+ get_shadow_root_locs get_host get_host_locs
+ by(auto simp add: l_set_disconnected_nodes_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_set_disconnected_nodes_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+locale l_set_disconnected_nodes_get_host = l_set_disconnected_nodes_defs + l_get_host_defs +
+ assumes set_disconnected_nodes_get_host:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_host_locs. r h h'))"
+
+lemma set_disconnected_nodes_get_host_is_l_set_disconnected_nodes_get_host [instances]:
+ "l_set_disconnected_nodes_get_host set_disconnected_nodes_locs get_host_locs"
+ apply(auto simp add: l_set_disconnected_nodes_get_host_def instances)[1]
+ using set_disconnected_nodes_get_host
+ by fast
+
+
+
+subsubsection \<open>get\_tag\_name\<close>
+
+locale l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ CD: l_get_tag_name\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_tag_name get_tag_name_locs +
+ l_type_wf type_wf
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> (_, tag_name) dom_prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+begin
+
+lemma get_tag_name_ok:
+ "type_wf h \<Longrightarrow> element_ptr |\<in>| element_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_tag_name element_ptr)"
+ apply(unfold type_wf_impl get_tag_name_impl[unfolded a_get_tag_name_def])
+ using CD.get_tag_name_ok CD.type_wf_impl ShadowRootClass.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ by blast
+end
+
+interpretation i_get_tag_name?: l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf get_tag_name get_tag_name_locs
+ by(auto simp add: l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_tag_name_is_l_get_tag_name [instances]: "l_get_tag_name type_wf get_tag_name get_tag_name_locs"
+ apply(auto simp add: l_get_tag_name_def)[1]
+ using get_tag_name_reads apply fast
+ using get_tag_name_ok apply fast
+ done
+
+
+paragraph \<open>set\_disconnected\_nodes\<close>
+
+locale l_set_disconnected_nodes_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_disconnected_nodes_get_tag_name:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_tag_name_locs ptr'. r h h'))"
+ by(auto simp add: CD.set_disconnected_nodes_locs_def CD.get_tag_name_locs_def all_args_def)
+end
+
+interpretation i_set_disconnected_nodes_get_tag_name?: l_set_disconnected_nodes_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf DocumentClass.type_wf set_disconnected_nodes set_disconnected_nodes_locs get_tag_name
+ get_tag_name_locs
+ by(auto simp add: l_set_disconnected_nodes_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_set_disconnected_nodes_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma set_disconnected_nodes_get_tag_name_is_l_set_disconnected_nodes_get_tag_name [instances]:
+ "l_set_disconnected_nodes_get_tag_name type_wf set_disconnected_nodes set_disconnected_nodes_locs
+get_tag_name get_tag_name_locs"
+ apply(auto simp add: l_set_disconnected_nodes_get_tag_name_def
+ l_set_disconnected_nodes_get_tag_name_axioms_def instances)[1]
+ using set_disconnected_nodes_get_tag_name
+ by fast
+
+
+paragraph \<open>set\_child\_nodes\<close>
+
+locale l_set_child_nodes_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_child_nodes_get_tag_name:
+ "\<forall>w \<in> set_child_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_tag_name_locs ptr'. r h h'))"
+ by(auto simp add: CD.set_child_nodes_locs_def set_child_nodes_locs_def CD.get_tag_name_locs_def
+ all_args_def intro: element_put_get_preserved[where getter=tag_name and setter=RElement.child_nodes_update])
+end
+
+interpretation i_set_child_nodes_get_tag_name?: l_set_child_nodes_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr
+ DocumentClass.type_wf DocumentClass.known_ptr set_child_nodes set_child_nodes_locs
+ Core_DOM_Functions.set_child_nodes Core_DOM_Functions.set_child_nodes_locs get_tag_name get_tag_name_locs
+ by(auto simp add: l_set_child_nodes_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_set_child_nodes_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma set_child_nodes_get_tag_name_is_l_set_child_nodes_get_tag_name [instances]:
+ "l_set_child_nodes_get_tag_name type_wf set_child_nodes set_child_nodes_locs get_tag_name get_tag_name_locs"
+ apply(auto simp add: l_set_child_nodes_get_tag_name_def l_set_child_nodes_get_tag_name_axioms_def instances)[1]
+ using set_child_nodes_get_tag_name
+ by fast
+
+
+paragraph \<open>delete\_shadow\_root\<close>
+
+locale l_delete_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma get_tag_name_delete_shadow_root: "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_tag_name_locs ptr' \<Longrightarrow> r h h'"
+ by(auto simp add: CD.get_tag_name_locs_def delete_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+end
+
+locale l_delete_shadow_root_get_tag_name = l_get_tag_name_defs +
+ assumes get_tag_name_delete_shadow_root: "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_tag_name_locs ptr' \<Longrightarrow> r h h'"
+interpretation l_delete_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf get_tag_name
+ get_tag_name_locs
+ by(auto simp add: l_delete_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+
+lemma l_delete_shadow_root_get_tag_name_get_tag_name_locs [instances]: "l_delete_shadow_root_get_tag_name get_tag_name_locs"
+ apply(auto simp add: l_delete_shadow_root_get_tag_name_def)[1]
+ using get_tag_name_delete_shadow_root apply fast
+ done
+
+
+paragraph \<open>set\_shadow\_root\<close>
+
+locale l_set_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_shadow_root_get_tag_name:
+ "\<forall>w \<in> set_shadow_root_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_tag_name_locs ptr'. r h h'))"
+ by(auto simp add: set_shadow_root_locs_def CD.get_tag_name_locs_def all_args_def element_put_get_preserved[where setter=shadow_root_opt_update])
+end
+
+interpretation
+ i_set_shadow_root_get_tag_name?: l_set_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_shadow_root
+ set_shadow_root_locs DocumentClass.type_wf get_tag_name get_tag_name_locs
+ apply(auto simp add: l_set_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)[1]
+ by(unfold_locales)
+declare l_set_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+locale l_set_shadow_root_get_tag_name = l_set_shadow_root_defs + l_get_tag_name_defs +
+ assumes set_shadow_root_get_tag_name: "\<forall>w \<in> set_shadow_root_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_tag_name_locs ptr'. r h h'))"
+
+lemma set_shadow_root_get_tag_name_is_l_set_shadow_root_get_tag_name [instances]:
+ "l_set_shadow_root_get_tag_name set_shadow_root_locs get_tag_name_locs"
+ using set_shadow_root_is_l_set_shadow_root get_tag_name_is_l_get_tag_name
+ apply(simp add: l_set_shadow_root_get_tag_name_def )
+ using set_shadow_root_get_tag_name
+ by fast
+
+
+
+paragraph \<open>new\_element\<close>
+
+locale l_new_element_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_tag_name get_tag_name_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> (_, tag_name) dom_prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_tag_name_new_element:
+ "ptr' \<noteq> new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_tag_name_locs ptr' \<Longrightarrow> r h h'"
+ by (auto simp add: CD.get_tag_name_locs_def new_element_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t new_element_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ new_element_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t split: prod.splits if_splits option.splits
+ elim!: bind_returns_result_E bind_returns_heap_E intro: is_element_ptr_kind_obtains)
+
+lemma new_element_empty_tag_name:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_tag_name new_element_ptr \<rightarrow>\<^sub>r ''''"
+ by(simp add: CD.get_tag_name_def new_element_tag_name)
+end
+
+locale l_new_element_get_tag_name = l_new_element + l_get_tag_name +
+ assumes get_tag_name_new_element:
+ "ptr' \<noteq> new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr
+ \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_tag_name_locs ptr' \<Longrightarrow> r h h'"
+ assumes new_element_empty_tag_name:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr \<Longrightarrow> h \<turnstile> new_element \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_tag_name new_element_ptr \<rightarrow>\<^sub>r ''''"
+
+
+interpretation i_new_element_get_tag_name?:
+ l_new_element_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf get_tag_name get_tag_name_locs
+ by(auto simp add: l_new_element_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_new_element_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma new_element_get_tag_name_is_l_new_element_get_tag_name [instances]:
+ "l_new_element_get_tag_name type_wf get_tag_name get_tag_name_locs"
+ using new_element_is_l_new_element get_tag_name_is_l_get_tag_name
+ apply(auto simp add: l_new_element_get_tag_name_def l_new_element_get_tag_name_axioms_def instances)[1]
+ using get_tag_name_new_element new_element_empty_tag_name
+ by fast+
+
+paragraph \<open>get\_shadow\_root\<close>
+
+locale l_set_mode_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_mode_get_tag_name:
+ "\<forall>w \<in> set_mode_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_tag_name_locs ptr'. r h h'))"
+ by(auto simp add: set_mode_locs_def CD.get_tag_name_locs_def all_args_def)
+end
+
+interpretation
+ i_set_mode_get_tag_name?: l_set_mode_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ set_mode set_mode_locs DocumentClass.type_wf get_tag_name
+ get_tag_name_locs
+ by unfold_locales
+declare l_set_mode_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+locale l_set_mode_get_tag_name = l_set_mode + l_get_tag_name +
+ assumes set_mode_get_tag_name:
+ "\<forall>w \<in> set_mode_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_tag_name_locs ptr'. r h h'))"
+
+lemma set_mode_get_tag_name_is_l_set_mode_get_tag_name [instances]:
+ "l_set_mode_get_tag_name type_wf set_mode set_mode_locs get_tag_name
+ get_tag_name_locs"
+ using set_mode_is_l_set_mode get_tag_name_is_l_get_tag_name
+ apply(simp add: l_set_mode_get_tag_name_def
+ l_set_mode_get_tag_name_axioms_def)
+ using set_mode_get_tag_name
+ by fast
+
+paragraph \<open>new\_document\<close>
+
+locale l_new_document_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_tag_name get_tag_name_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, tag_name) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_tag_name_new_document:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_tag_name_locs ptr' \<Longrightarrow> r h h'"
+ by(auto simp add: CD.get_tag_name_locs_def new_document_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+end
+
+locale l_new_document_get_tag_name = l_get_tag_name_defs +
+ assumes get_tag_name_new_document:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_tag_name_locs ptr' \<Longrightarrow> r h h'"
+
+interpretation i_new_document_get_tag_name?:
+ l_new_document_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf get_tag_name
+ get_tag_name_locs
+ by unfold_locales
+declare l_new_document_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def[instances]
+
+lemma new_document_get_tag_name_is_l_new_document_get_tag_name [instances]:
+ "l_new_document_get_tag_name get_tag_name_locs"
+ unfolding l_new_document_get_tag_name_def
+ unfolding get_tag_name_locs_def
+ using new_document_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t by blast
+
+paragraph \<open>new\_shadow\_root\<close>
+
+locale l_new_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma get_tag_name_new_shadow_root:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_tag_name_locs ptr' \<Longrightarrow> r h h'"
+ by (auto simp add: CD.get_tag_name_locs_def new_shadow_root_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t new_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ split: prod.splits if_splits option.splits
+ elim!: bind_returns_result_E bind_returns_heap_E intro: is_element_ptr_kind_obtains)
+end
+
+locale l_new_shadow_root_get_tag_name = l_get_tag_name +
+ assumes get_tag_name_new_shadow_root:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
+ \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_tag_name_locs ptr' \<Longrightarrow> r h h'"
+
+interpretation i_new_shadow_root_get_tag_name?:
+ l_new_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf get_tag_name get_tag_name_locs
+ by(unfold_locales)
+declare l_new_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma new_shadow_root_get_tag_name_is_l_new_shadow_root_get_tag_name [instances]:
+ "l_new_shadow_root_get_tag_name type_wf get_tag_name get_tag_name_locs"
+ using get_tag_name_is_l_get_tag_name
+ apply(auto simp add: l_new_shadow_root_get_tag_name_def l_new_shadow_root_get_tag_name_axioms_def instances)[1]
+ using get_tag_name_new_shadow_root
+ by fast
+
+paragraph \<open>new\_character\_data\<close>
+
+locale l_new_character_data_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_tag_name get_tag_name_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, tag_name) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_tag_name_new_character_data:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_tag_name_locs ptr' \<Longrightarrow> r h h'"
+ by(auto simp add: CD.get_tag_name_locs_def new_character_data_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+end
+
+locale l_new_character_data_get_tag_name = l_get_tag_name_defs +
+ assumes get_tag_name_new_character_data:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr \<Longrightarrow> h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_tag_name_locs ptr' \<Longrightarrow> r h h'"
+
+interpretation i_new_character_data_get_tag_name?:
+ l_new_character_data_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf get_tag_name
+ get_tag_name_locs
+ by unfold_locales
+declare l_new_character_data_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def[instances]
+
+lemma new_character_data_get_tag_name_is_l_new_character_data_get_tag_name [instances]:
+ "l_new_character_data_get_tag_name get_tag_name_locs"
+ unfolding l_new_character_data_get_tag_name_def
+ unfolding get_tag_name_locs_def
+ using new_character_data_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t by blast
+
+paragraph \<open>get\_tag\_type\<close>
+
+locale l_set_tag_name_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M = l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + l_set_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_tag_name_get_tag_name:
+ assumes "h \<turnstile> CD.a_set_tag_name element_ptr tag \<rightarrow>\<^sub>h h'"
+ shows "h' \<turnstile> CD.a_get_tag_name element_ptr \<rightarrow>\<^sub>r tag"
+ using assms
+ by(auto simp add: CD.a_get_tag_name_def CD.a_set_tag_name_def)
+
+lemma set_tag_name_get_tag_name_different_pointers:
+ assumes "ptr \<noteq> ptr'"
+ assumes "w \<in> CD.a_set_tag_name_locs ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ assumes "r \<in> CD.a_get_tag_name_locs ptr'"
+ shows "r h h'"
+ using assms
+ by(auto simp add: all_args_def CD.a_set_tag_name_locs_def CD.a_get_tag_name_locs_def
+ split: if_splits option.splits )
+end
+
+interpretation i_set_tag_name_get_tag_name?:
+ l_set_tag_name_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf get_tag_name
+ get_tag_name_locs set_tag_name set_tag_name_locs
+ by unfold_locales
+declare l_set_tag_name_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_tag_name_get_tag_name_is_l_set_tag_name_get_tag_name [instances]:
+ "l_set_tag_name_get_tag_name type_wf get_tag_name get_tag_name_locs
+ set_tag_name set_tag_name_locs"
+ using set_tag_name_is_l_set_tag_name get_tag_name_is_l_get_tag_name
+ apply(simp add: l_set_tag_name_get_tag_name_def
+ l_set_tag_name_get_tag_name_axioms_def)
+ using set_tag_name_get_tag_name
+ set_tag_name_get_tag_name_different_pointers
+ by fast+
+
+
+subsubsection \<open>attach\_shadow\_root\<close>
+
+locale l_attach_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_set_shadow_root_defs set_shadow_root set_shadow_root_locs +
+ l_set_mode_defs set_mode set_mode_locs +
+ l_get_tag_name_defs get_tag_name get_tag_name_locs +
+ l_get_shadow_root_defs get_shadow_root get_shadow_root_locs
+ for set_shadow_root :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr option \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_mode :: "(_) shadow_root_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> (_, char list) dom_prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+definition a_attach_shadow_root :: "(_) element_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> (_, (_) shadow_root_ptr) dom_prog"
+ where
+ "a_attach_shadow_root element_ptr shadow_root_mode = do {
+ tag \<leftarrow> get_tag_name element_ptr;
+ (if tag \<notin> safe_shadow_root_element_types then error HierarchyRequestError else return ());
+ prev_shadow_root \<leftarrow> get_shadow_root element_ptr;
+ (if prev_shadow_root \<noteq> None then error HierarchyRequestError else return ());
+ new_shadow_root_ptr \<leftarrow> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M;
+ set_mode new_shadow_root_ptr shadow_root_mode;
+ set_shadow_root element_ptr (Some new_shadow_root_ptr);
+ return new_shadow_root_ptr
+ }"
+end
+
+locale l_attach_shadow_root_defs =
+ fixes attach_shadow_root :: "(_) element_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> (_, (_) shadow_root_ptr) dom_prog"
+
+global_interpretation l_attach_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs set_shadow_root set_shadow_root_locs set_mode
+ set_mode_locs get_tag_name get_tag_name_locs get_shadow_root get_shadow_root_locs
+ defines attach_shadow_root = a_attach_shadow_root
+ .
+
+locale l_attach_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_attach_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs set_shadow_root set_shadow_root_locs set_mode set_mode_locs get_tag_name get_tag_name_locs get_shadow_root get_shadow_root_locs +
+ l_attach_shadow_root_defs attach_shadow_root +
+ l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf set_shadow_root set_shadow_root_locs +
+ l_set_mode type_wf set_mode set_mode_locs +
+ l_get_tag_name type_wf get_tag_name get_tag_name_locs +
+ l_get_shadow_root type_wf get_shadow_root get_shadow_root_locs +
+ l_known_ptr known_ptr
+ for known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and set_shadow_root :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr option \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_mode :: "(_) shadow_root_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and attach_shadow_root :: "(_) element_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr) prog"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> (_, char list) dom_prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes known_ptr_impl: "known_ptr = a_known_ptr"
+ assumes attach_shadow_root_impl: "attach_shadow_root = a_attach_shadow_root"
+begin
+lemmas attach_shadow_root_def = a_attach_shadow_root_def[folded attach_shadow_root_impl]
+
+lemma attach_shadow_root_element_ptr_in_heap:
+ assumes "h \<turnstile> ok (attach_shadow_root element_ptr shadow_root_mode)"
+ shows "element_ptr |\<in>| element_ptr_kinds h"
+proof -
+ obtain h' where "h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>h h'"
+ using assms by auto
+ then
+ obtain h2 h3 new_shadow_root_ptr where
+ h2: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h2" and
+ new_shadow_root_ptr: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr" and
+ h3: "h2 \<turnstile> set_mode new_shadow_root_ptr shadow_root_mode \<rightarrow>\<^sub>h h3" and
+ "h3 \<turnstile> set_shadow_root element_ptr (Some new_shadow_root_ptr) \<rightarrow>\<^sub>h h'"
+ by(auto simp add: attach_shadow_root_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_tag_name_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_shadow_root_pure, rotated] split: if_splits)
+
+ then have "element_ptr |\<in>| element_ptr_kinds h3"
+ using set_shadow_root_ptr_in_heap by blast
+
+ moreover
+ have "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_shadow_root_ptr|}"
+ using h2 new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_new_ptr new_shadow_root_ptr by auto
+
+ moreover
+ have "object_ptr_kinds h2 = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_mode_writes h3])
+ using set_mode_pointers_preserved
+ apply blast
+ by (auto simp add: reflp_def transp_def)
+ ultimately
+ show ?thesis
+ by (metis (no_types, lifting) cast_document_ptr_not_node_ptr(2) element_ptr_kinds_commutes
+ finsertE funion_finsert_right node_ptr_kinds_commutes sup_bot.right_neutral)
+qed
+
+lemma create_shadow_root_known_ptr:
+ assumes "h \<turnstile> attach_shadow_root element_ptr shadow_root_mode \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ shows "known_ptr (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_shadow_root_ptr)"
+ using assms
+ by(auto simp add: attach_shadow_root_def known_ptr_impl ShadowRootClass.a_known_ptr_def
+ new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def elim!: bind_returns_result_E)
+end
+
+locale l_attach_shadow_root = l_attach_shadow_root_defs
+
+interpretation
+ i_attach_shadow_root?: l_attach_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr set_shadow_root set_shadow_root_locs
+ set_mode set_mode_locs attach_shadow_root type_wf get_tag_name get_tag_name_locs get_shadow_root get_shadow_root_locs
+ by(auto simp add: l_attach_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_attach_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ attach_shadow_root_def instances)
+declare l_attach_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_parent\<close>
+
+global_interpretation l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs
+ defines get_parent = "l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_parent get_child_nodes"
+ and get_parent_locs = "l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_parent_locs get_child_nodes_locs"
+ .
+
+interpretation i_get_parent?: l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes
+ get_child_nodes_locs known_ptrs get_parent get_parent_locs
+ by(simp add: l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def get_parent_def
+ get_parent_locs_def instances)
+declare l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_parent_is_l_get_parent [instances]: "l_get_parent type_wf known_ptr known_ptrs get_parent
+get_parent_locs get_child_nodes get_child_nodes_locs"
+ apply(simp add: l_get_parent_def l_get_parent_axioms_def instances)
+ using get_parent_reads get_parent_ok get_parent_ptr_in_heap get_parent_pure get_parent_parent_in_heap get_parent_child_dual
+ using get_parent_reads_pointers
+ by blast
+
+
+
+paragraph \<open>set\_disconnected\_nodes\<close>
+
+locale l_set_disconnected_nodes_get_parent\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes_get_child_nodes
+ + l_set_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_disconnected_nodes_get_parent [simp]: "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_parent_locs. r h h'))"
+ by(auto simp add: get_parent_locs_def CD.set_disconnected_nodes_locs_def all_args_def)
+end
+interpretation i_set_disconnected_nodes_get_parent?:
+ l_set_disconnected_nodes_get_parent\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_disconnected_nodes set_disconnected_nodes_locs
+ get_child_nodes get_child_nodes_locs type_wf DocumentClass.type_wf known_ptr known_ptrs get_parent
+ get_parent_locs
+ by (simp add: l_set_disconnected_nodes_get_parent\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_set_disconnected_nodes_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_disconnected_nodes_get_parent_is_l_set_disconnected_nodes_get_parent [instances]:
+ "l_set_disconnected_nodes_get_parent set_disconnected_nodes_locs get_parent_locs"
+ by(simp add: l_set_disconnected_nodes_get_parent_def)
+
+
+
+subsubsection \<open>get\_root\_node\<close>
+
+global_interpretation l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_parent get_parent_locs
+ defines get_root_node = "l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_root_node get_parent"
+ and get_root_node_locs = "l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_root_node_locs get_parent_locs"
+ and get_ancestors = "l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_ancestors get_parent"
+ and get_ancestors_locs = "l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_ancestors_locs get_parent_locs"
+ .
+declare a_get_ancestors.simps [code]
+
+interpretation i_get_root_node?: l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr known_ptrs get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_ancestors get_ancestors_locs get_root_node
+ get_root_node_locs
+ by(simp add: l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def get_root_node_def
+ get_root_node_locs_def get_ancestors_def get_ancestors_locs_def instances)
+declare l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_ancestors_is_l_get_ancestors [instances]: "l_get_ancestors get_ancestors"
+ apply(auto simp add: l_get_ancestors_def)[1]
+ using get_ancestors_ptr_in_heap apply fast
+ using get_ancestors_ptr apply fast
+ done
+
+lemma get_root_node_is_l_get_root_node [instances]: "l_get_root_node get_root_node get_parent"
+ by (simp add: l_get_root_node_def Shadow_DOM.i_get_root_node.get_root_node_no_parent)
+
+
+
+subsubsection \<open>get\_root\_node\_si\<close>
+
+locale l_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_parent_defs get_parent get_parent_locs +
+ l_get_host_defs get_host get_host_locs
+ for get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_::linorder) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+partial_function (dom_prog) a_get_ancestors_si :: "(_::linorder) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ where
+ "a_get_ancestors_si ptr = do {
+ check_in_heap ptr;
+ ancestors \<leftarrow> (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some node_ptr \<Rightarrow> do {
+ parent_ptr_opt \<leftarrow> get_parent node_ptr;
+ (case parent_ptr_opt of
+ Some parent_ptr \<Rightarrow> a_get_ancestors_si parent_ptr
+ | None \<Rightarrow> return [])
+ }
+ | None \<Rightarrow> (case cast ptr of
+ Some shadow_root_ptr \<Rightarrow> do {
+ host \<leftarrow> get_host shadow_root_ptr;
+ a_get_ancestors_si (cast host)
+ } |
+ None \<Rightarrow> return []));
+ return (ptr # ancestors)
+ }"
+
+definition "a_get_ancestors_si_locs = get_parent_locs \<union> get_host_locs"
+
+definition a_get_root_node_si :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr) dom_prog"
+ where
+ "a_get_root_node_si ptr = do {
+ ancestors \<leftarrow> a_get_ancestors_si ptr;
+ return (last ancestors)
+ }"
+definition "a_get_root_node_si_locs = a_get_ancestors_si_locs"
+end
+
+locale l_get_ancestors_si_defs =
+ fixes get_ancestors_si :: "(_::linorder) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ fixes get_ancestors_si_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_root_node_si_defs =
+ fixes get_root_node_si :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr) dom_prog"
+ fixes get_root_node_si_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_parent +
+ l_get_host +
+ l_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_get_ancestors_si_defs +
+ l_get_root_node_si_defs +
+ assumes get_ancestors_si_impl: "get_ancestors_si = a_get_ancestors_si"
+ assumes get_ancestors_si_locs_impl: "get_ancestors_si_locs = a_get_ancestors_si_locs"
+ assumes get_root_node_si_impl: "get_root_node_si = a_get_root_node_si"
+ assumes get_root_node_si_locs_impl: "get_root_node_si_locs = a_get_root_node_si_locs"
+begin
+lemmas get_ancestors_si_def = a_get_ancestors_si.simps[folded get_ancestors_si_impl]
+lemmas get_ancestors_si_locs_def = a_get_ancestors_si_locs_def[folded get_ancestors_si_locs_impl]
+lemmas get_root_node_si_def = a_get_root_node_si_def[folded get_root_node_si_impl get_ancestors_si_impl]
+lemmas get_root_node_si_locs_def =
+ a_get_root_node_si_locs_def[folded get_root_node_si_locs_impl get_ancestors_si_locs_impl]
+
+lemma get_ancestors_si_pure [simp]:
+ "pure (get_ancestors_si ptr) h"
+proof -
+ have "\<forall>ptr h h' x. h \<turnstile> get_ancestors_si ptr \<rightarrow>\<^sub>r x \<longrightarrow> h \<turnstile> get_ancestors_si ptr \<rightarrow>\<^sub>h h' \<longrightarrow> h = h'"
+ proof (induct rule: a_get_ancestors_si.fixp_induct[folded get_ancestors_si_impl])
+ case 1
+ then show ?case
+ by(rule admissible_dom_prog)
+ next
+ case 2
+ then show ?case
+ by simp
+ next
+ case (3 f)
+ then show ?case
+ using get_parent_pure get_host_pure
+ apply(auto simp add: pure_returns_heap_eq pure_def split: option.splits
+ elim!: bind_returns_heap_E bind_returns_result_E
+ dest!: pure_returns_heap_eq[rotated, OF check_in_heap_pure])[1]
+ apply (meson option.simps(3) returns_result_eq)
+ apply(metis get_parent_pure pure_returns_heap_eq)
+ apply(metis get_host_pure pure_returns_heap_eq)
+ done
+ qed
+ then show ?thesis
+ by (meson pure_eq_iff)
+qed
+
+
+lemma get_root_node_si_pure [simp]: "pure (get_root_node_si ptr) h"
+ by(auto simp add: get_root_node_si_def bind_pure_I)
+
+
+lemma get_ancestors_si_ptr_in_heap:
+ assumes "h \<turnstile> ok (get_ancestors_si ptr)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ by(auto simp add: get_ancestors_si_def check_in_heap_ptr_in_heap elim!: bind_is_OK_E
+ dest: is_OK_returns_result_I)
+
+lemma get_ancestors_si_ptr:
+ assumes "h \<turnstile> get_ancestors_si ptr \<rightarrow>\<^sub>r ancestors"
+ shows "ptr \<in> set ancestors"
+ using assms
+ by(simp add: get_ancestors_si_def) (auto elim!: bind_returns_result_E2 split: option.splits
+ intro!: bind_pure_I)
+
+
+lemma get_ancestors_si_never_empty:
+ assumes "h \<turnstile> get_ancestors_si child \<rightarrow>\<^sub>r ancestors"
+ shows "ancestors \<noteq> []"
+ using assms
+ apply(simp add: get_ancestors_si_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits)
+ (*
+lemma get_ancestors_si_not_node:
+ assumes "h \<turnstile> get_ancestors_si ptr \<rightarrow>\<^sub>r ancestors"
+ assumes "\<not>is_node_ptr_kind ptr"
+ shows "ancestors = [ptr]"
+ using assms
+ by (simp add: get_ancestors_si_def) (auto elim!: bind_returns_result_E2 split: option.splits)
+ *)
+
+lemma get_root_node_si_no_parent:
+ "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r None \<Longrightarrow> h \<turnstile> get_root_node_si (cast node_ptr) \<rightarrow>\<^sub>r cast node_ptr"
+ apply(auto simp add: check_in_heap_def get_root_node_si_def get_ancestors_si_def
+ intro!: bind_pure_returns_result_I )[1]
+ using get_parent_ptr_in_heap by blast
+
+
+lemma get_root_node_si_root_not_shadow_root:
+ assumes "h \<turnstile> get_root_node_si ptr \<rightarrow>\<^sub>r root"
+ shows "\<not> is_shadow_root_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root"
+ using assms
+proof(auto simp add: get_root_node_si_def elim!: bind_returns_result_E2)
+ fix y
+ assume "h \<turnstile> get_ancestors_si ptr \<rightarrow>\<^sub>r y"
+ and "is_shadow_root_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (last y)"
+ and "root = last y"
+ then
+ show False
+ proof(induct y arbitrary: ptr)
+ case Nil
+ then show ?case
+ using assms(1) get_ancestors_si_never_empty by blast
+ next
+ case (Cons a x)
+ then show ?case
+ apply(auto simp add: get_ancestors_si_def[of ptr] elim!: bind_returns_result_E2
+ split: option.splits if_splits)[1]
+ using get_ancestors_si_never_empty apply blast
+ using Cons.prems(2) apply auto[1]
+ using \<open>is_shadow_root_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (last y)\<close> \<open>root = last y\<close> by auto
+ qed
+qed
+end
+
+global_interpretation l_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_parent get_parent_locs get_host get_host_locs
+ defines get_root_node_si = a_get_root_node_si
+ and get_root_node_si_locs = a_get_root_node_si_locs
+ and get_ancestors_si = a_get_ancestors_si
+ and get_ancestors_si_locs = a_get_ancestors_si_locs
+ .
+declare a_get_ancestors_si.simps [code]
+
+interpretation
+ i_get_root_node_si?: l_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr known_ptrs get_parent
+ get_parent_locs get_child_nodes get_child_nodes_locs get_host get_host_locs get_ancestors_si
+ get_ancestors_si_locs get_root_node_si get_root_node_si_locs
+ apply(auto simp add: l_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)[1]
+ by(auto simp add: get_root_node_si_def get_root_node_si_locs_def get_ancestors_si_def get_ancestors_si_locs_def)
+declare l_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_ancestors_si_is_l_get_ancestors [instances]: "l_get_ancestors get_ancestors_si"
+ unfolding l_get_ancestors_def
+ using get_ancestors_si_pure get_ancestors_si_ptr get_ancestors_si_ptr_in_heap
+ by blast
+
+lemma get_root_node_si_is_l_get_root_node [instances]: "l_get_root_node get_root_node_si get_parent"
+ apply(simp add: l_get_root_node_def)
+ using get_root_node_si_no_parent
+ by fast
+
+
+paragraph \<open>set\_disconnected\_nodes\<close>
+
+
+locale l_set_disconnected_nodes_get_ancestors_si\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes_get_parent
+ + l_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + l_set_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + l_set_disconnected_nodes_get_host
+begin
+lemma set_disconnected_nodes_get_ancestors_si:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_ancestors_si_locs. r h h'))"
+ by(auto simp add: get_parent_locs_def set_disconnected_nodes_locs_def
+ set_disconnected_nodes_get_host get_ancestors_si_locs_def all_args_def)
+end
+
+locale l_set_disconnected_nodes_get_ancestors_si = l_set_disconnected_nodes_defs + l_get_ancestors_si_defs +
+ assumes set_disconnected_nodes_get_ancestors_si:
+ "\<forall>w \<in> set_disconnected_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_ancestors_si_locs. r h h'))"
+
+interpretation
+ i_set_disconnected_nodes_get_ancestors_si?: l_set_disconnected_nodes_get_ancestors_si\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ set_disconnected_nodes set_disconnected_nodes_locs get_parent get_parent_locs type_wf known_ptr
+ known_ptrs get_child_nodes get_child_nodes_locs get_host get_host_locs get_ancestors_si
+ get_ancestors_si_locs get_root_node_si get_root_node_si_locs DocumentClass.type_wf
+
+ by (auto simp add: l_set_disconnected_nodes_get_ancestors_si\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_set_disconnected_nodes_get_ancestors_si\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+lemma set_disconnected_nodes_get_ancestors_si_is_l_set_disconnected_nodes_get_ancestors_si [instances]:
+ "l_set_disconnected_nodes_get_ancestors_si set_disconnected_nodes_locs get_ancestors_si_locs"
+ using instances
+ apply(simp add: l_set_disconnected_nodes_get_ancestors_si_def)
+ using set_disconnected_nodes_get_ancestors_si
+ by fast
+
+
+
+subsubsection \<open>get\_attribute\<close>
+
+lemma get_attribute_is_l_get_attribute [instances]: "l_get_attribute type_wf get_attribute get_attribute_locs"
+ apply(auto simp add: l_get_attribute_def)[1]
+ using i_get_attribute.get_attribute_reads apply fast
+ using type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t i_get_attribute.get_attribute_ok apply blast
+ using i_get_attribute.get_attribute_ptr_in_heap apply fast
+ done
+
+
+
+subsubsection \<open>to\_tree\_order\<close>
+
+global_interpretation l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs defines
+ to_tree_order = "l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_to_tree_order get_child_nodes" .
+declare a_to_tree_order.simps [code]
+
+interpretation i_to_tree_order?: l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M ShadowRootClass.known_ptr
+ ShadowRootClass.type_wf Shadow_DOM.get_child_nodes Shadow_DOM.get_child_nodes_locs to_tree_order
+ by(auto simp add: l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def to_tree_order_def instances)
+declare l_to_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+
+subsubsection \<open>to\_tree\_order\_si\<close>
+
+
+locale l_to_tree_order_si\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_child_nodes_defs get_child_nodes get_child_nodes_locs +
+ l_get_shadow_root_defs get_shadow_root get_shadow_root_locs
+ for get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+partial_function (dom_prog) a_to_tree_order_si :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ where
+ "a_to_tree_order_si ptr = (do {
+ children \<leftarrow> get_child_nodes ptr;
+ shadow_root_part \<leftarrow> (case cast ptr of
+ Some element_ptr \<Rightarrow> do {
+ shadow_root_opt \<leftarrow> get_shadow_root element_ptr;
+ (case shadow_root_opt of
+ Some shadow_root_ptr \<Rightarrow> return [cast shadow_root_ptr]
+ | None \<Rightarrow> return [])
+ } |
+ None \<Rightarrow> return []);
+ treeorders \<leftarrow> map_M a_to_tree_order_si ((map (cast) children) @ shadow_root_part);
+ return (ptr # concat treeorders)
+ })"
+end
+
+locale l_to_tree_order_si_defs =
+ fixes to_tree_order_si :: "(_) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+
+global_interpretation l_to_tree_order_si\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs
+ get_shadow_root get_shadow_root_locs
+ defines to_tree_order_si = "a_to_tree_order_si" .
+declare a_to_tree_order_si.simps [code]
+
+
+locale l_to_tree_order_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_to_tree_order_si_defs +
+ l_to_tree_order_si\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_get_child_nodes +
+ l_get_shadow_root +
+ assumes to_tree_order_si_impl: "to_tree_order_si = a_to_tree_order_si"
+begin
+lemmas to_tree_order_si_def = a_to_tree_order_si.simps[folded to_tree_order_si_impl]
+
+lemma to_tree_order_si_pure [simp]: "pure (to_tree_order_si ptr) h"
+proof -
+ have "\<forall>ptr h h' x. h \<turnstile> to_tree_order_si ptr \<rightarrow>\<^sub>r x \<longrightarrow> h \<turnstile> to_tree_order_si ptr \<rightarrow>\<^sub>h h' \<longrightarrow> h = h'"
+ proof (induct rule: a_to_tree_order_si.fixp_induct[folded to_tree_order_si_impl])
+ case 1
+ then show ?case
+ by (rule admissible_dom_prog)
+ next
+ case 2
+ then show ?case
+ by simp
+ next
+ case (3 f)
+ then have "\<And>x h. pure (f x) h"
+ by (metis is_OK_returns_heap_E is_OK_returns_result_E pure_def)
+ then have "\<And>xs h. pure (map_M f xs) h"
+ by(rule map_M_pure_I)
+ then show ?case
+ by(auto elim!: bind_returns_heap_E2 split: option.splits)
+ qed
+ then show ?thesis
+ unfolding pure_def
+ by (metis is_OK_returns_heap_E is_OK_returns_result_E)
+qed
+end
+
+interpretation i_to_tree_order_si?: l_to_tree_order_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M to_tree_order_si get_child_nodes
+ get_child_nodes_locs get_shadow_root get_shadow_root_locs type_wf known_ptr
+ by(auto simp add: l_to_tree_order_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_to_tree_order_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ to_tree_order_si_def instances)
+declare l_to_tree_order_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>first\_in\_tree\_order\<close>
+
+global_interpretation l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs to_tree_order defines
+ first_in_tree_order = "l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_first_in_tree_order to_tree_order" .
+
+interpretation i_first_in_tree_order?: l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M to_tree_order first_in_tree_order
+ by(auto simp add: l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def first_in_tree_order_def)
+declare l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma to_tree_order_is_l_to_tree_order [instances]: "l_to_tree_order to_tree_order"
+ by(auto simp add: l_to_tree_order_def)
+
+
+
+subsubsection \<open>first\_in\_tree\_order\<close>
+
+global_interpretation l_dummy defines
+ first_in_tree_order_si = "l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_first_in_tree_order to_tree_order_si"
+ .
+
+
+subsubsection \<open>get\_element\_by\<close>
+
+global_interpretation l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs to_tree_order first_in_tree_order get_attribute get_attribute_locs defines
+ get_element_by_id = "l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_element_by_id first_in_tree_order get_attribute" and
+ get_elements_by_class_name = "l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_elements_by_class_name to_tree_order get_attribute" and
+ get_elements_by_tag_name = "l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_elements_by_tag_name to_tree_order" .
+
+interpretation
+ i_get_element_by?: l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M to_tree_order first_in_tree_order get_attribute
+ get_attribute_locs get_element_by_id get_elements_by_class_name
+ get_elements_by_tag_name type_wf
+ by(auto simp add: l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def get_element_by_id_def
+ get_elements_by_class_name_def get_elements_by_tag_name_def instances)
+declare l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+lemma get_element_by_is_l_get_element_by [instances]: "l_get_element_by get_element_by_id get_elements_by_tag_name to_tree_order"
+ apply(auto simp add: l_get_element_by_def)[1]
+ using get_element_by_id_result_in_tree_order apply fast
+ done
+
+
+subsubsection \<open>get\_element\_by\_si\<close>
+
+global_interpretation l_dummy defines
+ get_element_by_id_si = "l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_element_by_id first_in_tree_order_si get_attribute" and
+ get_elements_by_class_name_si = "l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_elements_by_class_name to_tree_order_si get_attribute" and
+ get_elements_by_tag_name_si = "l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_elements_by_tag_name to_tree_order_si"
+ .
+
+
+
+subsubsection \<open>find\_slot\<close>
+
+locale l_find_slot\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_parent_defs get_parent get_parent_locs +
+ l_get_shadow_root_defs get_shadow_root get_shadow_root_locs +
+ l_get_mode_defs get_mode get_mode_locs +
+ l_get_attribute_defs get_attribute get_attribute_locs +
+ l_get_tag_name_defs get_tag_name get_tag_name_locs +
+ l_first_in_tree_order_defs first_in_tree_order
+ for get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_::linorder) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_mode :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, shadow_root_mode) prog"
+ and get_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_attribute :: "(_) element_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, char list option) prog"
+ and get_attribute_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and first_in_tree_order ::
+ "(_) object_ptr \<Rightarrow> ((_) object_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog) \<Rightarrow>
+((_) heap, exception, (_) element_ptr option) prog"
+begin
+definition a_find_slot :: "bool \<Rightarrow> (_) node_ptr \<Rightarrow> (_, (_) element_ptr option) dom_prog"
+ where
+ "a_find_slot open_flag slotable = do {
+ parent_opt \<leftarrow> get_parent slotable;
+ (case parent_opt of
+ Some parent \<Rightarrow>
+ if is_element_ptr_kind parent
+ then do {
+ shadow_root_ptr_opt \<leftarrow> get_shadow_root (the (cast parent));
+ (case shadow_root_ptr_opt of
+ Some shadow_root_ptr \<Rightarrow> do {
+ shadow_root_mode \<leftarrow> get_mode shadow_root_ptr;
+ if open_flag \<and> shadow_root_mode \<noteq> Open
+ then return None
+ else first_in_tree_order (cast shadow_root_ptr) (\<lambda>ptr. if is_element_ptr_kind ptr
+ then do {
+ tag \<leftarrow> get_tag_name (the (cast ptr));
+ name_attr \<leftarrow> get_attribute (the (cast ptr)) ''name'';
+ slotable_name_attr \<leftarrow> (if is_element_ptr_kind slotable
+ then get_attribute (the (cast slotable)) ''slot'' else return None);
+ (if (tag = ''slot'' \<and> (name_attr = slotable_name_attr \<or>
+ (name_attr = None \<and> slotable_name_attr = Some '''') \<or>
+ (name_attr = Some '''' \<and> slotable_name_attr = None)))
+ then return (Some (the (cast ptr)))
+ else return None)}
+ else return None)}
+ | None \<Rightarrow> return None)}
+ else return None
+ | _ \<Rightarrow> return None)}"
+
+definition a_assigned_slot :: "(_) node_ptr \<Rightarrow> (_, (_) element_ptr option) dom_prog"
+ where
+ "a_assigned_slot = a_find_slot True"
+end
+
+global_interpretation l_find_slot\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_parent get_parent_locs get_shadow_root
+ get_shadow_root_locs get_mode get_mode_locs get_attribute get_attribute_locs get_tag_name
+ get_tag_name_locs first_in_tree_order
+ defines find_slot = a_find_slot
+ and assigned_slot = a_assigned_slot
+ .
+
+locale l_find_slot_defs =
+ fixes find_slot :: "bool \<Rightarrow> (_) node_ptr \<Rightarrow> (_, (_) element_ptr option) dom_prog"
+ and assigned_slot :: "(_) node_ptr \<Rightarrow> (_, (_) element_ptr option) dom_prog"
+
+locale l_find_slot\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_find_slot\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_find_slot_defs +
+ l_get_parent +
+ l_get_shadow_root +
+ l_get_mode +
+ l_get_attribute +
+ l_get_tag_name +
+ l_to_tree_order +
+ l_first_in_tree_order\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ assumes find_slot_impl: "find_slot = a_find_slot"
+ assumes assigned_slot_impl: "assigned_slot = a_assigned_slot"
+begin
+lemmas find_slot_def = find_slot_impl[unfolded a_find_slot_def]
+lemmas assigned_slot_def = assigned_slot_impl[unfolded a_assigned_slot_def]
+
+lemma find_slot_ptr_in_heap:
+ assumes "h \<turnstile> find_slot open_flag slotable \<rightarrow>\<^sub>r slot_opt"
+ shows "slotable |\<in>| node_ptr_kinds h"
+ using assms
+ apply(auto simp add: find_slot_def elim!: bind_returns_result_E2)[1]
+ using get_parent_ptr_in_heap by blast
+
+lemma find_slot_slot_in_heap:
+ assumes "h \<turnstile> find_slot open_flag slotable \<rightarrow>\<^sub>r Some slot"
+ shows "slot |\<in>| element_ptr_kinds h"
+ using assms
+ apply(auto simp add: find_slot_def first_in_tree_order_def elim!: bind_returns_result_E2
+ map_filter_M_pure_E[where y=slot] split: option.splits if_splits list.splits intro!: map_filter_M_pure
+ bind_pure_I)[1]
+ using get_tag_name_ptr_in_heap by blast+
+
+lemma find_slot_pure [simp]: "pure (find_slot open_flag slotable) h"
+ by(auto simp add: find_slot_def first_in_tree_order_def intro!: bind_pure_I map_filter_M_pure
+ split: option.splits list.splits)
+end
+
+interpretation i_find_slot?: l_find_slot\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_parent get_parent_locs get_shadow_root
+ get_shadow_root_locs get_mode get_mode_locs get_attribute get_attribute_locs get_tag_name
+ get_tag_name_locs first_in_tree_order find_slot assigned_slot type_wf known_ptr known_ptrs
+ get_child_nodes get_child_nodes_locs to_tree_order
+ by (auto simp add: find_slot_def assigned_slot_def l_find_slot\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def
+ l_find_slot\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_find_slot\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+locale l_find_slot = l_find_slot_defs +
+ assumes find_slot_ptr_in_heap: "h \<turnstile> find_slot open_flag slotable \<rightarrow>\<^sub>r slot_opt \<Longrightarrow> slotable |\<in>| node_ptr_kinds h"
+ assumes find_slot_slot_in_heap: "h \<turnstile> find_slot open_flag slotable \<rightarrow>\<^sub>r Some slot \<Longrightarrow> slot |\<in>| element_ptr_kinds h"
+ assumes find_slot_pure [simp]: "pure (find_slot open_flag slotable) h"
+
+lemma find_slot_is_l_find_slot [instances]: "l_find_slot find_slot"
+ apply(auto simp add: l_find_slot_def)[1]
+ using find_slot_ptr_in_heap apply fast
+ using find_slot_slot_in_heap apply fast
+ done
+
+
+
+subsubsection \<open>get\_disconnected\_nodes\<close>
+
+locale l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ CD: l_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs +
+ l_type_wf type_wf
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+begin
+
+lemma get_disconnected_nodes_ok:
+ "type_wf h \<Longrightarrow> document_ptr |\<in>| document_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_disconnected_nodes document_ptr)"
+ apply(unfold type_wf_impl get_disconnected_nodes_impl[unfolded a_get_disconnected_nodes_def])
+ using CD.get_disconnected_nodes_ok CD.type_wf_impl ShadowRootClass.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ by blast
+end
+
+interpretation i_get_disconnected_nodes?: l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ DocumentClass.type_wf get_disconnected_nodes get_disconnected_nodes_locs
+ by(auto simp add: l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_disconnected_nodes_is_l_get_disconnected_nodes [instances]:
+ "l_get_disconnected_nodes type_wf get_disconnected_nodes get_disconnected_nodes_locs"
+ apply(auto simp add: l_get_disconnected_nodes_def)[1]
+ using i_get_disconnected_nodes.get_disconnected_nodes_reads apply fast
+ using get_disconnected_nodes_ok apply fast
+ using i_get_disconnected_nodes.get_disconnected_nodes_ptr_in_heap apply fast
+ done
+
+
+paragraph \<open>set\_child\_nodes\<close>
+
+locale l_set_child_nodes_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_child_nodes_get_disconnected_nodes:
+ "\<forall>w \<in> set_child_nodes_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+ by(auto simp add: set_child_nodes_locs_def CD.set_child_nodes_locs_def
+ CD.get_disconnected_nodes_locs_def all_args_def elim: get_M_document_put_M_shadow_root
+ split: option.splits)
+end
+
+interpretation
+ i_set_child_nodes_get_disconnected_nodes?: l_set_child_nodes_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ known_ptr DocumentClass.type_wf DocumentClass.known_ptr set_child_nodes set_child_nodes_locs
+ Core_DOM_Functions.set_child_nodes Core_DOM_Functions.set_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs
+ apply(auto simp add: l_set_child_nodes_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)[1]
+ by(unfold_locales)
+declare l_set_child_nodes_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_child_nodes_get_disconnected_nodes_is_l_set_child_nodes_get_disconnected_nodes [instances]:
+ "l_set_child_nodes_get_disconnected_nodes type_wf set_child_nodes set_child_nodes_locs
+get_disconnected_nodes get_disconnected_nodes_locs"
+ using set_child_nodes_is_l_set_child_nodes get_disconnected_nodes_is_l_get_disconnected_nodes
+ apply(simp add: l_set_child_nodes_get_disconnected_nodes_def l_set_child_nodes_get_disconnected_nodes_axioms_def )
+ using set_child_nodes_get_disconnected_nodes
+ by fast
+
+
+paragraph \<open>set\_disconnected\_nodes\<close>
+
+lemma set_disconnected_nodes_get_disconnected_nodes_l_set_disconnected_nodes_get_disconnected_nodes [instances]:
+ "l_set_disconnected_nodes_get_disconnected_nodes ShadowRootClass.type_wf get_disconnected_nodes
+get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs"
+ apply(auto simp add: l_set_disconnected_nodes_get_disconnected_nodes_def
+ l_set_disconnected_nodes_get_disconnected_nodes_axioms_def instances)[1]
+ using i_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ apply fast
+ using i_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes_different_pointers
+ apply fast
+ done
+
+
+paragraph \<open>delete\_shadow\_root\<close>
+
+locale l_delete_shadow_root_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma get_disconnected_nodes_delete_shadow_root:
+ "cast shadow_root_ptr \<noteq> ptr' \<Longrightarrow> h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_disconnected_nodes_locs ptr' \<Longrightarrow> r h h'"
+ by(auto simp add: CD.get_disconnected_nodes_locs_def delete_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+end
+
+locale l_delete_shadow_root_get_disconnected_nodes = l_get_disconnected_nodes_defs +
+ assumes get_disconnected_nodes_delete_shadow_root:
+ "cast shadow_root_ptr \<noteq> ptr' \<Longrightarrow> h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_disconnected_nodes_locs ptr' \<Longrightarrow> r h h'"
+interpretation l_delete_shadow_root_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf
+ get_disconnected_nodes get_disconnected_nodes_locs
+ by(auto simp add: l_delete_shadow_root_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+
+lemma l_delete_shadow_root_get_disconnected_nodes_get_disconnected_nodes_locs [instances]: "l_delete_shadow_root_get_disconnected_nodes get_disconnected_nodes_locs"
+ apply(auto simp add: l_delete_shadow_root_get_disconnected_nodes_def)[1]
+ using get_disconnected_nodes_delete_shadow_root apply fast
+ done
+
+
+paragraph \<open>set\_shadow\_root\<close>
+
+locale l_set_shadow_root_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_shadow_root_get_disconnected_nodes:
+ "\<forall>w \<in> set_shadow_root_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+ by(auto simp add: set_shadow_root_locs_def CD.get_disconnected_nodes_locs_def all_args_def)
+end
+
+interpretation
+ i_set_shadow_root_get_disconnected_nodes?: l_set_shadow_root_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ set_shadow_root set_shadow_root_locs DocumentClass.type_wf get_disconnected_nodes get_disconnected_nodes_locs
+ apply(auto simp add: l_set_shadow_root_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)[1]
+ by(unfold_locales)
+declare l_set_shadow_root_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+locale l_set_shadow_root_get_disconnected_nodes = l_set_shadow_root_defs + l_get_disconnected_nodes_defs +
+ assumes set_shadow_root_get_disconnected_nodes:
+ "\<forall>w \<in> set_shadow_root_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+
+lemma set_shadow_root_get_disconnected_nodes_is_l_set_shadow_root_get_disconnected_nodes [instances]:
+ "l_set_shadow_root_get_disconnected_nodes set_shadow_root_locs get_disconnected_nodes_locs"
+ using set_shadow_root_is_l_set_shadow_root get_disconnected_nodes_is_l_get_disconnected_nodes
+ apply(simp add: l_set_shadow_root_get_disconnected_nodes_def )
+ using set_shadow_root_get_disconnected_nodes
+ by fast
+
+paragraph \<open>set\_mode\<close>
+
+locale l_set_mode_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_mode\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_mode_get_disconnected_nodes:
+ "\<forall>w \<in> set_mode_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+ by(auto simp add: set_mode_locs_def
+ CD.get_disconnected_nodes_locs_impl[unfolded CD.a_get_disconnected_nodes_locs_def]
+ all_args_def)
+end
+
+interpretation
+ i_set_mode_get_disconnected_nodes?: l_set_mode_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ set_mode set_mode_locs DocumentClass.type_wf get_disconnected_nodes
+ get_disconnected_nodes_locs
+ by unfold_locales
+declare l_set_mode_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+locale l_set_mode_get_disconnected_nodes = l_set_mode + l_get_disconnected_nodes +
+ assumes set_mode_get_disconnected_nodes:
+ "\<forall>w \<in> set_mode_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+
+lemma set_mode_get_disconnected_nodes_is_l_set_mode_get_disconnected_nodes [instances]:
+ "l_set_mode_get_disconnected_nodes type_wf set_mode set_mode_locs get_disconnected_nodes
+ get_disconnected_nodes_locs"
+ using set_mode_is_l_set_mode get_disconnected_nodes_is_l_get_disconnected_nodes
+ apply(simp add: l_set_mode_get_disconnected_nodes_def
+ l_set_mode_get_disconnected_nodes_axioms_def)
+ using set_mode_get_disconnected_nodes
+ by fast
+
+paragraph \<open>new\_shadow\_root\<close>
+
+locale l_new_shadow_root_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma get_disconnected_nodes_new_shadow_root_different_pointers:
+ "cast new_shadow_root_ptr \<noteq> ptr' \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_disconnected_nodes_locs ptr' \<Longrightarrow> r h h'"
+ by(auto simp add: CD.get_disconnected_nodes_locs_def new_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t)
+
+lemma new_shadow_root_no_disconnected_nodes:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_disconnected_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []"
+ by(simp add: CD.get_disconnected_nodes_def new_shadow_root_disconnected_nodes)
+
+end
+
+interpretation i_new_shadow_root_get_disconnected_nodes?:
+ l_new_shadow_root_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf get_disconnected_nodes
+ get_disconnected_nodes_locs
+ by unfold_locales
+declare l_new_shadow_root_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+locale l_new_shadow_root_get_disconnected_nodes = l_get_disconnected_nodes_defs +
+ assumes get_disconnected_nodes_new_shadow_root_different_pointers:
+ "cast new_shadow_root_ptr \<noteq> ptr' \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> r \<in> get_disconnected_nodes_locs ptr' \<Longrightarrow> r h h'"
+ assumes new_shadow_root_no_disconnected_nodes:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h' \<turnstile> get_disconnected_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []"
+
+lemma new_shadow_root_get_disconnected_nodes_is_l_new_shadow_root_get_disconnected_nodes [instances]:
+ "l_new_shadow_root_get_disconnected_nodes get_disconnected_nodes get_disconnected_nodes_locs"
+ apply (auto simp add: l_new_shadow_root_get_disconnected_nodes_def)[1]
+ using get_disconnected_nodes_new_shadow_root_different_pointers apply fast
+ using new_shadow_root_no_disconnected_nodes apply blast
+ done
+
+
+subsubsection \<open>remove\_shadow\_root\<close>
+
+locale l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_child_nodes_defs get_child_nodes get_child_nodes_locs +
+ l_get_shadow_root_defs get_shadow_root get_shadow_root_locs +
+ l_set_shadow_root_defs set_shadow_root set_shadow_root_locs +
+ l_get_disconnected_nodes_defs get_disconnected_nodes get_disconnected_nodes_locs
+ for get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_shadow_root :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr option \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+
+definition a_remove_shadow_root :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog" where
+ "a_remove_shadow_root element_ptr = do {
+ shadow_root_ptr_opt \<leftarrow> get_shadow_root element_ptr;
+ (case shadow_root_ptr_opt of
+ Some shadow_root_ptr \<Rightarrow> do {
+ children \<leftarrow> get_child_nodes (cast shadow_root_ptr);
+ disconnected_nodes \<leftarrow> get_disconnected_nodes (cast shadow_root_ptr);
+ (if children = [] \<and> disconnected_nodes = []
+ then do {
+ set_shadow_root element_ptr None;
+ delete_M shadow_root_ptr
+ } else do {
+ error HierarchyRequestError
+ })
+ } |
+ None \<Rightarrow> error HierarchyRequestError)
+ }"
+
+definition a_remove_shadow_root_locs :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr \<Rightarrow> ((_, unit) dom_prog) set"
+ where
+ "a_remove_shadow_root_locs element_ptr shadow_root_ptr \<equiv> set_shadow_root_locs element_ptr \<union> {delete_M shadow_root_ptr}"
+end
+
+global_interpretation l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs
+ get_shadow_root get_shadow_root_locs set_shadow_root set_shadow_root_locs get_disconnected_nodes
+ get_disconnected_nodes_locs
+ defines remove_shadow_root = "a_remove_shadow_root"
+ and remove_shadow_root_locs = a_remove_shadow_root_locs
+ .
+
+locale l_remove_shadow_root_defs =
+ fixes remove_shadow_root :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog"
+ fixes remove_shadow_root_locs :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr \<Rightarrow> ((_, unit) dom_prog) set"
+
+
+locale l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_remove_shadow_root_defs +
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_child_nodes +
+ l_get_disconnected_nodes +
+ assumes remove_shadow_root_impl: "remove_shadow_root = a_remove_shadow_root"
+ assumes remove_shadow_root_locs_impl: "remove_shadow_root_locs = a_remove_shadow_root_locs"
+begin
+lemmas remove_shadow_root_def =
+ remove_shadow_root_impl[unfolded remove_shadow_root_def a_remove_shadow_root_def]
+lemmas remove_shadow_root_locs_def =
+ remove_shadow_root_locs_impl[unfolded remove_shadow_root_locs_def a_remove_shadow_root_locs_def]
+
+lemma remove_shadow_root_writes:
+ "writes (remove_shadow_root_locs element_ptr (the |h \<turnstile> get_shadow_root element_ptr|\<^sub>r))
+(remove_shadow_root element_ptr) h h'"
+ apply(auto simp add: remove_shadow_root_locs_def remove_shadow_root_def all_args_def
+ writes_union_right_I writes_union_left_I set_shadow_root_writes
+ intro!: writes_bind writes_bind_pure[OF get_shadow_root_pure] writes_bind_pure[OF get_child_nodes_pure]
+ intro: writes_subset[OF set_shadow_root_writes] writes_subset[OF writes_singleton2] split: option.splits)[1]
+ using writes_union_left_I[OF set_shadow_root_writes]
+ apply (metis inf_sup_aci(5) insert_is_Un)
+ using writes_union_right_I[OF writes_singleton[of delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M]]
+ by (smt insert_is_Un writes_singleton2 writes_union_left_I)
+end
+
+interpretation i_remove_shadow_root?: l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs
+ get_shadow_root get_shadow_root_locs set_shadow_root set_shadow_root_locs get_disconnected_nodes
+ get_disconnected_nodes_locs remove_shadow_root remove_shadow_root_locs type_wf known_ptr
+ by(auto simp add: l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ remove_shadow_root_def remove_shadow_root_locs_def instances)
+declare l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+paragraph \<open>get\_child\_nodes\<close>
+
+locale l_remove_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma remove_shadow_root_get_child_nodes_different_pointers:
+ assumes "ptr \<noteq> cast shadow_root_ptr"
+ assumes "w \<in> remove_shadow_root_locs element_ptr shadow_root_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ assumes "r \<in> get_child_nodes_locs ptr"
+ shows "r h h'"
+ using assms
+ by(auto simp add: all_args_def get_child_nodes_locs_def CD.get_child_nodes_locs_def
+ remove_shadow_root_locs_def set_shadow_root_locs_def
+ delete_shadow_root_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t delete_shadow_root_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+ intro: is_shadow_root_ptr_kind_obtains
+ simp add: delete_shadow_root_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t delete_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ delete_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t[rotated] element_put_get_preserved[where setter=shadow_root_opt_update]
+ elim: is_document_ptr_kind_obtains is_shadow_root_ptr_kind_obtains
+ split: if_splits option.splits)[1]
+end
+
+locale l_remove_shadow_root_get_child_nodes = l_get_child_nodes_defs + l_remove_shadow_root_defs +
+ assumes remove_shadow_root_get_child_nodes_different_pointers:
+ "ptr \<noteq> cast shadow_root_ptr \<Longrightarrow> w \<in> remove_shadow_root_locs element_ptr shadow_root_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow>
+r \<in> get_child_nodes_locs ptr \<Longrightarrow> r h h'"
+
+interpretation
+ i_remove_shadow_root_get_child_nodes?: l_remove_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ known_ptr DocumentClass.type_wf DocumentClass.known_ptr get_child_nodes get_child_nodes_locs
+ Core_DOM_Functions.get_child_nodes Core_DOM_Functions.get_child_nodes_locs get_shadow_root
+ get_shadow_root_locs set_shadow_root set_shadow_root_locs get_disconnected_nodes get_disconnected_nodes_locs
+ remove_shadow_root remove_shadow_root_locs
+ by(auto simp add: l_remove_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_remove_shadow_root_get_child_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma remove_shadow_root_get_child_nodes_is_l_remove_shadow_root_get_child_nodes [instances]:
+ "l_remove_shadow_root_get_child_nodes get_child_nodes_locs remove_shadow_root_locs"
+ apply(auto simp add: l_remove_shadow_root_get_child_nodes_def instances )[1]
+ using remove_shadow_root_get_child_nodes_different_pointers apply fast
+ done
+
+paragraph \<open>get\_tag\_name\<close>
+
+locale l_remove_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma remove_shadow_root_get_tag_name:
+ assumes "w \<in> remove_shadow_root_locs element_ptr shadow_root_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ assumes "r \<in> get_tag_name_locs ptr"
+ shows "r h h'"
+ using assms
+ by(auto simp add: all_args_def remove_shadow_root_locs_def set_shadow_root_locs_def
+ CD.get_tag_name_locs_def delete_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ element_put_get_preserved[where setter=shadow_root_opt_update] split: if_splits option.splits)
+end
+
+locale l_remove_shadow_root_get_tag_name = l_get_tag_name_defs + l_remove_shadow_root_defs +
+ assumes remove_shadow_root_get_tag_name:
+ "w \<in> remove_shadow_root_locs element_ptr shadow_root_ptr \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> r \<in> get_tag_name_locs ptr \<Longrightarrow>
+r h h'"
+
+interpretation
+ i_remove_shadow_root_get_tag_name?: l_remove_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf
+ DocumentClass.type_wf get_tag_name get_tag_name_locs get_child_nodes get_child_nodes_locs
+ get_shadow_root get_shadow_root_locs set_shadow_root set_shadow_root_locs get_disconnected_nodes
+ get_disconnected_nodes_locs remove_shadow_root remove_shadow_root_locs known_ptr
+ by(auto simp add: l_remove_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_remove_shadow_root_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma remove_shadow_root_get_tag_name_is_l_remove_shadow_root_get_tag_name [instances]:
+ "l_remove_shadow_root_get_tag_name get_tag_name_locs remove_shadow_root_locs"
+ apply(auto simp add: l_remove_shadow_root_get_tag_name_def instances )[1]
+ using remove_shadow_root_get_tag_name apply fast
+ done
+
+
+subsubsection \<open>get\_owner\_document\<close>
+
+locale l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_host_defs get_host get_host_locs +
+ CD: l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_root_node get_root_node_locs get_disconnected_nodes get_disconnected_nodes_locs
+ for get_root_node :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+definition a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r :: "(_) shadow_root_ptr \<Rightarrow> unit \<Rightarrow> (_, (_) document_ptr) dom_prog"
+ where
+ "a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr = CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast shadow_root_ptr)"
+
+definition a_get_owner_document_tups :: "(((_) object_ptr \<Rightarrow> bool) \<times> ((_) object_ptr \<Rightarrow> unit
+ \<Rightarrow> (_, (_) document_ptr) dom_prog)) list"
+ where
+ "a_get_owner_document_tups = [(is_shadow_root_ptr, a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast)]"
+
+definition a_get_owner_document :: "(_::linorder) object_ptr \<Rightarrow> (_, (_) document_ptr) dom_prog"
+ where
+ "a_get_owner_document ptr = invoke (CD.a_get_owner_document_tups @ a_get_owner_document_tups) ptr ()"
+end
+
+global_interpretation l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_root_node get_root_node_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_host get_host_locs
+ defines get_owner_document_tups = "l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_owner_document_tups"
+ and get_owner_document =
+ "l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_owner_document get_root_node get_disconnected_nodes"
+ and get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r =
+ "l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r"
+ and get_owner_document_tups\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ "l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_owner_document_tups get_root_node get_disconnected_nodes"
+ and get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r =
+ "l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r get_root_node get_disconnected_nodes"
+ .
+
+locale l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_root_node get_root_node_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_host get_host_locs +
+ l_get_owner_document_defs get_owner_document +
+ l_get_host get_host get_host_locs +
+ CD: l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_parent get_parent_locs known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes
+ get_disconnected_nodes_locs get_root_node get_root_node_locs get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ for known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_root_node :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_owner_document :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes get_owner_document_impl: "get_owner_document = a_get_owner_document"
+begin
+lemmas get_owner_document_def = a_get_owner_document_def[folded get_owner_document_impl]
+
+lemma get_owner_document_pure [simp]:
+ "pure (get_owner_document ptr) h"
+proof -
+ have "\<And>shadow_root_ptr. pure (a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr ()) h"
+ apply(auto simp add: a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: bind_pure_I filter_M_pure_I
+ split: option.splits)[1]
+ by(auto simp add: CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: bind_pure_I filter_M_pure_I
+ split: option.splits)
+ then show ?thesis
+ apply(auto simp add: get_owner_document_def)[1]
+ apply(split CD.get_owner_document_splits, rule conjI)+
+ apply(simp)
+ apply(auto simp add: a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, rule conjI)+
+ apply simp
+ by(auto intro!: bind_pure_I)
+qed
+
+lemma get_owner_document_ptr_in_heap:
+ assumes "h \<turnstile> ok (get_owner_document ptr)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ by(auto simp add: get_owner_document_def invoke_ptr_in_heap dest: is_OK_returns_heap_I)
+end
+
+interpretation
+ i_get_owner_document?: l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M DocumentClass.known_ptr get_parent get_parent_locs
+ DocumentClass.type_wf get_disconnected_nodes get_disconnected_nodes_locs get_root_node get_root_node_locs CD.a_get_owner_document get_host get_host_locs get_owner_document get_child_nodes get_child_nodes_locs
+ using get_child_nodes_is_l_get_child_nodes[unfolded ShadowRootClass.known_ptr_defs]
+ by(auto simp add: instances l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_owner_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def get_owner_document_def Core_DOM_Functions.get_owner_document_def)
+declare l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_owner_document_is_l_get_owner_document [instances]: "l_get_owner_document get_owner_document"
+ apply(auto simp add: l_get_owner_document_def)[1]
+ using get_owner_document_ptr_in_heap apply fast
+ done
+
+
+
+
+subsubsection \<open>remove\_child\<close>
+
+global_interpretation l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs set_child_nodes
+ set_child_nodes_locs get_parent get_parent_locs get_owner_document get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs
+ defines remove = "l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_remove get_child_nodes set_child_nodes get_parent
+get_owner_document get_disconnected_nodes set_disconnected_nodes"
+ and remove_child = "l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_remove_child get_child_nodes set_child_nodes
+get_owner_document get_disconnected_nodes set_disconnected_nodes"
+ and remove_child_locs = "l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_remove_child_locs set_child_nodes_locs
+set_disconnected_nodes_locs"
+ .
+
+interpretation i_remove_child?: l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M Shadow_DOM.get_child_nodes
+ Shadow_DOM.get_child_nodes_locs Shadow_DOM.set_child_nodes Shadow_DOM.set_child_nodes_locs
+ Shadow_DOM.get_parent Shadow_DOM.get_parent_locs
+ Shadow_DOM.get_owner_document get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs remove_child remove_child_locs remove
+ ShadowRootClass.type_wf
+ ShadowRootClass.known_ptr ShadowRootClass.known_ptrs
+ by(auto simp add: l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def remove_child_def
+ remove_child_locs_def remove_def instances)
+declare l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+
+subsubsection \<open>get\_disconnected\_document\<close>
+
+locale l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_disconnected_nodes_defs get_disconnected_nodes get_disconnected_nodes_locs
+ for get_disconnected_nodes :: "(_::linorder) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+definition a_get_disconnected_document :: "(_) node_ptr \<Rightarrow> (_, (_) document_ptr) dom_prog"
+ where
+ "a_get_disconnected_document node_ptr = do {
+ check_in_heap (cast node_ptr);
+ ptrs \<leftarrow> document_ptr_kinds_M;
+ candidates \<leftarrow> filter_M (\<lambda>document_ptr. do {
+ disconnected_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ return (node_ptr \<in> set disconnected_nodes)
+ }) ptrs;
+ (case candidates of
+ Cons document_ptr [] \<Rightarrow> return document_ptr |
+ _ \<Rightarrow> error HierarchyRequestError
+ )
+ }"
+definition "a_get_disconnected_document_locs =
+(\<Union>document_ptr. get_disconnected_nodes_locs document_ptr) \<union> (\<Union>ptr. {preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr RObject.nothing)})"
+end
+
+locale l_get_disconnected_document_defs =
+ fixes get_disconnected_document :: "(_) node_ptr \<Rightarrow> (_, (_::linorder) document_ptr) dom_prog"
+ fixes get_disconnected_document_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_get_disconnected_document_defs +
+ l_get_disconnected_nodes +
+ assumes get_disconnected_document_impl: "get_disconnected_document = a_get_disconnected_document"
+ assumes get_disconnected_document_locs_impl: "get_disconnected_document_locs = a_get_disconnected_document_locs"
+begin
+lemmas get_disconnected_document_def =
+ get_disconnected_document_impl[unfolded a_get_disconnected_document_def]
+lemmas get_disconnected_document_locs_def =
+ get_disconnected_document_locs_impl[unfolded a_get_disconnected_document_locs_def]
+
+
+lemma get_disconnected_document_pure [simp]: "pure (get_disconnected_document ptr) h"
+ using get_disconnected_nodes_pure
+ by(auto simp add: get_disconnected_document_def intro!: bind_pure_I filter_M_pure_I split: list.splits)
+
+lemma get_disconnected_document_ptr_in_heap [simp]:
+ "h \<turnstile> ok (get_disconnected_document node_ptr) \<Longrightarrow> node_ptr |\<in>| node_ptr_kinds h"
+ using get_disconnected_document_def is_OK_returns_result_I check_in_heap_ptr_in_heap
+ by (metis (no_types, lifting) bind_returns_heap_E get_disconnected_document_pure
+ node_ptr_kinds_commutes pure_pure)
+
+lemma get_disconnected_document_disconnected_document_in_heap:
+ assumes "h \<turnstile> get_disconnected_document child_node \<rightarrow>\<^sub>r disconnected_document"
+ shows "disconnected_document |\<in>| document_ptr_kinds h"
+ using assms get_disconnected_nodes_pure
+ by(auto simp add: get_disconnected_document_def elim!: bind_returns_result_E2
+ dest!: filter_M_not_more_elements[where x=disconnected_document]
+ intro!: filter_M_pure_I bind_pure_I
+ split: if_splits list.splits)
+
+lemma get_disconnected_document_reads:
+ "reads get_disconnected_document_locs (get_disconnected_document node_ptr) h h'"
+ using get_disconnected_nodes_reads[unfolded reads_def]
+ by(auto simp add: get_disconnected_document_def get_disconnected_document_locs_def
+ intro!: reads_bind_pure reads_subset[OF check_in_heap_reads]
+ reads_subset[OF error_reads]
+ reads_subset[OF get_disconnected_nodes_reads] reads_subset[OF return_reads]
+ reads_subset[OF document_ptr_kinds_M_reads] filter_M_reads filter_M_pure_I bind_pure_I
+ split: list.splits)
+
+end
+
+locale l_get_disconnected_document = l_get_disconnected_document_defs +
+ assumes get_disconnected_document_reads:
+ "reads get_disconnected_document_locs (get_disconnected_document node_ptr) h h'"
+ assumes get_disconnected_document_ptr_in_heap:
+ "h \<turnstile> ok (get_disconnected_document node_ptr) \<Longrightarrow> node_ptr |\<in>| node_ptr_kinds h"
+ assumes get_disconnected_document_pure [simp]:
+ "pure (get_disconnected_document node_ptr) h"
+ assumes get_disconnected_document_disconnected_document_in_heap:
+ "h \<turnstile> get_disconnected_document child_node \<rightarrow>\<^sub>r disconnected_document \<Longrightarrow>
+disconnected_document |\<in>| document_ptr_kinds h"
+
+global_interpretation l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_disconnected_nodes
+ get_disconnected_nodes_locs defines
+ get_disconnected_document = "l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_disconnected_document
+get_disconnected_nodes" and
+ get_disconnected_document_locs = "l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_get_disconnected_document_locs
+get_disconnected_nodes_locs" .
+
+interpretation i_get_disconnected_document?: l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_disconnected_nodes get_disconnected_nodes_locs get_disconnected_document get_disconnected_document_locs type_wf
+ by(auto simp add: l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ get_disconnected_document_def get_disconnected_document_locs_def instances)
+declare l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_disconnected_document_is_l_get_disconnected_document [instances]:
+ "l_get_disconnected_document get_disconnected_document get_disconnected_document_locs"
+ apply(auto simp add: l_get_disconnected_document_def instances)[1]
+ using get_disconnected_document_ptr_in_heap get_disconnected_document_pure
+ get_disconnected_document_disconnected_document_in_heap get_disconnected_document_reads
+ by blast+
+
+paragraph \<open>get\_disconnected\_nodes\<close>
+
+locale l_set_tag_name_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_tag_name_get_disconnected_nodes:
+ "\<forall>w \<in> set_tag_name_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_disconnected_nodes_locs ptr'. r h h'))"
+ by(auto simp add: CD.set_tag_name_locs_impl[unfolded CD.a_set_tag_name_locs_def]
+ CD.get_disconnected_nodes_locs_impl[unfolded CD.a_get_disconnected_nodes_locs_def]
+ all_args_def)
+end
+
+interpretation
+ i_set_tag_name_get_disconnected_nodes?: l_set_tag_name_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf
+ set_tag_name set_tag_name_locs get_disconnected_nodes
+ get_disconnected_nodes_locs
+ by unfold_locales
+declare l_set_tag_name_get_disconnected_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_tag_name_get_disconnected_nodes_is_l_set_tag_name_get_disconnected_nodes [instances]:
+ "l_set_tag_name_get_disconnected_nodes type_wf set_tag_name set_tag_name_locs get_disconnected_nodes
+ get_disconnected_nodes_locs"
+ using set_tag_name_is_l_set_tag_name get_disconnected_nodes_is_l_get_disconnected_nodes
+ apply(simp add: l_set_tag_name_get_disconnected_nodes_def
+ l_set_tag_name_get_disconnected_nodes_axioms_def)
+ using set_tag_name_get_disconnected_nodes
+ by fast
+
+
+subsubsection \<open>get\_ancestors\_di\<close>
+
+locale l_get_ancestors_di\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_parent_defs get_parent get_parent_locs +
+ l_get_host_defs get_host get_host_locs +
+ l_get_disconnected_document_defs get_disconnected_document get_disconnected_document_locs
+ for get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_::linorder) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_document :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_disconnected_document_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+partial_function (dom_prog) a_get_ancestors_di :: "(_::linorder) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ where
+ "a_get_ancestors_di ptr = do {
+ check_in_heap ptr;
+ ancestors \<leftarrow> (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some node_ptr \<Rightarrow> do {
+ parent_ptr_opt \<leftarrow> get_parent node_ptr;
+ (case parent_ptr_opt of
+ Some parent_ptr \<Rightarrow> a_get_ancestors_di parent_ptr
+ | None \<Rightarrow> do {
+ document_ptr \<leftarrow> get_disconnected_document node_ptr;
+ a_get_ancestors_di (cast document_ptr)
+ })
+ }
+ | None \<Rightarrow> (case cast ptr of
+ Some shadow_root_ptr \<Rightarrow> do {
+ host \<leftarrow> get_host shadow_root_ptr;
+ a_get_ancestors_di (cast host)
+ } |
+ None \<Rightarrow> return []));
+ return (ptr # ancestors)
+ }"
+
+definition "a_get_ancestors_di_locs = get_parent_locs \<union> get_host_locs \<union> get_disconnected_document_locs"
+end
+
+locale l_get_ancestors_di_defs =
+ fixes get_ancestors_di :: "(_::linorder) object_ptr \<Rightarrow> (_, (_) object_ptr list) dom_prog"
+ fixes get_ancestors_di_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+
+locale l_get_ancestors_di\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_parent +
+ l_get_host +
+ l_get_disconnected_document +
+ l_get_ancestors_di\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs +
+ l_get_ancestors_di_defs +
+ assumes get_ancestors_di_impl: "get_ancestors_di = a_get_ancestors_di"
+ assumes get_ancestors_di_locs_impl: "get_ancestors_di_locs = a_get_ancestors_di_locs"
+begin
+lemmas get_ancestors_di_def = a_get_ancestors_di.simps[folded get_ancestors_di_impl]
+lemmas get_ancestors_di_locs_def = a_get_ancestors_di_locs_def[folded get_ancestors_di_locs_impl]
+
+
+lemma get_ancestors_di_pure [simp]:
+ "pure (get_ancestors_di ptr) h"
+proof -
+ have "\<forall>ptr h h' x. h \<turnstile> get_ancestors_di ptr \<rightarrow>\<^sub>r x \<longrightarrow> h \<turnstile> get_ancestors_di ptr \<rightarrow>\<^sub>h h' \<longrightarrow> h = h'"
+ proof (induct rule: a_get_ancestors_di.fixp_induct[folded get_ancestors_di_impl])
+ case 1
+ then show ?case
+ by(rule admissible_dom_prog)
+ next
+ case 2
+ then show ?case
+ by simp
+ next
+ case (3 f)
+ then show ?case
+ using get_parent_pure get_host_pure get_disconnected_document_pure
+ apply(auto simp add: pure_returns_heap_eq pure_def split: option.splits elim!: bind_returns_heap_E
+ bind_returns_result_E dest!: pure_returns_heap_eq[rotated, OF check_in_heap_pure])[1]
+ apply (metis is_OK_returns_result_I returns_heap_eq returns_result_eq)
+ apply (meson option.simps(3) returns_result_eq)
+ apply (meson option.simps(3) returns_result_eq)
+ apply(metis get_parent_pure pure_returns_heap_eq)
+ apply(metis get_host_pure pure_returns_heap_eq)
+ done
+ qed
+ then show ?thesis
+ by (meson pure_eq_iff)
+qed
+
+lemma get_ancestors_di_ptr:
+ assumes "h \<turnstile> get_ancestors_di ptr \<rightarrow>\<^sub>r ancestors"
+ shows "ptr \<in> set ancestors"
+ using assms
+ by(simp add: get_ancestors_di_def) (auto elim!: bind_returns_result_E2 split: option.splits
+ intro!: bind_pure_I)
+
+lemma get_ancestors_di_ptr_in_heap:
+ assumes "h \<turnstile> ok (get_ancestors_di ptr)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ by(auto simp add: get_ancestors_di_def check_in_heap_ptr_in_heap elim!: bind_is_OK_E
+ dest: is_OK_returns_result_I)
+
+lemma get_ancestors_di_never_empty:
+ assumes "h \<turnstile> get_ancestors_di child \<rightarrow>\<^sub>r ancestors"
+ shows "ancestors \<noteq> []"
+ using assms
+ apply(simp add: get_ancestors_di_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits intro!: bind_pure_I)
+end
+
+global_interpretation l_get_ancestors_di\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_parent get_parent_locs get_host get_host_locs
+ get_disconnected_document get_disconnected_document_locs
+ defines get_ancestors_di = a_get_ancestors_di
+ and get_ancestors_di_locs = a_get_ancestors_di_locs .
+declare a_get_ancestors_di.simps [code]
+
+interpretation i_get_ancestors_di?: l_get_ancestors_di\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_host get_host_locs get_disconnected_document get_disconnected_document_locs get_ancestors_di get_ancestors_di_locs
+ by(auto simp add: l_get_ancestors_di\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_ancestors_di\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ get_ancestors_di_def get_ancestors_di_locs_def instances)
+declare l_get_ancestors_di\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_ancestors_di_is_l_get_ancestors [instances]: "l_get_ancestors get_ancestors_di"
+ apply(auto simp add: l_get_ancestors_def)[1]
+ using get_ancestors_di_ptr_in_heap apply fast
+ using get_ancestors_di_ptr apply fast
+ done
+
+subsubsection \<open>adopt\_node\<close>
+
+locale l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w_\<^sub>D\<^sub>O\<^sub>M_defs =
+ CD: l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_owner_document get_parent get_parent_locs remove_child
+ remove_child_locs get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs +
+ l_get_ancestors_di_defs get_ancestors_di get_ancestors_di_locs
+ for get_owner_document :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and remove_child :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and remove_child_locs :: "(_) object_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_ancestors_di :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_ancestors_di_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+definition a_adopt_node :: "(_) document_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> (_, unit) dom_prog"
+ where
+ "a_adopt_node document node = do {
+ ancestors \<leftarrow> get_ancestors_di (cast document);
+ (if cast node \<in> set ancestors
+ then error HierarchyRequestError
+ else CD.a_adopt_node document node)}"
+
+definition a_adopt_node_locs ::
+ "(_) object_ptr option \<Rightarrow> (_) document_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+ where "a_adopt_node_locs = CD.a_adopt_node_locs"
+end
+
+locale l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w_\<^sub>D\<^sub>O\<^sub>M_defs get_owner_document get_parent get_parent_locs remove_child
+ remove_child_locs get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs get_ancestors_di get_ancestors_di_locs +
+ l_adopt_node_defs adopt_node adopt_node_locs +
+ l_get_ancestors_di\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf known_ptr known_ptrs get_parent get_parent_locs
+ get_child_nodes get_child_nodes_locs get_host get_host_locs get_disconnected_document
+ get_disconnected_document_locs get_ancestors_di get_ancestors_di_locs +
+ CD: l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_owner_document get_parent get_parent_locs remove_child
+ remove_child_locs get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf get_child_nodes get_child_nodes_locs known_ptrs set_child_nodes
+ set_child_nodes_locs remove
+ for get_owner_document :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and remove_child :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and remove_child_locs :: "(_) object_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_ancestors_di :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog"
+ and get_ancestors_di_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and adopt_node :: "(_) document_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and adopt_node_locs ::
+ "(_) object_ptr option \<Rightarrow> (_) document_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) document_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M ::
+ "(_) object_ptr option \<Rightarrow> (_) document_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and set_child_nodes :: "(_) object_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_document :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_disconnected_document_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and remove :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog" +
+ assumes adopt_node_impl: "adopt_node = a_adopt_node"
+ assumes adopt_node_locs_impl: "adopt_node_locs = a_adopt_node_locs"
+begin
+lemmas adopt_node_def = a_adopt_node_def[folded adopt_node_impl CD.adopt_node_impl]
+lemmas adopt_node_locs_def = a_adopt_node_locs_def[folded adopt_node_locs_impl CD.adopt_node_locs_impl]
+
+lemma adopt_node_writes:
+ "writes (adopt_node_locs |h \<turnstile> get_parent node|\<^sub>r
+ |h \<turnstile> get_owner_document (cast node)|\<^sub>r document_ptr) (adopt_node document_ptr node) h h'"
+ by(auto simp add: CD.adopt_node_writes adopt_node_def CD.adopt_node_impl[symmetric]
+ adopt_node_locs_def CD.adopt_node_locs_impl[symmetric]
+ intro!: writes_bind_pure[OF get_ancestors_di_pure])
+
+lemma adopt_node_pointers_preserved:
+ "w \<in> adopt_node_locs parent owner_document document_ptr
+ \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> object_ptr_kinds h = object_ptr_kinds h'"
+ using CD.adopt_node_locs_impl CD.adopt_node_pointers_preserved local.adopt_node_locs_def by blast
+lemma adopt_node_types_preserved:
+ "w \<in> adopt_node_locs parent owner_document document_ptr
+ \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ using CD.adopt_node_locs_impl CD.adopt_node_types_preserved local.adopt_node_locs_def by blast
+lemma adopt_node_child_in_heap:
+ "h \<turnstile> ok (adopt_node document_ptr child) \<Longrightarrow> child |\<in>| node_ptr_kinds h"
+ by (smt CD.adopt_node_child_in_heap CD.adopt_node_impl bind_is_OK_E error_returns_heap
+ is_OK_returns_heap_E l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M.adopt_node_def l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms
+ local.get_ancestors_di_pure pure_returns_heap_eq)
+lemma adopt_node_children_subset:
+ "h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children'
+ \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h \<Longrightarrow> set children' \<subseteq> set children"
+ by (smt CD.adopt_node_children_subset CD.adopt_node_impl bind_returns_heap_E error_returns_heap
+ local.adopt_node_def local.get_ancestors_di_pure pure_returns_heap_eq)
+end
+
+global_interpretation l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w_\<^sub>D\<^sub>O\<^sub>M_defs get_owner_document get_parent get_parent_locs
+ remove_child remove_child_locs get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs get_ancestors_di get_ancestors_di_locs
+ defines adopt_node = "a_adopt_node"
+ and adopt_node_locs = "a_adopt_node_locs"
+ and adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = "CD.a_adopt_node"
+ and adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = "CD.a_adopt_node_locs"
+ .
+interpretation i_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M: l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document get_parent get_parent_locs remove_child remove_child_locs
+ get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs
+ adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes get_child_nodes_locs
+ known_ptrs set_child_nodes set_child_nodes_locs remove
+ by(auto simp add: l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def
+ adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare i_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.l_adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+interpretation i_adopt_node?: l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document get_parent get_parent_locs remove_child remove_child_locs get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs get_ancestors_di
+ get_ancestors_di_locs adopt_node adopt_node_locs CD.a_adopt_node CD.a_adopt_node_locs known_ptr
+ type_wf get_child_nodes get_child_nodes_locs known_ptrs set_child_nodes set_child_nodes_locs
+ get_host get_host_locs get_disconnected_document get_disconnected_document_locs remove
+ by(auto simp add: l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def adopt_node_def
+ adopt_node_locs_def instances)
+declare l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma adopt_node_is_l_adopt_node [instances]: "l_adopt_node type_wf known_ptr known_ptrs get_parent
+adopt_node adopt_node_locs get_child_nodes get_owner_document"
+ apply(auto simp add: l_adopt_node_def l_adopt_node_axioms_def instances)[1]
+ using adopt_node_writes apply fast
+ using adopt_node_pointers_preserved apply (fast, fast)
+ using adopt_node_types_preserved apply (fast, fast)
+ using adopt_node_child_in_heap apply fast
+ using adopt_node_children_subset apply fast
+ done
+
+
+
+paragraph \<open>get\_shadow\_root\<close>
+
+locale l_adopt_node_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_child_nodes_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_disconnected_nodes_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma adopt_node_get_shadow_root:
+ "\<forall>w \<in> adopt_node_locs parent owner_document document_ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow>
+(\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+ by(auto simp add: adopt_node_locs_def CD.adopt_node_locs_def CD.remove_child_locs_def
+ all_args_def set_disconnected_nodes_get_shadow_root set_child_nodes_get_shadow_root)
+end
+
+locale l_adopt_node_get_shadow_root = l_adopt_node_defs + l_get_shadow_root_defs +
+ assumes adopt_node_get_shadow_root:
+ "\<forall>w \<in> adopt_node_locs parent owner_document document_ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow>
+(\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+
+interpretation i_adopt_node_get_shadow_root?: l_adopt_node_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr DocumentClass.type_wf DocumentClass.known_ptr set_child_nodes set_child_nodes_locs
+ Core_DOM_Functions.set_child_nodes Core_DOM_Functions.set_child_nodes_locs get_shadow_root
+ get_shadow_root_locs set_disconnected_nodes set_disconnected_nodes_locs get_owner_document
+ get_parent get_parent_locs remove_child remove_child_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_ancestors_di get_ancestors_di_locs adopt_node adopt_node_locs
+ adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs known_ptrs get_host
+ get_host_locs get_disconnected_document get_disconnected_document_locs remove
+ by(auto simp add: l_adopt_node_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_adopt_node_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+interpretation i_adopt_node_get_shadow_root?: l_adopt_node_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr DocumentClass.type_wf DocumentClass.known_ptr set_child_nodes
+ set_child_nodes_locs Core_DOM_Functions.set_child_nodes Core_DOM_Functions.set_child_nodes_locs
+ get_shadow_root get_shadow_root_locs set_disconnected_nodes set_disconnected_nodes_locs
+ get_owner_document get_parent get_parent_locs remove_child remove_child_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_ancestors_di get_ancestors_di_locs adopt_node adopt_node_locs
+ adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs known_ptrs get_host
+ get_host_locs get_disconnected_document get_disconnected_document_locs remove
+ by(auto simp add: l_adopt_node_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_adopt_node_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma adopt_node_get_shadow_root_is_l_adopt_node_get_shadow_root [instances]:
+ "l_adopt_node_get_shadow_root adopt_node_locs get_shadow_root_locs"
+ apply(auto simp add: l_adopt_node_get_shadow_root_def)[1]
+ using adopt_node_get_shadow_root apply fast
+ done
+
+
+
+subsubsection \<open>insert\_before\<close>
+
+global_interpretation l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_parent get_parent_locs get_child_nodes
+ get_child_nodes_locs set_child_nodes set_child_nodes_locs get_ancestors_di get_ancestors_di_locs
+ adopt_node adopt_node_locs set_disconnected_nodes set_disconnected_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_owner_document
+ defines
+ next_sibling = a_next_sibling and
+ insert_node = a_insert_node and
+ ensure_pre_insertion_validity = a_ensure_pre_insertion_validity and
+ insert_before = a_insert_before and
+ insert_before_locs = a_insert_before_locs
+ .
+global_interpretation l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs insert_before
+ defines append_child = "l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_append_child insert_before"
+ .
+
+interpretation i_insert_before?: l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_parent get_parent_locs get_child_nodes
+ get_child_nodes_locs set_child_nodes set_child_nodes_locs get_ancestors_di get_ancestors_di_locs
+ adopt_node adopt_node_locs set_disconnected_nodes set_disconnected_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_owner_document insert_before insert_before_locs append_child type_wf
+ known_ptr known_ptrs
+ by(auto simp add: l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def insert_before_def
+ insert_before_locs_def instances)
+declare l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+interpretation i_append_child?: l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M append_child insert_before insert_before_locs
+ by(simp add: l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances append_child_def)
+declare l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+subsubsection \<open>get\_assigned\_nodes\<close>
+
+fun map_filter_M2 :: "('x \<Rightarrow> ('heap, 'e, 'y option) prog) \<Rightarrow> 'x list
+ \<Rightarrow> ('heap, 'e, 'y list) prog"
+ where
+ "map_filter_M2 f [] = return []" |
+ "map_filter_M2 f (x # xs) = do {
+ res \<leftarrow> f x;
+ remainder \<leftarrow> map_filter_M2 f xs;
+ return ((case res of Some r \<Rightarrow> [r] | None \<Rightarrow> []) @ remainder)
+ }"
+lemma map_filter_M2_pure [simp]:
+ assumes "\<And>x. x \<in> set xs \<Longrightarrow> pure (f x) h"
+ shows "pure (map_filter_M2 f xs) h"
+ using assms
+ apply(induct xs arbitrary: h)
+ by(auto elim!: bind_returns_result_E2 intro!: bind_pure_I)
+
+lemma map_filter_pure_no_monad:
+ assumes "\<And>x. x \<in> set xs \<Longrightarrow> pure (f x) h"
+ assumes "h \<turnstile> map_filter_M2 f xs \<rightarrow>\<^sub>r ys"
+ shows
+ "ys = map the (filter (\<lambda>x. x \<noteq> None) (map (\<lambda>x. |h \<turnstile> f x|\<^sub>r) xs))" and
+ "\<And>x. x \<in> set xs \<Longrightarrow> h \<turnstile> ok (f x)"
+ using assms
+ apply(induct xs arbitrary: h ys)
+ by(auto elim!: bind_returns_result_E2)
+
+lemma map_filter_pure_foo:
+ assumes "\<And>x. x \<in> set xs \<Longrightarrow> pure (f x) h"
+ assumes "h \<turnstile> map_filter_M2 f xs \<rightarrow>\<^sub>r ys"
+ assumes "y \<in> set ys"
+ obtains x where "h \<turnstile> f x \<rightarrow>\<^sub>r Some y" and "x \<in> set xs"
+ using assms
+ apply(induct xs arbitrary: ys)
+ by(auto elim!: bind_returns_result_E2)
+
+
+lemma map_filter_M2_in_result:
+ assumes "h \<turnstile> map_filter_M2 P xs \<rightarrow>\<^sub>r ys"
+ assumes "a \<in> set xs"
+ assumes "\<And>x. x \<in> set xs \<Longrightarrow> pure (P x) h"
+ assumes "h \<turnstile> P a \<rightarrow>\<^sub>r Some b"
+ shows "b \<in> set ys"
+ using assms
+ apply(induct xs arbitrary: h ys)
+ by(auto elim!: bind_returns_result_E2 )
+
+
+locale l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ l_get_tag_name_defs get_tag_name get_tag_name_locs +
+ l_get_root_node_defs get_root_node get_root_node_locs +
+ l_get_host_defs get_host get_host_locs +
+ l_get_child_nodes_defs get_child_nodes get_child_nodes_locs +
+ l_find_slot_defs find_slot assigned_slot +
+ l_remove_defs remove +
+ l_insert_before_defs insert_before insert_before_locs +
+ l_append_child_defs append_child +
+ l_remove_shadow_root_defs remove_shadow_root remove_shadow_root_locs
+ for get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_root_node :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and find_slot :: "bool \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog"
+ and assigned_slot :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog"
+ and remove :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and insert_before ::
+ "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> (_) node_ptr option \<Rightarrow> ((_) heap, exception, unit) prog"
+ and insert_before_locs ::
+ "(_) object_ptr \<Rightarrow> (_) object_ptr option \<Rightarrow> (_) document_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+ and append_child :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and remove_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and remove_shadow_root_locs ::
+ "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+begin
+definition a_assigned_nodes :: "(_) element_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ where
+ "a_assigned_nodes slot = do {
+ tag \<leftarrow> get_tag_name slot;
+ (if tag \<noteq> ''slot''
+ then error HierarchyRequestError
+ else return ());
+ root \<leftarrow> get_root_node (cast slot);
+ if is_shadow_root_ptr_kind root
+ then do {
+ host \<leftarrow> get_host (the (cast root));
+ children \<leftarrow> get_child_nodes (cast host);
+ filter_M (\<lambda>slotable. do {
+ found_slot \<leftarrow> find_slot False slotable;
+ return (found_slot = Some slot)}) children}
+ else return []}"
+
+partial_function (dom_prog) a_assigned_nodes_flatten ::
+ "(_) element_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ where
+ "a_assigned_nodes_flatten slot = do {
+ tag \<leftarrow> get_tag_name slot;
+ (if tag \<noteq> ''slot''
+ then error HierarchyRequestError
+ else return ());
+ root \<leftarrow> get_root_node (cast slot);
+ (if is_shadow_root_ptr_kind root
+ then do {
+ slotables \<leftarrow> a_assigned_nodes slot;
+ slotables_or_child_nodes \<leftarrow> (if slotables = []
+ then do {
+ get_child_nodes (cast slot)
+ } else do {
+ return slotables
+ });
+ list_of_lists \<leftarrow> map_M (\<lambda>node_ptr. do {
+ (case cast node_ptr of
+ Some element_ptr \<Rightarrow> do {
+ tag \<leftarrow> get_tag_name element_ptr;
+ (if tag = ''slot''
+ then do {
+ root \<leftarrow> get_root_node (cast element_ptr);
+ (if is_shadow_root_ptr_kind root
+ then do {
+ a_assigned_nodes_flatten element_ptr
+ } else do {
+ return [node_ptr]
+ })
+ } else do {
+ return [node_ptr]
+ })
+ }
+ | None \<Rightarrow> return [node_ptr])
+ }) slotables_or_child_nodes;
+ return (concat list_of_lists)
+ } else return [])
+ }"
+
+definition a_flatten_dom :: "(_, unit) dom_prog" where
+ "a_flatten_dom = do {
+ tups \<leftarrow> element_ptr_kinds_M \<bind> map_filter_M2 (\<lambda>element_ptr. do {
+ tag \<leftarrow> get_tag_name element_ptr;
+ assigned_nodes \<leftarrow> a_assigned_nodes element_ptr;
+ (if tag = ''slot'' \<and> assigned_nodes \<noteq> []
+ then return (Some (element_ptr, assigned_nodes)) else return None)});
+ forall_M (\<lambda>(slot, assigned_nodes). do {
+ get_child_nodes (cast slot) \<bind> forall_M remove;
+ forall_M (append_child (cast slot)) assigned_nodes
+ }) tups;
+ shadow_root_ptr_kinds_M \<bind> forall_M (\<lambda>shadow_root_ptr. do {
+ host \<leftarrow> get_host shadow_root_ptr;
+ get_child_nodes (cast host) \<bind> forall_M remove;
+ get_child_nodes (cast shadow_root_ptr) \<bind> forall_M (append_child (cast host));
+ remove_shadow_root host
+ });
+ return ()
+ }"
+end
+
+global_interpretation l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs
+ get_tag_name get_tag_name_locs get_root_node get_root_node_locs get_host get_host_locs
+ find_slot assigned_slot remove insert_before insert_before_locs append_child remove_shadow_root
+ remove_shadow_root_locs
+ defines assigned_nodes =
+ "l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_assigned_nodes get_child_nodes get_tag_name get_root_node get_host
+find_slot"
+ and assigned_nodes_flatten =
+ "l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_assigned_nodes_flatten get_child_nodes get_tag_name get_root_node
+get_host find_slot"
+ and flatten_dom =
+ "l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_flatten_dom get_child_nodes get_tag_name get_root_node get_host
+find_slot remove append_child remove_shadow_root"
+ .
+
+declare a_assigned_nodes_flatten.simps [code]
+
+locale l_assigned_nodes_defs =
+ fixes assigned_nodes :: "(_) element_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ fixes assigned_nodes_flatten :: "(_) element_ptr \<Rightarrow> (_, (_) node_ptr list) dom_prog"
+ fixes flatten_dom :: "(_, unit) dom_prog"
+
+locale l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_assigned_nodes_defs
+ assigned_nodes assigned_nodes_flatten flatten_dom
+ + l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ get_child_nodes get_child_nodes_locs get_tag_name get_tag_name_locs get_root_node
+ get_root_node_locs get_host get_host_locs find_slot assigned_slot remove insert_before
+ insert_before_locs append_child remove_shadow_root remove_shadow_root_locs
+ (* + l_get_element_by\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M *)
+ + l_get_shadow_root
+ type_wf get_shadow_root get_shadow_root_locs
+ + l_set_shadow_root
+ type_wf set_shadow_root set_shadow_root_locs
+ + l_remove
+ + l_insert_before
+ insert_before insert_before_locs
+ + l_find_slot
+ find_slot assigned_slot
+ + l_get_tag_name
+ type_wf get_tag_name get_tag_name_locs
+ + l_get_root_node
+ get_root_node get_root_node_locs get_parent get_parent_locs
+ + l_get_host
+ get_host get_host_locs
+ + l_get_child_nodes
+ type_wf known_ptr get_child_nodes get_child_nodes_locs
+ + l_to_tree_order
+ to_tree_order
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and assigned_nodes :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and assigned_nodes_flatten :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and flatten_dom :: "((_) heap, exception, unit) prog"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_root_node :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr) prog"
+ and get_root_node_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and find_slot :: "bool \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog"
+ and assigned_slot :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr option) prog"
+ and remove :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and insert_before :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> (_) node_ptr option \<Rightarrow> ((_) heap, exception, unit) prog"
+ and insert_before_locs ::
+ "(_) object_ptr \<Rightarrow> (_) object_ptr option \<Rightarrow> (_) document_ptr \<Rightarrow> (_) document_ptr \<Rightarrow> (_, unit) dom_prog set"
+ and append_child :: "(_) object_ptr \<Rightarrow> (_) node_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and remove_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog"
+ and remove_shadow_root_locs :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_shadow_root :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr option \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and to_tree_order :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr list) prog" +
+ assumes assigned_nodes_impl: "assigned_nodes = a_assigned_nodes"
+ assumes flatten_dom_impl: "flatten_dom = a_flatten_dom"
+begin
+lemmas assigned_nodes_def = assigned_nodes_impl[unfolded a_assigned_nodes_def]
+lemmas flatten_dom_def = flatten_dom_impl[unfolded a_flatten_dom_def, folded assigned_nodes_impl]
+
+lemma assigned_nodes_pure [simp]: "pure (assigned_nodes slot) h"
+ by(auto simp add: assigned_nodes_def intro!: bind_pure_I filter_M_pure_I)
+
+lemma assigned_nodes_ptr_in_heap:
+ assumes "h \<turnstile> ok (assigned_nodes slot)"
+ shows "slot |\<in>| element_ptr_kinds h"
+ using assms
+ apply(auto simp add: assigned_nodes_def)[1]
+ by (meson bind_is_OK_E is_OK_returns_result_I local.get_tag_name_ptr_in_heap)
+
+lemma assigned_nodes_slot_is_slot:
+ assumes "h \<turnstile> ok (assigned_nodes slot)"
+ shows "h \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ using assms
+ by(auto simp add: assigned_nodes_def elim!: bind_is_OK_E split: if_splits)
+
+lemma assigned_nodes_different_ptr:
+ assumes "h \<turnstile> assigned_nodes slot \<rightarrow>\<^sub>r nodes"
+ assumes "h \<turnstile> assigned_nodes slot' \<rightarrow>\<^sub>r nodes'"
+ assumes "slot \<noteq> slot'"
+ shows "set nodes \<inter> set nodes' = {}"
+proof (rule ccontr)
+ assume "set nodes \<inter> set nodes' \<noteq> {} "
+ then obtain common_ptr where "common_ptr \<in> set nodes" and "common_ptr \<in> set nodes'"
+ by auto
+
+ have "h \<turnstile> find_slot False common_ptr \<rightarrow>\<^sub>r Some slot"
+ using \<open>common_ptr \<in> set nodes\<close>
+ using assms(1)
+ by(auto simp add: assigned_nodes_def elim!: bind_returns_result_E2 split: if_splits
+ dest!: filter_M_holds_for_result[where x=common_ptr] intro!: bind_pure_I)
+ moreover
+ have "h \<turnstile> find_slot False common_ptr \<rightarrow>\<^sub>r Some slot'"
+ using \<open>common_ptr \<in> set nodes'\<close>
+ using assms(2)
+ by(auto simp add: assigned_nodes_def elim!: bind_returns_result_E2 split: if_splits
+ dest!: filter_M_holds_for_result[where x=common_ptr] intro!: bind_pure_I)
+ ultimately
+ show False
+ using assms(3)
+ by (meson option.inject returns_result_eq)
+qed
+end
+
+interpretation i_assigned_nodes?: l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr assigned_nodes
+ assigned_nodes_flatten flatten_dom get_child_nodes get_child_nodes_locs get_tag_name
+ get_tag_name_locs get_root_node get_root_node_locs get_host get_host_locs find_slot assigned_slot
+ remove insert_before insert_before_locs append_child remove_shadow_root remove_shadow_root_locs
+ type_wf get_shadow_root get_shadow_root_locs set_shadow_root set_shadow_root_locs get_parent
+ get_parent_locs to_tree_order
+ by(auto simp add: instances l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ assigned_nodes_def flatten_dom_def)
+declare l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+locale l_assigned_nodes = l_assigned_nodes_defs +
+ assumes assigned_nodes_pure [simp]: "pure (assigned_nodes slot) h"
+ assumes assigned_nodes_ptr_in_heap: "h \<turnstile> ok (assigned_nodes slot) \<Longrightarrow> slot |\<in>| element_ptr_kinds h"
+ assumes assigned_nodes_slot_is_slot: "h \<turnstile> ok (assigned_nodes slot) \<Longrightarrow> h \<turnstile> get_tag_name slot \<rightarrow>\<^sub>r ''slot''"
+ assumes assigned_nodes_different_ptr:
+ "h \<turnstile> assigned_nodes slot \<rightarrow>\<^sub>r nodes \<Longrightarrow> h \<turnstile> assigned_nodes slot' \<rightarrow>\<^sub>r nodes' \<Longrightarrow> slot \<noteq> slot' \<Longrightarrow>
+set nodes \<inter> set nodes' = {}"
+
+lemma assigned_nodes_is_l_assigned_nodes [instances]: "l_assigned_nodes assigned_nodes"
+ apply(auto simp add: l_assigned_nodes_def)[1]
+ using assigned_nodes_ptr_in_heap apply fast
+ using assigned_nodes_slot_is_slot apply fast
+ using assigned_nodes_different_ptr apply fast
+ done
+
+
+subsubsection \<open>set\_val\<close>
+
+locale l_set_val\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ CD: l_set_val\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M set_val set_val_locs +
+ l_type_wf type_wf
+ for type_wf :: "(_) heap \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and set_val :: "(_) character_data_ptr \<Rightarrow> char list \<Rightarrow> (_, unit) dom_prog"
+ and set_val_locs :: "(_) character_data_ptr \<Rightarrow> (_, unit) dom_prog set" +
+ assumes type_wf_impl: "type_wf = ShadowRootClass.type_wf"
+begin
+
+lemma set_val_ok:
+ "type_wf h \<Longrightarrow> character_data_ptr |\<in>| character_data_ptr_kinds h \<Longrightarrow>
+h \<turnstile> ok (set_val character_data_ptr tag)"
+ using CD.set_val_ok CD.type_wf_impl ShadowRootClass.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t local.type_wf_impl by blast
+
+lemma set_val_writes: "writes (set_val_locs character_data_ptr) (set_val character_data_ptr tag) h h'"
+ using CD.set_val_writes .
+
+lemma set_val_pointers_preserved:
+ assumes "w \<in> set_val_locs character_data_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h'"
+ using assms CD.set_val_pointers_preserved by simp
+
+lemma set_val_typess_preserved:
+ assumes "w \<in> set_val_locs character_data_ptr"
+ assumes "h \<turnstile> w \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ apply(unfold type_wf_impl)
+ using assms(1) type_wf_preserved[OF writes_singleton2 assms(2)]
+ by(auto simp add: all_args_def CD.set_val_locs_impl[unfolded CD.a_set_val_locs_def] split: if_splits)
+end
+
+interpretation
+ i_set_val?: l_set_val\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf set_val set_val_locs
+ apply(unfold_locales)
+ by (auto simp add: set_val_def set_val_locs_def)
+declare l_set_val\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_val_is_l_set_val [instances]: "l_set_val type_wf set_val set_val_locs"
+ apply(simp add: l_set_val_def)
+ using set_val_ok set_val_writes set_val_pointers_preserved set_val_typess_preserved
+ by blast
+
+paragraph \<open>get\_shadow\_root\<close>
+
+locale l_set_val_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_val\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_val_get_shadow_root:
+ "\<forall>w \<in> set_val_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+ by(auto simp add: CD.set_val_locs_impl[unfolded CD.a_set_val_locs_def]
+ get_shadow_root_locs_def all_args_def)
+end
+
+locale l_set_val_get_shadow_root = l_set_val + l_get_shadow_root +
+ assumes set_val_get_shadow_root:
+ "\<forall>w \<in> set_val_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_shadow_root_locs ptr'. r h h'))"
+
+interpretation
+ i_set_val_get_shadow_root?: l_set_val_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf
+ set_val set_val_locs
+ get_shadow_root get_shadow_root_locs
+ apply(auto simp add: l_set_val_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)[1]
+ using l_set_val\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms
+ by unfold_locales
+declare l_set_val_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_val_get_shadow_root_is_l_set_val_get_shadow_root [instances]:
+ "l_set_val_get_shadow_root type_wf set_val set_val_locs get_shadow_root
+ get_shadow_root_locs"
+ using set_val_is_l_set_val get_shadow_root_is_l_get_shadow_root
+ apply(simp add: l_set_val_get_shadow_root_def l_set_val_get_shadow_root_axioms_def)
+ using set_val_get_shadow_root
+ by fast
+
+paragraph \<open>get\_tag\_type\<close>
+
+locale l_set_val_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_val\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma set_val_get_tag_name:
+ "\<forall>w \<in> set_val_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_tag_name_locs ptr'. r h h'))"
+ by(auto simp add: CD.set_val_locs_impl[unfolded CD.a_set_val_locs_def]
+ CD.get_tag_name_locs_impl[unfolded CD.a_get_tag_name_locs_def]
+ all_args_def)
+end
+
+locale l_set_val_get_tag_name = l_set_val + l_get_tag_name +
+ assumes set_val_get_tag_name:
+ "\<forall>w \<in> set_val_locs ptr. (h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>r \<in> get_tag_name_locs ptr'. r h h'))"
+
+interpretation
+ i_set_val_get_tag_name?: l_set_val_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf DocumentClass.type_wf set_val
+ set_val_locs get_tag_name get_tag_name_locs
+ by unfold_locales
+declare l_set_val_get_tag_name\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_val_get_tag_name_is_l_set_val_get_tag_name [instances]:
+ "l_set_val_get_tag_name type_wf set_val set_val_locs get_tag_name get_tag_name_locs"
+ using set_val_is_l_set_val get_tag_name_is_l_get_tag_name
+ apply(simp add: l_set_val_get_tag_name_def l_set_val_get_tag_name_axioms_def)
+ using set_val_get_tag_name
+ by fast
+
+subsubsection \<open>create\_character\_data\<close>
+
+
+locale l_create_character_data\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ CD: l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M _ _ _ _ _ _ type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M _ known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_known_ptr known_ptr
+ for known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> bool" +
+ assumes known_ptr_impl: "known_ptr = a_known_ptr"
+begin
+
+lemma create_character_data_document_in_heap:
+ assumes "h \<turnstile> ok (create_character_data document_ptr text)"
+ shows "document_ptr |\<in>| document_ptr_kinds h"
+ using assms CD.create_character_data_document_in_heap by simp
+
+lemma create_character_data_known_ptr:
+ assumes "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr"
+ shows "known_ptr (cast new_character_data_ptr)"
+ using assms CD.create_character_data_known_ptr
+ by(simp add: known_ptr_impl CD.known_ptr_impl ShadowRootClass.a_known_ptr_def)
+end
+
+locale l_create_character_data = l_create_character_data_defs
+
+interpretation
+ i_create_character_data?: l_create_character_data\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs set_val
+ set_val_locs create_character_data known_ptr DocumentClass.type_wf DocumentClass.known_ptr
+ by(auto simp add: l_create_character_data\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_create_character_data\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_create_character_data\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+subsubsection \<open>create\_element\<close>
+
+locale l_create_element\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ CD: l_create_element\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs set_tag_name set_tag_name_locs type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M create_element known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_known_ptr known_ptr
+ for get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_tag_name :: "(_) element_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and create_element :: "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) object_ptr \<Rightarrow> bool" +
+ assumes known_ptr_impl: "known_ptr = a_known_ptr"
+begin
+lemmas create_element_def = CD.create_element_def
+
+lemma create_element_document_in_heap:
+ assumes "h \<turnstile> ok (create_element document_ptr tag)"
+ shows "document_ptr |\<in>| document_ptr_kinds h"
+ using CD.create_element_document_in_heap assms .
+
+lemma create_element_known_ptr:
+ assumes "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr"
+ shows "known_ptr (cast new_element_ptr)"
+proof -
+ have "is_element_ptr new_element_ptr"
+ using assms
+ apply(auto simp add: create_element_def elim!: bind_returns_result_E)[1]
+ using new_element_is_element_ptr
+ by blast
+ then show ?thesis
+ by(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs)
+qed
+end
+
+interpretation
+ i_create_element?: l_create_element\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs set_tag_name set_tag_name_locs type_wf
+ create_element known_ptr DocumentClass.type_wf DocumentClass.known_ptr
+ by(auto simp add: l_create_element\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_create_element\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_create_element\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+
+subsection \<open>A wellformed heap (Core DOM)\<close>
+
+subsubsection \<open>wellformed\_heap\<close>
+
+
+locale l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs =
+ CD: l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs +
+ l_get_shadow_root_defs get_shadow_root get_shadow_root_locs +
+ l_get_tag_name_defs get_tag_name get_tag_name_locs
+ for get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+definition a_host_shadow_root_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ where
+ "a_host_shadow_root_rel h = (\<lambda>(x, y). (cast x, cast y)) ` {(host, shadow_root).
+ host |\<in>| element_ptr_kinds h \<and> |h \<turnstile> get_shadow_root host|\<^sub>r = Some shadow_root}"
+
+lemma a_host_shadow_root_rel_code [code]: "a_host_shadow_root_rel h = set (concat (map
+ (\<lambda>host. (case |h \<turnstile> get_shadow_root host|\<^sub>r of
+ Some shadow_root \<Rightarrow> [(cast host, cast shadow_root)] |
+ None \<Rightarrow> []))
+ (sorted_list_of_fset (element_ptr_kinds h)))
+)"
+ by(auto simp add: a_host_shadow_root_rel_def)
+
+definition a_ptr_disconnected_node_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ where
+ "a_ptr_disconnected_node_rel h = (\<lambda>(x, y). (cast x, cast y)) ` {(document_ptr, disconnected_node).
+ document_ptr |\<in>| document_ptr_kinds h \<and> disconnected_node \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r}"
+
+lemma a_ptr_disconnected_node_rel_code [code]: "a_ptr_disconnected_node_rel h = set (concat (map
+ (\<lambda>ptr. map
+ (\<lambda>node. (cast ptr, cast node))
+ |h \<turnstile> get_disconnected_nodes ptr|\<^sub>r)
+ (sorted_list_of_fset (document_ptr_kinds h)))
+)"
+ by(auto simp add: a_ptr_disconnected_node_rel_def)
+
+definition a_all_ptrs_in_heap :: "(_) heap \<Rightarrow> bool" where
+ "a_all_ptrs_in_heap h = ((\<forall>host shadow_root_ptr.
+ (h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr) \<longrightarrow>
+ shadow_root_ptr |\<in>| shadow_root_ptr_kinds h))"
+
+definition a_distinct_lists :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_distinct_lists h = distinct (concat (
+ map (\<lambda>element_ptr. (case |h \<turnstile> get_shadow_root element_ptr|\<^sub>r of
+ Some shadow_root_ptr \<Rightarrow> [shadow_root_ptr] | None \<Rightarrow> []))
+ |h \<turnstile> element_ptr_kinds_M|\<^sub>r
+ ))"
+
+definition a_shadow_root_valid :: "(_) heap \<Rightarrow> bool" where
+ "a_shadow_root_valid h = (\<forall>shadow_root_ptr \<in> fset (shadow_root_ptr_kinds h).
+ (\<exists>host \<in> fset(element_ptr_kinds h).
+ |h \<turnstile> get_tag_name host|\<^sub>r \<in> safe_shadow_root_element_types \<and>
+ |h \<turnstile> get_shadow_root host|\<^sub>r = Some shadow_root_ptr))"
+
+definition a_heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_heap_is_wellformed h \<longleftrightarrow> CD.a_heap_is_wellformed h \<and>
+ acyclic (CD.a_parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h) \<and>
+ a_all_ptrs_in_heap h \<and>
+ a_distinct_lists h \<and>
+ a_shadow_root_valid h"
+end
+
+global_interpretation l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs
+ get_tag_name get_tag_name_locs
+ defines heap_is_wellformed = a_heap_is_wellformed
+ and parent_child_rel = CD.a_parent_child_rel
+ and host_shadow_root_rel = a_host_shadow_root_rel
+ and ptr_disconnected_node_rel = a_ptr_disconnected_node_rel
+ and all_ptrs_in_heap = a_all_ptrs_in_heap
+ and distinct_lists = a_distinct_lists
+ and shadow_root_valid = a_shadow_root_valid
+ and heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = CD.a_heap_is_wellformed
+ and parent_child_rel\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = CD.a_parent_child_rel
+ and acyclic_heap\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = CD.a_acyclic_heap
+ and all_ptrs_in_heap\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = CD.a_all_ptrs_in_heap
+ and distinct_lists\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = CD.a_distinct_lists
+ and owner_document_valid\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M = CD.a_owner_document_valid
+ .
+
+interpretation i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M: l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M parent_child_rel
+ by (auto simp add: l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def parent_child_rel_def instances)
+declare i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_is_l_heap_is_wellformed [instances]:
+ "l_heap_is_wellformed type_wf known_ptr heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M parent_child_rel get_child_nodes
+get_disconnected_nodes"
+ apply(auto simp add: l_heap_is_wellformed_def)[1]
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.heap_is_wellformed_children_in_heap apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.heap_is_wellformed_disc_nodes_in_heap apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.heap_is_wellformed_one_parent apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.heap_is_wellformed_one_disc_parent apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.heap_is_wellformed_children_disc_nodes_different apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.heap_is_wellformed_disconnected_nodes_distinct apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.heap_is_wellformed_children_distinct apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.heap_is_wellformed_children_disc_nodes apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_child apply (blast, blast)
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_finite apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_acyclic apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_node_ptr apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_parent_in_heap apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_child_in_heap apply blast
+ done
+
+
+locale l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs
+ + CD: l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M parent_child_rel
+ + l_heap_is_wellformed_defs
+ heap_is_wellformed parent_child_rel
+ + l_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_shadow_root get_shadow_root_locs get_host get_host_locs type_wf
+ + l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs
+ get_disconnected_document get_disconnected_document_locs type_wf
+ + l_get_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root get_shadow_root_locs
+ for get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_document :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_disconnected_document_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set" +
+ assumes heap_is_wellformed_impl: "heap_is_wellformed = a_heap_is_wellformed"
+begin
+lemmas heap_is_wellformed_def = heap_is_wellformed_impl[unfolded a_heap_is_wellformed_def,
+ folded CD.heap_is_wellformed_impl CD.parent_child_rel_impl]
+
+lemma a_distinct_lists_code [code]: "a_all_ptrs_in_heap h = ((\<forall>host \<in> fset (element_ptr_kinds h).
+h \<turnstile> ok (get_shadow_root host) \<longrightarrow> (case |h \<turnstile> get_shadow_root host|\<^sub>r of
+ Some shadow_root_ptr \<Rightarrow> shadow_root_ptr |\<in>| shadow_root_ptr_kinds h |
+ None \<Rightarrow> True)))"
+ apply(auto simp add: a_all_ptrs_in_heap_def split: option.splits)[1]
+ by (meson is_OK_returns_result_I local.get_shadow_root_ptr_in_heap notin_fset select_result_I2)
+
+lemma get_shadow_root_shadow_root_ptr_in_heap:
+ assumes "heap_is_wellformed h"
+ assumes "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ shows "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ using assms
+ by(auto simp add: heap_is_wellformed_def a_all_ptrs_in_heap_def)
+
+lemma get_host_ptr_in_heap:
+ assumes "heap_is_wellformed h"
+ assumes "h \<turnstile> get_host shadow_root_ptr \<rightarrow>\<^sub>r host"
+ shows "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ using assms get_shadow_root_shadow_root_ptr_in_heap
+ by(auto simp add: get_host_def elim!: bind_returns_result_E2 dest!: filter_M_holds_for_result
+ intro!: bind_pure_I split: list.splits)
+
+lemma shadow_root_same_host:
+ assumes "heap_is_wellformed h" and "type_wf h"
+ assumes "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ assumes "h \<turnstile> get_shadow_root host' \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ shows "host = host'"
+proof (rule ccontr)
+ assume " host \<noteq> host'"
+ have "host |\<in>| element_ptr_kinds h"
+ using assms(3)
+ by (meson is_OK_returns_result_I local.get_shadow_root_ptr_in_heap)
+ moreover
+ have "host' |\<in>| element_ptr_kinds h"
+ using assms(4)
+ by (meson is_OK_returns_result_I local.get_shadow_root_ptr_in_heap)
+ ultimately show False
+ using assms
+ apply(auto simp add: heap_is_wellformed_def a_distinct_lists_def)[1]
+ apply(drule distinct_concat_map_E(1)[where x=host and y=host'])
+ apply(simp)
+ apply(simp)
+ using \<open>host \<noteq> host'\<close> apply(simp)
+ apply(auto)[1]
+ done
+qed
+
+lemma shadow_root_host_dual:
+ assumes "h \<turnstile> get_host shadow_root_ptr \<rightarrow>\<^sub>r host"
+ shows "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ using assms
+ by(auto simp add: get_host_def dest: filter_M_holds_for_result elim!: bind_returns_result_E2
+ intro!: bind_pure_I split: list.splits)
+
+lemma disc_doc_disc_node_dual:
+ assumes "h \<turnstile> get_disconnected_document disc_node \<rightarrow>\<^sub>r disc_doc"
+ obtains disc_nodes where "h \<turnstile> get_disconnected_nodes disc_doc \<rightarrow>\<^sub>r disc_nodes" and
+ "disc_node \<in> set disc_nodes"
+ using assms get_disconnected_nodes_pure
+ by(auto simp add: get_disconnected_document_def bind_pure_I
+ dest!: filter_M_holds_for_result
+ elim!: bind_returns_result_E2
+ intro!: filter_M_pure_I
+ split: if_splits list.splits)
+
+lemma get_host_valid_tag_name:
+ assumes "heap_is_wellformed h" and "type_wf h"
+ assumes "h \<turnstile> get_host shadow_root_ptr \<rightarrow>\<^sub>r host"
+ assumes "h \<turnstile> get_tag_name host \<rightarrow>\<^sub>r tag"
+ shows "tag \<in> safe_shadow_root_element_types"
+proof -
+ obtain host' where "host' |\<in>| element_ptr_kinds h" and
+ "|h \<turnstile> get_tag_name host'|\<^sub>r \<in> safe_shadow_root_element_types"
+ and "h \<turnstile> get_shadow_root host' \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ using assms
+ apply(auto simp add: heap_is_wellformed_def a_shadow_root_valid_def)[1]
+ by (smt assms(1) finite_set_in get_host_ptr_in_heap local.get_shadow_root_ok returns_result_select_result)
+ then have "host = host'"
+ by (meson assms(1) assms(2) assms(3) shadow_root_host_dual shadow_root_same_host)
+ then show ?thesis
+ by (smt \<open>\<And>thesis. (\<And>host'. \<lbrakk>host' |\<in>| element_ptr_kinds h; |h \<turnstile> get_tag_name host'|\<^sub>r \<in>
+safe_shadow_root_element_types; h \<turnstile> get_shadow_root host' \<rightarrow>\<^sub>r Some shadow_root_ptr\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow>
+thesis\<close> \<open>h \<turnstile> get_shadow_root host' \<rightarrow>\<^sub>r Some shadow_root_ptr\<close> assms(1) assms(2) assms(4)
+ select_result_I2 shadow_root_same_host)
+qed
+
+
+lemma a_host_shadow_root_rel_finite: "finite (a_host_shadow_root_rel h)"
+proof -
+ have "a_host_shadow_root_rel h = (\<Union>host \<in> fset (element_ptr_kinds h).
+(case |h \<turnstile> get_shadow_root host|\<^sub>r of Some shadow_root \<Rightarrow> {(cast host, cast shadow_root)} | None \<Rightarrow> {}))"
+ by(auto simp add: a_host_shadow_root_rel_def split: option.splits)
+ moreover have "finite (\<Union>host \<in> fset (element_ptr_kinds h). (case |h \<turnstile> get_shadow_root host|\<^sub>r of
+Some shadow_root \<Rightarrow> {(cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host, cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root)} | None \<Rightarrow> {}))"
+ by(auto split: option.splits)
+ ultimately show ?thesis
+ by auto
+qed
+
+lemma a_ptr_disconnected_node_rel_finite: "finite (a_ptr_disconnected_node_rel h)"
+proof -
+ have "a_ptr_disconnected_node_rel h = (\<Union>owner_document \<in> set |h \<turnstile> document_ptr_kinds_M|\<^sub>r.
+ (\<Union>disconnected_node \<in> set |h \<turnstile> get_disconnected_nodes owner_document|\<^sub>r.
+{(cast owner_document, cast disconnected_node)}))"
+ by(auto simp add: a_ptr_disconnected_node_rel_def)
+ moreover have "finite (\<Union>owner_document \<in> set |h \<turnstile> document_ptr_kinds_M|\<^sub>r.
+ (\<Union>disconnected_node \<in> set |h \<turnstile> get_disconnected_nodes owner_document|\<^sub>r.
+{(cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document, cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disconnected_node)}))"
+ by simp
+ ultimately show ?thesis
+ by simp
+qed
+
+
+lemma heap_is_wellformed_children_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> child \<in> set children \<Longrightarrow>
+child |\<in>| node_ptr_kinds h"
+ using CD.heap_is_wellformed_children_in_heap local.heap_is_wellformed_def by blast
+lemma heap_is_wellformed_disc_nodes_in_heap:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes \<Longrightarrow>
+node \<in> set disc_nodes \<Longrightarrow> node |\<in>| node_ptr_kinds h"
+ using CD.heap_is_wellformed_disc_nodes_in_heap local.heap_is_wellformed_def by blast
+lemma heap_is_wellformed_one_parent: "heap_is_wellformed h \<Longrightarrow>
+h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children' \<Longrightarrow>
+set children \<inter> set children' \<noteq> {} \<Longrightarrow> ptr = ptr'"
+ using CD.heap_is_wellformed_one_parent local.heap_is_wellformed_def by blast
+lemma heap_is_wellformed_one_disc_parent: "heap_is_wellformed h \<Longrightarrow>
+h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes \<Longrightarrow>
+h \<turnstile> get_disconnected_nodes document_ptr' \<rightarrow>\<^sub>r disc_nodes' \<Longrightarrow> set disc_nodes \<inter> set disc_nodes' \<noteq> {} \<Longrightarrow>
+document_ptr = document_ptr'"
+ using CD.heap_is_wellformed_one_disc_parent local.heap_is_wellformed_def by blast
+lemma heap_is_wellformed_children_disc_nodes_different: "heap_is_wellformed h \<Longrightarrow>
+h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes \<Longrightarrow>
+set children \<inter> set disc_nodes = {}"
+ using CD.heap_is_wellformed_children_disc_nodes_different local.heap_is_wellformed_def by blast
+lemma heap_is_wellformed_disconnected_nodes_distinct: "heap_is_wellformed h \<Longrightarrow>
+h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes \<Longrightarrow> distinct disc_nodes"
+ using CD.heap_is_wellformed_disconnected_nodes_distinct local.heap_is_wellformed_def by blast
+lemma heap_is_wellformed_children_distinct: "heap_is_wellformed h \<Longrightarrow>
+h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> distinct children"
+ using CD.heap_is_wellformed_children_distinct local.heap_is_wellformed_def by blast
+lemma heap_is_wellformed_children_disc_nodes: "heap_is_wellformed h \<Longrightarrow>
+node_ptr |\<in>| node_ptr_kinds h \<Longrightarrow> \<not>(\<exists>parent \<in> fset (object_ptr_kinds h).
+node_ptr \<in> set |h \<turnstile> get_child_nodes parent|\<^sub>r) \<Longrightarrow> (\<exists>document_ptr \<in> fset (document_ptr_kinds h).
+node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)"
+ using CD.heap_is_wellformed_children_disc_nodes local.heap_is_wellformed_def by blast
+lemma parent_child_rel_finite: "heap_is_wellformed h \<Longrightarrow> finite (parent_child_rel h)"
+ using CD.parent_child_rel_finite by blast
+lemma parent_child_rel_acyclic: "heap_is_wellformed h \<Longrightarrow> acyclic (parent_child_rel h)"
+ using CD.parent_child_rel_acyclic heap_is_wellformed_def by blast
+lemma parent_child_rel_child_in_heap: "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptr parent \<Longrightarrow>
+(parent, child_ptr) \<in> parent_child_rel h \<Longrightarrow> child_ptr |\<in>| object_ptr_kinds h"
+ using CD.parent_child_rel_child_in_heap local.heap_is_wellformed_def by blast
+end
+
+interpretation i_heap_is_wellformed?: l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs get_tag_name
+ get_tag_name_locs known_ptr type_wf heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_host get_host_locs get_disconnected_document get_disconnected_document_locs
+ by(auto simp add: l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def
+ l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def
+ parent_child_rel_def heap_is_wellformed_def instances)
+declare l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma heap_is_wellformed_is_l_heap_is_wellformed [instances]: "l_heap_is_wellformed
+ShadowRootClass.type_wf ShadowRootClass.known_ptr Shadow_DOM.heap_is_wellformed
+Shadow_DOM.parent_child_rel Shadow_DOM.get_child_nodes get_disconnected_nodes"
+ apply(auto simp add: l_heap_is_wellformed_def instances)[1]
+ using heap_is_wellformed_children_in_heap apply metis
+ using heap_is_wellformed_disc_nodes_in_heap apply metis
+ using heap_is_wellformed_one_parent apply blast
+ using heap_is_wellformed_one_disc_parent apply blast
+ using heap_is_wellformed_children_disc_nodes_different apply blast
+ using heap_is_wellformed_disconnected_nodes_distinct apply metis
+ using heap_is_wellformed_children_distinct apply metis
+ using heap_is_wellformed_children_disc_nodes apply metis
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_child apply(blast, blast)
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_finite apply blast
+ using parent_child_rel_acyclic apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_node_ptr apply blast
+ using i_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_parent_in_heap apply blast
+ using parent_child_rel_child_in_heap apply metis
+ done
+
+
+subsubsection \<open>get\_parent\<close>
+
+interpretation i_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M: l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes
+ get_child_nodes_locs known_ptrs get_parent get_parent_locs heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M parent_child_rel
+ get_disconnected_nodes
+ by(simp add: l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare i_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+interpretation i_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M: l_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes
+ get_child_nodes_locs known_ptrs get_parent get_parent_locs heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M parent_child_rel
+ get_disconnected_nodes get_disconnected_nodes_locs
+ by(auto simp add: l_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare i_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.l_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_is_l_get_parent_wf [instances]: "l_get_parent_wf type_wf known_ptr
+known_ptrs heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M parent_child_rel get_child_nodes get_parent"
+ apply(auto simp add: l_get_parent_wf_def l_get_parent_wf_axioms_def instances)[1]
+ using i_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.child_parent_dual apply fast
+ using i_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.heap_wellformed_induct apply metis
+ using i_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.heap_wellformed_induct_rev apply metis
+ using i_get_parent_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_parent apply fast
+ done
+
+
+subsubsection \<open>get\_disconnected\_nodes\<close>
+
+
+subsubsection \<open>set\_disconnected\_nodes\<close>
+
+
+paragraph \<open>get\_disconnected\_nodes\<close>
+
+interpretation i_set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M:
+ l_set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M parent_child_rel get_child_nodes
+ by (simp add: l_set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare i_set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.l_set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_is_l_set_disconnected_nodes_get_disconnected_nodes_wf [instances]:
+ "l_set_disconnected_nodes_get_disconnected_nodes_wf type_wf known_ptr heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+parent_child_rel get_child_nodes get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs"
+ apply(auto simp add: l_set_disconnected_nodes_get_disconnected_nodes_wf_def
+ l_set_disconnected_nodes_get_disconnected_nodes_wf_axioms_def instances)[1]
+ using i_set_disconnected_nodes_get_disconnected_nodes_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.remove_from_disconnected_nodes_removes
+ apply fast
+ done
+
+
+paragraph \<open>get\_root\_node\<close>
+
+interpretation i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M:
+ l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf known_ptrs heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M parent_child_rel
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs get_parent
+ get_parent_locs get_ancestors get_ancestors_locs get_root_node get_root_node_locs
+ by(simp add: l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_ancestors_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_is_l_get_ancestors_wf [instances]:
+ "l_get_ancestors_wf heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M parent_child_rel known_ptr known_ptrs type_wf
+get_ancestors get_ancestors_locs get_child_nodes get_parent"
+ apply(auto simp add: l_get_ancestors_wf_def l_get_ancestors_wf_axioms_def instances)[1]
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_ancestors_never_empty apply blast
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_ancestors_ok apply blast
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_ancestors_reads apply blast
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_ancestors_ptrs_in_heap apply blast
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_ancestors_remains_not_in_ancestors apply blast
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_ancestors_also_parent apply blast
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_ancestors_obtains_children apply blast
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_ancestors_parent_child_rel apply blast
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_ancestors_parent_child_rel apply blast
+ done
+
+lemma get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_is_l_get_root_node_wf [instances]:
+ "l_get_root_node_wf heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_root_node type_wf known_ptr known_ptrs
+get_ancestors get_parent"
+ apply(auto simp add: l_get_root_node_wf_def l_get_root_node_wf_axioms_def instances)[1]
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_root_node_ok apply blast
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_root_node_ptr_in_heap apply blast
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_root_node_root_in_heap apply blast
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_ancestors_same_root_node apply(blast, blast)
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_root_node_same_no_parent apply blast
+ (* using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_root_node_not_node_same apply blast *)
+ using i_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_root_node_parent_same apply (blast, blast)
+ done
+
+
+subsubsection \<open>to\_tree\_order\<close>
+
+interpretation i_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M: l_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes
+ get_child_nodes_locs to_tree_order known_ptrs get_parent get_parent_locs heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ parent_child_rel get_disconnected_nodes get_disconnected_nodes_locs
+ apply(simp add: l_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+ done
+declare i_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.l_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_is_l_to_tree_order_wf [instances]:
+ "l_to_tree_order_wf heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M parent_child_rel type_wf known_ptr known_ptrs
+to_tree_order get_parent get_child_nodes"
+ apply(auto simp add: l_to_tree_order_wf_def l_to_tree_order_wf_axioms_def instances)[1]
+ using i_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.to_tree_order_ok apply blast
+ using i_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.to_tree_order_ptrs_in_heap apply blast
+ using i_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.to_tree_order_parent_child_rel apply(blast, blast)
+ using i_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.to_tree_order_child2 apply blast
+ using i_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.to_tree_order_node_ptrs apply blast
+ using i_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.to_tree_order_child apply blast
+ using i_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.to_tree_order_ptr_in_result apply blast
+ using i_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.to_tree_order_parent apply blast
+ using i_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.to_tree_order_subset apply blast
+ done
+
+paragraph \<open>get\_root\_node\<close>
+
+interpretation i_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M: l_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf known_ptrs heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M parent_child_rel get_child_nodes
+ get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs get_parent get_parent_locs
+ get_ancestors get_ancestors_locs get_root_node get_root_node_locs to_tree_order
+ by(auto simp add: l_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare i_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.l_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_is_l_to_tree_order_wf_get_root_node_wf [instances]:
+ "l_to_tree_order_wf_get_root_node_wf type_wf known_ptr known_ptrs to_tree_order get_root_node heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M"
+ apply(auto simp add: l_to_tree_order_wf_get_root_node_wf_def l_to_tree_order_wf_get_root_node_wf_axioms_def instances)[1]
+ using i_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.to_tree_order_get_root_node apply blast
+ using i_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.to_tree_order_same_root apply blast
+ done
+
+subsubsection \<open>remove\_child\<close>
+
+interpretation i_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M: l_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs
+ set_child_nodes set_child_nodes_locs get_parent
+ get_parent_locs get_owner_document get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes
+ set_disconnected_nodes_locs remove_child remove_child_locs remove type_wf known_ptr known_ptrs
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ parent_child_rel
+ by unfold_locales
+declare i_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.l_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_is_l_remove_child_wf2 [instances]:
+ "l_remove_child_wf2 type_wf known_ptr known_ptrs remove_child heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes remove"
+ apply(auto simp add: l_remove_child_wf2_def l_remove_child_wf2_axioms_def instances)[1]
+ using i_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.remove_child_heap_is_wellformed_preserved apply(fast, fast, fast)
+ using i_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.remove_heap_is_wellformed_preserved apply(fast, fast, fast)
+ using i_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.remove_child_removes_child apply fast
+ using i_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.remove_child_removes_first_child apply fast
+ using i_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.remove_removes_child apply fast
+ using i_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.remove_for_all_empty_children apply fast
+ done
+
+
+subsection \<open>A wellformed heap\<close>
+
+subsubsection \<open>get\_parent\<close>
+
+interpretation i_get_parent_wf?: l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes
+ get_child_nodes_locs known_ptrs get_parent get_parent_locs heap_is_wellformed parent_child_rel
+ get_disconnected_nodes
+ using instances
+ by(simp add: l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def)
+declare l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_parent_wf_is_l_get_parent_wf [instances]: "l_get_parent_wf ShadowRootClass.type_wf
+ShadowRootClass.known_ptr ShadowRootClass.known_ptrs heap_is_wellformed parent_child_rel
+Shadow_DOM.get_child_nodes Shadow_DOM.get_parent"
+ apply(auto simp add: l_get_parent_wf_def l_get_parent_wf_axioms_def instances)[1]
+ using child_parent_dual apply blast
+ using heap_wellformed_induct apply metis
+ using heap_wellformed_induct_rev apply metis
+ using parent_child_rel_parent apply metis
+ done
+
+
+
+subsubsection \<open>remove\_shadow\_root\<close>
+
+locale l_remove_shadow_root_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_tag_name +
+ l_get_disconnected_nodes +
+ l_set_shadow_root_get_tag_name +
+ l_get_child_nodes +
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_delete_shadow_root_get_disconnected_nodes +
+ l_delete_shadow_root_get_child_nodes +
+ l_set_shadow_root_get_disconnected_nodes +
+ l_set_shadow_root_get_child_nodes +
+ l_delete_shadow_root_get_tag_name +
+ l_set_shadow_root_get_shadow_root +
+ l_delete_shadow_root_get_shadow_root +
+ l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma remove_shadow_root_preserves:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> remove_shadow_root ptr \<rightarrow>\<^sub>h h'"
+ shows "known_ptrs h'" and "type_wf h'" "heap_is_wellformed h'"
+proof -
+ obtain shadow_root_ptr h2 where
+ "h \<turnstile> get_shadow_root ptr \<rightarrow>\<^sub>r Some shadow_root_ptr" and
+ "h \<turnstile> get_child_nodes (cast shadow_root_ptr) \<rightarrow>\<^sub>r []" and
+ "h \<turnstile> get_disconnected_nodes (cast shadow_root_ptr) \<rightarrow>\<^sub>r []" and
+ h2: "h \<turnstile> set_shadow_root ptr None \<rightarrow>\<^sub>h h2" and
+ h': "h2 \<turnstile> delete_M shadow_root_ptr \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ by(auto simp add: remove_shadow_root_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_shadow_root_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ split: option.splits if_splits)
+
+ have "type_wf h2"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_shadow_root_writes h2]
+ using \<open>type_wf h\<close> set_shadow_root_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then show "type_wf h'"
+ using h' delete_shadow_root_type_wf_preserved local.type_wf_impl
+ by blast
+
+ have object_ptr_kinds_eq_h: "object_ptr_kinds h = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_shadow_root_writes h2])
+ using set_shadow_root_pointers_preserved
+ apply blast
+ by (auto simp add: reflp_def transp_def)
+ have node_ptr_kinds_eq_h: "node_ptr_kinds h = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h
+ by (simp add: node_ptr_kinds_def)
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h = element_ptr_kinds h2"
+ using node_ptr_kinds_eq_h
+ by (simp add: element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h = document_ptr_kinds h2"
+ using object_ptr_kinds_eq_h
+ by (simp add: document_ptr_kinds_def)
+ have shadow_root_ptr_kinds_eq_h: "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h2"
+ using object_ptr_kinds_eq_h
+ by (simp add: document_ptr_kinds_eq_h shadow_root_ptr_kinds_def)
+
+ have "known_ptrs h2"
+ using \<open>known_ptrs h\<close> object_ptr_kinds_eq_h known_ptrs_subset
+ by blast
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h' |\<subseteq>| object_ptr_kinds h2"
+ using h' delete_shadow_root_pointers
+ by auto
+ have object_ptr_kinds_eq2_h2: "object_ptr_kinds h2 = object_ptr_kinds h' |\<union>| {|cast shadow_root_ptr|}"
+ using h' delete_shadow_root_pointers
+ by auto
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h2 = node_ptr_kinds h'"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def delete_shadow_root_pointers[OF h'])
+ have element_ptr_kinds_eq_h2: "element_ptr_kinds h2 = element_ptr_kinds h'"
+ using node_ptr_kinds_eq_h2
+ by (simp add: element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h2: "document_ptr_kinds h2 = document_ptr_kinds h' |\<union>| {|cast shadow_root_ptr|}"
+ using object_ptr_kinds_eq_h2
+ apply(auto simp add: document_ptr_kinds_def delete_shadow_root_pointers[OF h'])[1]
+ using document_ptr_kinds_def by fastforce
+ then
+ have document_ptr_kinds_eq2_h2: "document_ptr_kinds h' |\<subseteq>| document_ptr_kinds h2"
+ using h' delete_shadow_root_pointers
+ by auto
+ have shadow_root_ptr_kinds_eq_h2: "shadow_root_ptr_kinds h' |\<subseteq>| shadow_root_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ apply(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)[1]
+ by auto
+ have shadow_root_ptr_kinds_eq2_h2: "shadow_root_ptr_kinds h2 = shadow_root_ptr_kinds h' |\<union>| {|shadow_root_ptr|}"
+ using object_ptr_kinds_eq2_h2
+ apply (auto simp add: shadow_root_ptr_kinds_def)[1]
+ using document_ptr_kinds_eq_h2 apply auto[1]
+ apply (metis \<open>h \<turnstile> get_shadow_root ptr \<rightarrow>\<^sub>r Some shadow_root_ptr\<close> assms(1) document_ptr_kinds_eq_h
+ fset.map_comp local.get_shadow_root_shadow_root_ptr_in_heap shadow_root_ptr_kinds_def)
+ using document_ptr_kinds_eq_h2 by auto
+
+ show "known_ptrs h'"
+ using object_ptr_kinds_eq_h2 \<open>known_ptrs h2\<close> known_ptrs_subset
+ by blast
+
+
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes =
+h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_shadow_root_writes h2 set_shadow_root_get_disconnected_nodes
+ by(rule reads_writes_preserved)
+ then have disconnected_nodes_eq2_h:
+ "\<And>doc_ptr. |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. doc_ptr \<noteq> cast shadow_root_ptr \<Longrightarrow> h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes =
+h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads get_disconnected_nodes_delete_shadow_root[rotated, OF h']
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by(metis (no_types, lifting))+
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. doc_ptr \<noteq> cast shadow_root_ptr \<Longrightarrow> |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r =
+|h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have tag_name_eq_h:
+ "\<And>doc_ptr disc_nodes. h \<turnstile> get_tag_name doc_ptr \<rightarrow>\<^sub>r disc_nodes =
+h2 \<turnstile> get_tag_name doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_tag_name_reads set_shadow_root_writes h2 set_shadow_root_get_tag_name
+ by(rule reads_writes_preserved)
+ then have tag_name_eq2_h: "\<And>doc_ptr. |h \<turnstile> get_tag_name doc_ptr|\<^sub>r = |h2 \<turnstile> get_tag_name doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have tag_name_eq_h2:
+ "\<And>doc_ptr disc_nodes. h2 \<turnstile> get_tag_name doc_ptr \<rightarrow>\<^sub>r disc_nodes = h' \<turnstile> get_tag_name doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_tag_name_reads get_tag_name_delete_shadow_root[OF h']
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have tag_name_eq2_h2: "\<And>doc_ptr. |h2 \<turnstile> get_tag_name doc_ptr|\<^sub>r = |h' \<turnstile> get_tag_name doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+
+ have children_eq_h:
+ "\<And>ptr' children. h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_shadow_root_writes h2 set_shadow_root_get_child_nodes
+ by(rule reads_writes_preserved)
+
+ then have children_eq2_h: "\<And>ptr'. |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+
+ have children_eq_h2:
+ "\<And>ptr' children. ptr' \<noteq> cast shadow_root_ptr \<Longrightarrow> h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children =
+h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads h' get_child_nodes_delete_shadow_root
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h2:
+ "\<And>ptr'. ptr' \<noteq> cast shadow_root_ptr \<Longrightarrow> |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "cast shadow_root_ptr |\<notin>| object_ptr_kinds h'"
+ using h' delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_not_in_heap
+ by auto
+
+ have get_shadow_root_eq_h:
+ "\<And>shadow_root_opt ptr'. ptr \<noteq> ptr' \<Longrightarrow> h \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_opt =
+h2 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_opt"
+ using get_shadow_root_reads set_shadow_root_writes h2
+ apply(rule reads_writes_preserved)
+ using set_shadow_root_get_shadow_root_different_pointers
+ by fast
+
+ have get_shadow_root_eq_h2:
+ "\<And>shadow_root_opt ptr'. h2 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_opt =
+h' \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_opt"
+ using get_shadow_root_reads get_shadow_root_delete_shadow_root[OF h']
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then
+ have get_shadow_root_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_shadow_root ptr'|\<^sub>r = |h' \<turnstile> get_shadow_root ptr'|\<^sub>r"
+ using select_result_eq by force
+
+
+
+ have "acyclic (parent_child_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def CD.acyclic_heap_def)
+ moreover
+ have "parent_child_rel h = parent_child_rel h2"
+ by(auto simp add: CD.parent_child_rel_def object_ptr_kinds_eq_h children_eq2_h)
+ moreover
+ have "parent_child_rel h' \<subseteq> parent_child_rel h2"
+ using object_ptr_kinds_eq_h2
+ apply(auto simp add: CD.parent_child_rel_def)[1]
+ by (metis \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close> children_eq2_h2)
+ ultimately
+ have "CD.a_acyclic_heap h'"
+ using acyclic_subset
+ by (auto simp add: heap_is_wellformed_def CD.heap_is_wellformed_def CD.acyclic_heap_def)
+
+ moreover
+ have "CD.a_all_ptrs_in_heap h"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_all_ptrs_in_heap h2"
+ apply(auto simp add: CD.a_all_ptrs_in_heap_def object_ptr_kinds_eq_h node_ptr_kinds_def
+ children_eq_h disconnected_nodes_eq_h)[1]
+ apply (metis (no_types, lifting) children_eq2_h finite_set_in subsetD)
+ by (metis (no_types, lifting) disconnected_nodes_eq2_h document_ptr_kinds_eq_h
+ finite_set_in in_mono)
+ then have "CD.a_all_ptrs_in_heap h'"
+ apply(auto simp add: CD.a_all_ptrs_in_heap_def node_ptr_kinds_eq_h2 children_eq_h2
+ disconnected_nodes_eq_h2)[1]
+ apply(case_tac "ptr = cast shadow_root_ptr")
+ using object_ptr_kinds_eq_h2 children_eq_h2
+ apply (meson \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close>
+ is_OK_returns_result_I local.get_child_nodes_ptr_in_heap)
+ apply(auto dest!: children_eq_h2)[1]
+ using assms(1) children_eq_h local.heap_is_wellformed_children_in_heap node_ptr_kinds_eq_h
+ node_ptr_kinds_eq_h2 apply blast
+ apply (meson \<open>known_ptrs h'\<close> \<open>type_wf h'\<close> local.get_child_nodes_ok local.known_ptrs_known_ptr
+ returns_result_select_result)
+ by (metis (no_types, lifting) \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close>
+ \<open>type_wf h2\<close> assms(1) disconnected_nodes_eq2_h2 disconnected_nodes_eq_h document_ptr_kinds_commutes
+ document_ptr_kinds_eq2_h2 fin_mono local.get_disconnected_nodes_ok
+ local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_eq_h node_ptr_kinds_eq_h2
+ returns_result_select_result)
+
+ moreover
+ have "CD.a_distinct_lists h"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_distinct_lists h2"
+ by(auto simp add: CD.a_distinct_lists_def object_ptr_kinds_eq_h document_ptr_kinds_eq_h
+ children_eq2_h disconnected_nodes_eq2_h)
+ then have "CD.a_distinct_lists h'"
+ apply(auto simp add: CD.a_distinct_lists_def document_ptr_kinds_eq_h2 disconnected_nodes_eq2_h2)[1]
+ apply(auto simp add: intro!: distinct_concat_map_I)[1]
+ apply(case_tac "x = cast shadow_root_ptr")
+ using \<open>cast shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close> apply simp
+ using children_eq_h2 concat_map_all_distinct[of "(\<lambda>ptr. |h2 \<turnstile> get_child_nodes ptr|\<^sub>r)"]
+ apply (metis (no_types, lifting) children_eq2_h2 finite_fset fmember.rep_eq fset_mp
+ object_ptr_kinds_eq_h2 set_sorted_list_of_set)
+ apply(case_tac "x = cast shadow_root_ptr")
+ using \<open>cast shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close> apply simp
+ apply(case_tac "y = cast shadow_root_ptr")
+ using \<open>cast shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close> apply simp
+ using children_eq_h2 distinct_concat_map_E(1)[of "(\<lambda>ptr. |h2 \<turnstile> get_child_nodes ptr|\<^sub>r)"]
+ apply (smt IntI children_eq2_h2 empty_iff finite_fset fmember.rep_eq fset_mp
+ object_ptr_kinds_eq_h2 set_sorted_list_of_set)
+
+ apply(auto simp add: intro!: distinct_concat_map_I)[1]
+ apply(case_tac "x = cast shadow_root_ptr")
+ using \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close> document_ptr_kinds_commutes
+ apply blast
+ apply (metis (mono_tags, lifting) \<open>local.CD.a_distinct_lists h2\<close> \<open>type_wf h'\<close>
+ disconnected_nodes_eq_h2 is_OK_returns_result_E local.CD.distinct_lists_disconnected_nodes
+ local.get_disconnected_nodes_ok select_result_I2)
+ apply(case_tac "x = cast shadow_root_ptr")
+ using \<open>cast shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close> apply simp
+ apply(case_tac "y = cast shadow_root_ptr")
+ using \<open>cast shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close> apply simp
+ proof -
+ fix x and y and xa
+ assume a1: "x |\<in>| document_ptr_kinds h'"
+ assume a2: "y |\<in>| document_ptr_kinds h'"
+ assume a3: "x \<noteq> y"
+ assume a4: "x \<noteq> cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr"
+ assume a5: "y \<noteq> cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr"
+ assume a6: "xa \<in> set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ assume a7: "xa \<in> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ assume "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+(insort (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) (sorted_list_of_set (fset (document_ptr_kinds h') -
+{cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr})))))"
+ then show False
+ using a7 a6 a5 a4 a3 a2 a1 by (metis (no_types) IntI
+ distinct_concat_map_E(1)[of "(\<lambda>ptr. |h2 \<turnstile> get_disconnected_nodes ptr|\<^sub>r)"] disconnected_nodes_eq2_h2
+ empty_iff finite_fset finsert.rep_eq fmember.rep_eq insert_iff set_sorted_list_of_set
+ sorted_list_of_set.insert_remove)
+ next
+ fix x xa xb
+ assume 0: "distinct (concat (map (\<lambda>ptr. |h2 \<turnstile> get_child_nodes ptr|\<^sub>r)
+(sorted_list_of_set (fset (object_ptr_kinds h2)))))"
+ and 1: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+(insort (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) (sorted_list_of_set (fset (document_ptr_kinds h') -
+{cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr})))))"
+ and 2: "(\<Union>x\<in>fset (object_ptr_kinds h2). set |h2 \<turnstile> get_child_nodes x|\<^sub>r) \<inter>
+(\<Union>x\<in>set (insort (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) (sorted_list_of_set (fset (document_ptr_kinds h') -
+{cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr}))). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 3: "xa |\<in>| object_ptr_kinds h'"
+ and 4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 5: "xb |\<in>| document_ptr_kinds h'"
+ and 6: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ then show "False"
+ apply(cases "xa = cast shadow_root_ptr")
+ using \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close> apply blast
+ apply(cases "xb = cast shadow_root_ptr")
+ using \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close> document_ptr_kinds_commutes
+ apply blast
+ by (metis (no_types, hide_lams) \<open>local.CD.a_distinct_lists h2\<close> \<open>type_wf h'\<close> children_eq2_h2
+ disconnected_nodes_eq_h2 fset_rev_mp is_OK_returns_result_E local.CD.distinct_lists_no_parent
+ local.get_disconnected_nodes_ok object_ptr_kinds_eq_h2 select_result_I2)
+ qed
+ moreover
+ have "CD.a_owner_document_valid h"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_owner_document_valid h2"
+ by(auto simp add: CD.a_owner_document_valid_def object_ptr_kinds_eq_h document_ptr_kinds_eq_h
+ node_ptr_kinds_eq_h children_eq2_h disconnected_nodes_eq2_h)
+ then have "CD.a_owner_document_valid h'"
+ apply(auto simp add: CD.a_owner_document_valid_def document_ptr_kinds_eq_h2 node_ptr_kinds_eq_h2
+ disconnected_nodes_eq2_h2)[1]
+ by (smt \<open>h \<turnstile> get_child_nodes (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) \<rightarrow>\<^sub>r []\<close>
+ \<open>h \<turnstile> get_disconnected_nodes (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) \<rightarrow>\<^sub>r []\<close> \<open>local.CD.a_distinct_lists h\<close>
+ children_eq2_h children_eq2_h2 disconnected_nodes_eq2_h disconnected_nodes_eq2_h2 finite_set_in finsert_iff
+ funion_finsert_right local.CD.distinct_lists_no_parent object_ptr_kinds_eq2_h2 object_ptr_kinds_eq_h
+ select_result_I2 sup_bot.comm_neutral)
+
+ ultimately have "heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M h'"
+ by(simp add: CD.heap_is_wellformed_def)
+
+ moreover
+ have "acyclic (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by(simp add: heap_is_wellformed_def)
+ then
+ have "acyclic (parent_child_rel h2 \<union> a_host_shadow_root_rel h2 \<union> a_ptr_disconnected_node_rel h2)"
+ proof -
+ have "a_host_shadow_root_rel h2 \<subseteq> a_host_shadow_root_rel h"
+ apply(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h)[1]
+ apply(case_tac "aa = ptr")
+ apply(simp)
+ apply (metis (no_types, lifting) \<open>type_wf h2\<close> assms(2) h2 local.get_shadow_root_ok
+ local.type_wf_impl option.distinct(1) returns_result_eq returns_result_select_result
+ set_shadow_root_get_shadow_root)
+ using get_shadow_root_eq_h
+ by (metis (mono_tags, lifting) \<open>type_wf h2\<close> image_eqI is_OK_returns_result_E
+ local.get_shadow_root_ok mem_Collect_eq prod.simps(2) select_result_I2)
+ moreover have "a_ptr_disconnected_node_rel h = a_ptr_disconnected_node_rel h2"
+ by (simp add: a_ptr_disconnected_node_rel_def disconnected_nodes_eq2_h document_ptr_kinds_eq_h)
+ ultimately show ?thesis
+ using \<open>parent_child_rel h = parent_child_rel h2\<close>
+ by (smt \<open>acyclic (parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union>
+local.a_ptr_disconnected_node_rel h)\<close> acyclic_subset subset_refl sup_mono)
+ qed
+ then
+ have "acyclic (parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h')"
+ proof -
+ have "a_host_shadow_root_rel h' \<subseteq> a_host_shadow_root_rel h2"
+ by(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h2 get_shadow_root_eq2_h2)
+ moreover have "a_ptr_disconnected_node_rel h2 = a_ptr_disconnected_node_rel h'"
+ apply(simp add: a_ptr_disconnected_node_rel_def disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2)
+ by (metis (no_types, lifting) \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close>
+ \<open>h \<turnstile> get_child_nodes (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) \<rightarrow>\<^sub>r []\<close>
+ \<open>h \<turnstile> get_disconnected_nodes (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr) \<rightarrow>\<^sub>r []\<close> \<open>local.CD.a_distinct_lists h\<close>
+ disconnected_nodes_eq2_h disconnected_nodes_eq2_h2 document_ptr_kinds_commutes is_OK_returns_result_I
+ local.CD.distinct_lists_no_parent local.get_disconnected_nodes_ptr_in_heap select_result_I2)
+ ultimately show ?thesis
+ using \<open>parent_child_rel h' \<subseteq> parent_child_rel h2\<close>
+ \<open>acyclic (parent_child_rel h2 \<union> a_host_shadow_root_rel h2 \<union> a_ptr_disconnected_node_rel h2)\<close>
+ using acyclic_subset order_refl sup_mono
+ by (metis (no_types, hide_lams))
+ qed
+
+ moreover
+ have "a_all_ptrs_in_heap h"
+ using \<open>heap_is_wellformed h\<close>
+ by(simp add: heap_is_wellformed_def)
+ then
+ have "a_all_ptrs_in_heap h2"
+ apply(auto simp add: a_all_ptrs_in_heap_def shadow_root_ptr_kinds_eq_h)[1]
+ apply(case_tac "host = ptr")
+ apply(simp)
+ apply (metis assms(2) h2 local.type_wf_impl option.distinct(1) returns_result_eq
+ set_shadow_root_get_shadow_root)
+ using get_shadow_root_eq_h
+ by fastforce
+ then
+ have "a_all_ptrs_in_heap h'"
+ apply(auto simp add: a_all_ptrs_in_heap_def get_shadow_root_eq_h2)[1]
+ apply(auto simp add: shadow_root_ptr_kinds_eq2_h2)[1]
+ by (metis (no_types, lifting) \<open>h \<turnstile> get_shadow_root ptr \<rightarrow>\<^sub>r Some shadow_root_ptr\<close> assms(1) assms(2)
+ get_shadow_root_eq_h get_shadow_root_eq_h2 h2 local.shadow_root_same_host local.type_wf_impl
+ option.distinct(1) select_result_I2 set_shadow_root_get_shadow_root)
+
+ moreover
+ have "a_distinct_lists h"
+ using \<open>heap_is_wellformed h\<close>
+ by(simp add: heap_is_wellformed_def)
+ then
+ have "a_distinct_lists h2"
+ apply(auto simp add: a_distinct_lists_def element_ptr_kinds_eq_h)[1]
+ apply(auto intro!: distinct_concat_map_I split: option.splits)[1]
+ apply(case_tac "x = ptr")
+ apply(simp)
+ apply (metis (no_types, hide_lams) assms(2) h2 is_OK_returns_result_I
+ l_set_shadow_root_get_shadow_root.set_shadow_root_get_shadow_root
+ l_set_shadow_root_get_shadow_root_axioms local.type_wf_impl option.discI returns_result_eq
+ returns_result_select_result)
+
+ apply(case_tac "y = ptr")
+ apply(simp)
+ apply (metis (no_types, hide_lams) assms(2) h2 is_OK_returns_result_I
+ l_set_shadow_root_get_shadow_root.set_shadow_root_get_shadow_root
+ l_set_shadow_root_get_shadow_root_axioms local.type_wf_impl option.discI returns_result_eq
+ returns_result_select_result)
+ by (metis \<open>type_wf h2\<close> assms(1) assms(2) get_shadow_root_eq_h local.get_shadow_root_ok
+ local.shadow_root_same_host returns_result_select_result)
+
+ then
+ have "a_distinct_lists h'"
+ by(auto simp add: a_distinct_lists_def element_ptr_kinds_eq_h2 get_shadow_root_eq2_h2)
+
+ moreover
+ have "a_shadow_root_valid h"
+ using \<open>heap_is_wellformed h\<close>
+ by(simp add: heap_is_wellformed_def)
+ then
+ have "a_shadow_root_valid h'"
+ apply(auto simp add: a_shadow_root_valid_def shadow_root_ptr_kinds_eq_h element_ptr_kinds_eq_h
+ tag_name_eq2_h)[1]
+ apply(simp add: shadow_root_ptr_kinds_eq2_h2 element_ptr_kinds_eq_h2 tag_name_eq2_h2)
+ using get_shadow_root_eq_h get_shadow_root_eq_h2
+ by (smt \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr |\<notin>| object_ptr_kinds h'\<close>
+ \<open>h \<turnstile> get_shadow_root ptr \<rightarrow>\<^sub>r Some shadow_root_ptr\<close> assms(2) document_ptr_kinds_commutes
+ element_ptr_kinds_eq_h element_ptr_kinds_eq_h2 finite_set_in local.get_shadow_root_ok
+ option.inject returns_result_select_result select_result_I2 shadow_root_ptr_kinds_commutes)
+
+ ultimately show "heap_is_wellformed h'"
+ by(simp add: heap_is_wellformed_def)
+qed
+end
+interpretation i_remove_shadow_root_wf?: l_remove_shadow_root_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf get_tag_name get_tag_name_locs get_disconnected_nodes get_disconnected_nodes_locs
+ set_shadow_root set_shadow_root_locs known_ptr get_child_nodes get_child_nodes_locs get_shadow_root
+ get_shadow_root_locs heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host
+ get_host_locs get_disconnected_document get_disconnected_document_locs remove_shadow_root
+ remove_shadow_root_locs known_ptrs get_parent get_parent_locs
+ by(auto simp add: l_remove_shadow_root_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_remove_shadow_root_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+
+subsubsection \<open>get\_root\_node\<close>
+
+interpretation i_get_root_node_wf?:
+ l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf known_ptrs heap_is_wellformed parent_child_rel
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs get_parent
+ get_parent_locs get_ancestors get_ancestors_locs get_root_node get_root_node_locs
+ by(simp add: l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms[instances]
+
+lemma get_ancestors_wf_is_l_get_ancestors_wf [instances]:
+ "l_get_ancestors_wf heap_is_wellformed parent_child_rel known_ptr known_ptrs type_wf get_ancestors
+get_ancestors_locs get_child_nodes get_parent"
+ apply(auto simp add: l_get_ancestors_wf_def l_get_ancestors_wf_axioms_def instances)[1]
+ using get_ancestors_never_empty apply blast
+ using get_ancestors_ok apply blast
+ using get_ancestors_reads apply blast
+ using get_ancestors_ptrs_in_heap apply blast
+ using get_ancestors_remains_not_in_ancestors apply blast
+ using get_ancestors_also_parent apply blast
+ using get_ancestors_obtains_children apply blast
+ using get_ancestors_parent_child_rel apply blast
+ using get_ancestors_parent_child_rel apply blast
+ done
+
+lemma get_root_node_wf_is_l_get_root_node_wf [instances]:
+ "l_get_root_node_wf heap_is_wellformed get_root_node type_wf known_ptr known_ptrs get_ancestors get_parent"
+ using known_ptrs_is_l_known_ptrs
+ apply(auto simp add: l_get_root_node_wf_def l_get_root_node_wf_axioms_def)[1]
+ using get_root_node_ok apply blast
+ using get_root_node_ptr_in_heap apply blast
+ using get_root_node_root_in_heap apply blast
+ using get_ancestors_same_root_node apply(blast, blast)
+ using get_root_node_same_no_parent apply blast
+ (* using get_root_node_not_node_same apply blast *)
+ using get_root_node_parent_same apply (blast, blast)
+ done
+
+subsubsection \<open>get\_parent\_get\_host\_get\_disconnected\_document\<close>
+
+locale l_get_parent_get_host_get_disconnected_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs
+ known_ptr type_wf heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs
+ get_disconnected_document get_disconnected_document_locs +
+ l_get_disconnected_document get_disconnected_document get_disconnected_document_locs +
+ l_get_disconnected_nodes type_wf get_disconnected_nodes get_disconnected_nodes_locs +
+ l_get_parent_wf type_wf known_ptr known_ptrs heap_is_wellformed parent_child_rel get_child_nodes
+ get_child_nodes_locs get_parent get_parent_locs +
+ l_get_shadow_root type_wf get_shadow_root get_shadow_root_locs +
+ l_get_host get_host get_host_locs +
+ l_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs
+ for get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_document :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_disconnected_document_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and get_parent :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) object_ptr option) prog"
+ and get_parent_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+begin
+lemma a_host_shadow_root_rel_shadow_root:
+ "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r shadow_root_option \<Longrightarrow> shadow_root_option = Some shadow_root \<longleftrightarrow>
+((cast host, cast shadow_root) \<in> a_host_shadow_root_rel h)"
+ apply(auto simp add: a_host_shadow_root_rel_def)[1]
+ by(metis (mono_tags, lifting) case_prodI is_OK_returns_result_I
+ l_get_shadow_root.get_shadow_root_ptr_in_heap local.l_get_shadow_root_axioms mem_Collect_eq
+ pair_imageI select_result_I2)
+
+lemma a_host_shadow_root_rel_host:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_host shadow_root \<rightarrow>\<^sub>r host \<Longrightarrow>
+((cast host, cast shadow_root) \<in> a_host_shadow_root_rel h)"
+ apply(auto simp add: a_host_shadow_root_rel_def)[1]
+ using shadow_root_host_dual
+ by (metis (no_types, lifting) Collect_cong a_host_shadow_root_rel_shadow_root
+ local.a_host_shadow_root_rel_def split_cong)
+
+lemma a_ptr_disconnected_node_rel_disconnected_node:
+ "h \<turnstile> get_disconnected_nodes document \<rightarrow>\<^sub>r disc_nodes \<Longrightarrow> node_ptr \<in> set disc_nodes \<longleftrightarrow>
+(cast document, cast node_ptr) \<in> a_ptr_disconnected_node_rel h"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def)[1]
+ by (smt CD.get_disconnected_nodes_ptr_in_heap case_prodI is_OK_returns_result_I mem_Collect_eq
+ pair_imageI select_result_I2)
+
+lemma a_ptr_disconnected_node_rel_document:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> get_disconnected_document node_ptr \<rightarrow>\<^sub>r document \<Longrightarrow>
+(cast document, cast node_ptr) \<in> a_ptr_disconnected_node_rel h"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def)[1]
+ using disc_doc_disc_node_dual
+ by (metis (no_types, lifting) local.a_ptr_disconnected_node_rel_def
+ a_ptr_disconnected_node_rel_disconnected_node)
+
+lemma heap_wellformed_induct_si [consumes 1, case_names step]:
+ assumes "heap_is_wellformed h"
+ assumes "\<And>parent. (\<And>children child. h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children \<Longrightarrow> child \<in> set children \<Longrightarrow>
+P (cast child))
+ \<Longrightarrow> (\<And>shadow_root host. parent = cast host \<Longrightarrow> h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root \<Longrightarrow>
+ P (cast shadow_root))
+ \<Longrightarrow> (\<And>owner_document disc_nodes node_ptr. parent = cast owner_document \<Longrightarrow>
+h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes \<Longrightarrow> node_ptr \<in> set disc_nodes \<Longrightarrow> P (cast node_ptr))
+ \<Longrightarrow> P parent"
+ shows "P ptr"
+proof -
+ fix ptr
+ have "finite (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)"
+ using a_host_shadow_root_rel_finite a_ptr_disconnected_node_rel_finite
+ using local.CD.parent_child_rel_finite local.CD.parent_child_rel_impl
+ by auto
+ then
+ have "wf ((parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<inverse>)"
+ using assms(1)
+ apply(simp add: heap_is_wellformed_def)
+ by (simp add: finite_acyclic_wf_converse local.CD.parent_child_rel_impl)
+ then show "?thesis"
+ proof (induct rule: wf_induct_rule)
+ case (less parent)
+ then show ?case
+ apply(auto)[1]
+ using assms a_ptr_disconnected_node_rel_disconnected_node a_host_shadow_root_rel_shadow_root
+ local.CD.parent_child_rel_child
+ by blast
+ qed
+qed
+
+lemma heap_wellformed_induct_rev_si [consumes 1, case_names step]:
+ assumes "heap_is_wellformed h"
+ assumes "\<And>child. (\<And>parent child_node. child = cast child_node \<Longrightarrow>
+h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent \<Longrightarrow> P parent)
+ \<Longrightarrow> (\<And>host shadow_root. child = cast shadow_root \<Longrightarrow> h \<turnstile> get_host shadow_root \<rightarrow>\<^sub>r host \<Longrightarrow>
+P (cast host))
+ \<Longrightarrow> (\<And>disc_doc disc_node. child = cast disc_node \<Longrightarrow>
+h \<turnstile> get_disconnected_document disc_node \<rightarrow>\<^sub>r disc_doc\<Longrightarrow> P (cast disc_doc))
+ \<Longrightarrow> P child"
+ shows "P ptr"
+proof -
+ fix ptr
+ have "finite (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)"
+ using a_host_shadow_root_rel_finite a_ptr_disconnected_node_rel_finite
+ using local.CD.parent_child_rel_finite local.CD.parent_child_rel_impl
+ by auto
+ then
+ have "wf (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)"
+ using assms(1)
+ apply(simp add: heap_is_wellformed_def)
+ by (simp add: finite_acyclic_wf)
+ then show "?thesis"
+ proof (induct rule: wf_induct_rule)
+ case (less parent)
+ then show ?case
+ apply(auto)[1]
+ using parent_child_rel_parent a_host_shadow_root_rel_host a_ptr_disconnected_node_rel_document
+ using assms(1) assms(2) by auto
+ qed
+qed
+end
+
+interpretation i_get_parent_get_host_get_disconnected_document_wf?:
+ l_get_parent_get_host_get_disconnected_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs known_ptr type_wf heap_is_wellformed
+ parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document
+ get_disconnected_document_locs known_ptrs get_parent get_parent_locs
+ by(auto simp add: l_get_parent_get_host_get_disconnected_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_parent_get_host_get_disconnected_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+locale l_get_parent_get_host_wf =
+ l_heap_is_wellformed_defs +
+ l_get_parent_defs +
+ l_get_shadow_root_defs +
+ l_get_host_defs +
+ l_get_child_nodes_defs +
+ l_get_disconnected_document_defs +
+ l_get_disconnected_nodes_defs +
+ assumes heap_wellformed_induct_si [consumes 1, case_names step]:
+ "heap_is_wellformed h
+ \<Longrightarrow> (\<And>parent. (\<And>children child. h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children \<Longrightarrow>
+child \<in> set children \<Longrightarrow> P (cast child))
+ \<Longrightarrow> (\<And>shadow_root host. parent = cast host \<Longrightarrow>
+h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root \<Longrightarrow> P (cast shadow_root))
+ \<Longrightarrow> (\<And>owner_document disc_nodes node_ptr. parent = cast owner_document \<Longrightarrow>
+h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes \<Longrightarrow> node_ptr \<in> set disc_nodes \<Longrightarrow>
+P (cast node_ptr))
+ \<Longrightarrow> P parent)
+ \<Longrightarrow> P ptr"
+ assumes heap_wellformed_induct_rev_si [consumes 1, case_names step]:
+ "heap_is_wellformed h
+ \<Longrightarrow> (\<And>child. (\<And>parent child_node. child = cast child_node \<Longrightarrow>
+h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent \<Longrightarrow> P parent)
+ \<Longrightarrow> (\<And>host shadow_root. child = cast shadow_root \<Longrightarrow>
+h \<turnstile> get_host shadow_root \<rightarrow>\<^sub>r host \<Longrightarrow> P (cast host))
+ \<Longrightarrow> (\<And>disc_doc disc_node. child = cast disc_node \<Longrightarrow>
+h \<turnstile> get_disconnected_document disc_node \<rightarrow>\<^sub>r disc_doc \<Longrightarrow> P (cast disc_doc))
+ \<Longrightarrow> P child)
+ \<Longrightarrow> P ptr"
+
+lemma l_get_parent_get_host_wf_is_get_parent_get_host_wf [instances]:
+ "l_get_parent_get_host_wf heap_is_wellformed get_parent get_shadow_root get_host get_child_nodes
+get_disconnected_document get_disconnected_nodes"
+ using heap_wellformed_induct_si heap_wellformed_induct_rev_si
+ using l_get_parent_get_host_wf_def by blast
+
+
+subsubsection \<open>get\_host\<close>
+
+locale l_get_host_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs
+ known_ptr type_wf heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs +
+ l_type_wf type_wf +
+ l_get_host\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_shadow_root get_shadow_root_locs get_host get_host_locs type_wf +
+ l_get_shadow_root type_wf get_shadow_root get_shadow_root_locs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+begin
+
+lemma get_host_ok [simp]:
+ assumes "heap_is_wellformed h"
+ assumes "type_wf h"
+ assumes "known_ptrs h"
+ assumes "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ shows "h \<turnstile> ok (get_host shadow_root_ptr)"
+proof -
+ obtain host where host: "host |\<in>| element_ptr_kinds h"
+ and "|h \<turnstile> get_tag_name host|\<^sub>r \<in> safe_shadow_root_element_types"
+ and shadow_root: "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root_ptr"
+ using assms(1) assms(4) get_shadow_root_ok assms(2)
+ apply(auto simp add: heap_is_wellformed_def a_shadow_root_valid_def)[1]
+ by (smt finite_set_in returns_result_select_result)
+
+
+ obtain host_candidates where
+ host_candidates: "h \<turnstile> filter_M (\<lambda>element_ptr. Heap_Error_Monad.bind (get_shadow_root element_ptr)
+(\<lambda>shadow_root_opt. return (shadow_root_opt = Some shadow_root_ptr)))
+ (sorted_list_of_set (fset (element_ptr_kinds h)))
+ \<rightarrow>\<^sub>r host_candidates"
+ apply(drule is_OK_returns_result_E[rotated])
+ using get_shadow_root_ok assms(2)
+ by(auto intro!: filter_M_is_OK_I bind_pure_I bind_is_OK_I2)
+ then have "host_candidates = [host]"
+ apply(rule filter_M_ex1)
+ using host apply(auto)[1]
+ apply (smt assms(1) assms(2) bind_pure_returns_result_I2 bind_returns_result_E finite_set_in host
+ local.get_shadow_root_ok local.get_shadow_root_pure local.shadow_root_same_host return_returns_result
+ returns_result_eq shadow_root sorted_list_of_fset.rep_eq sorted_list_of_fset_simps(1))
+ apply (simp add: bind_pure_I)
+ apply(auto intro!: bind_pure_returns_result_I)[1]
+ apply (smt assms(2) bind_pure_returns_result_I2 host local.get_shadow_root_ok
+ local.get_shadow_root_pure return_returns_result returns_result_eq shadow_root)
+ done
+
+ then
+ show ?thesis
+ using host_candidates host assms(1) get_shadow_root_ok
+ apply(auto simp add: get_host_def known_ptrs_known_ptr
+ intro!: bind_is_OK_pure_I filter_M_pure_I filter_M_is_OK_I bind_pure_I split: list.splits)[1]
+ using assms(2) apply blast
+ apply (meson list.distinct(1) returns_result_eq)
+ by (meson list.distinct(1) list.inject returns_result_eq)
+qed
+end
+
+interpretation i_get_host_wf?: l_get_host_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_disconnected_document get_disconnected_document_locs known_ptr known_ptrs type_wf get_host
+ get_host_locs get_shadow_root get_shadow_root_locs get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_tag_name get_tag_name_locs heap_is_wellformed
+ parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ by(auto simp add: l_get_host_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_host_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+locale l_get_host_wf = l_heap_is_wellformed_defs + l_known_ptrs + l_type_wf + l_get_host_defs +
+ assumes get_host_ok: "heap_is_wellformed h \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h \<Longrightarrow>
+shadow_root_ptr |\<in>| shadow_root_ptr_kinds h \<Longrightarrow> h \<turnstile> ok (get_host shadow_root_ptr)"
+
+lemma get_host_wf_is_l_get_host_wf [instances]: "l_get_host_wf heap_is_wellformed known_ptr
+known_ptrs type_wf get_host"
+ by(auto simp add: l_get_host_wf_def l_get_host_wf_axioms_def instances)
+
+
+subsubsection \<open>get\_root\_node\_si\<close>
+
+locale l_get_root_node_si_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_root_node_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent_wf +
+ l_get_parent_get_host_wf +
+ l_get_host_wf
+begin
+lemma get_root_node_ptr_in_heap:
+ assumes "h \<turnstile> ok (get_root_node_si ptr)"
+ shows "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ unfolding get_root_node_si_def
+ using get_ancestors_si_ptr_in_heap
+ by auto
+
+
+lemma get_ancestors_si_ok:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ and "ptr |\<in>| object_ptr_kinds h"
+ shows "h \<turnstile> ok (get_ancestors_si ptr)"
+proof (insert assms(1) assms(4), induct rule: heap_wellformed_induct_rev_si)
+ case (step child)
+ then show ?case
+ using assms(2) assms(3)
+ apply(auto simp add: get_ancestors_si_def[of child] assms(1) get_parent_parent_in_heap
+ intro!: bind_is_OK_pure_I split: option.splits)[1]
+ using local.get_parent_ok apply blast
+ using get_host_ok assms(1) apply blast
+ by (meson assms(1) is_OK_returns_result_I local.get_shadow_root_ptr_in_heap
+ local.shadow_root_host_dual)
+qed
+
+lemma get_ancestors_si_remains_not_in_ancestors:
+ assumes "heap_is_wellformed h"
+ and "heap_is_wellformed h'"
+ and "h \<turnstile> get_ancestors_si ptr \<rightarrow>\<^sub>r ancestors"
+ and "h' \<turnstile> get_ancestors_si ptr \<rightarrow>\<^sub>r ancestors'"
+ and "\<And>p children children'. h \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children
+ \<Longrightarrow> h' \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children' \<Longrightarrow> set children' \<subseteq> set children"
+ and "\<And>p shadow_root_option shadow_root_option'. h \<turnstile> get_shadow_root p \<rightarrow>\<^sub>r shadow_root_option \<Longrightarrow>
+h' \<turnstile> get_shadow_root p \<rightarrow>\<^sub>r shadow_root_option' \<Longrightarrow> (if shadow_root_option = None
+then shadow_root_option' = None else shadow_root_option' = None \<or> shadow_root_option' = shadow_root_option)"
+ and "node \<notin> set ancestors"
+ and object_ptr_kinds_eq3: "object_ptr_kinds h = object_ptr_kinds h'"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ and type_wf': "type_wf h'"
+ shows "node \<notin> set ancestors'"
+proof -
+ have object_ptr_kinds_M_eq:
+ "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ using object_ptr_kinds_eq3
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+
+ show ?thesis
+ proof (insert assms(1) assms(3) assms(4) assms(7), induct ptr arbitrary: ancestors ancestors'
+ rule: heap_wellformed_induct_rev_si)
+ case (step child)
+
+ obtain ancestors_remains where ancestors_remains:
+ "ancestors = child # ancestors_remains"
+ using \<open>h \<turnstile> get_ancestors_si child \<rightarrow>\<^sub>r ancestors\<close> get_ancestors_si_never_empty
+ by(auto simp add: get_ancestors_si_def[of child] elim!: bind_returns_result_E2 split: option.splits)
+ obtain ancestors_remains' where ancestors_remains':
+ "ancestors' = child # ancestors_remains'"
+ using \<open>h' \<turnstile> get_ancestors_si child \<rightarrow>\<^sub>r ancestors'\<close> get_ancestors_si_never_empty
+ by(auto simp add: get_ancestors_si_def[of child] elim!: bind_returns_result_E2 split: option.splits)
+ have "child |\<in>| object_ptr_kinds h"
+ using local.get_ancestors_si_ptr_in_heap object_ptr_kinds_eq3 step.prems(2) by fastforce
+
+ have "node \<noteq> child"
+ using ancestors_remains step.prems(3) by auto
+
+ have 1: "\<And>p parent. h' \<turnstile> get_parent p \<rightarrow>\<^sub>r Some parent \<Longrightarrow> h \<turnstile> get_parent p \<rightarrow>\<^sub>r Some parent"
+ proof -
+ fix p parent
+ assume "h' \<turnstile> get_parent p \<rightarrow>\<^sub>r Some parent"
+ then obtain children' where
+ children': "h' \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children'" and
+ p_in_children': "p \<in> set children'"
+ using get_parent_child_dual by blast
+ obtain children where children: "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children"
+ using get_child_nodes_ok assms(1) get_child_nodes_ptr_in_heap object_ptr_kinds_eq children'
+ known_ptrs
+ using type_wf type_wf'
+ by (metis \<open>h' \<turnstile> get_parent p \<rightarrow>\<^sub>r Some parent\<close> get_parent_parent_in_heap is_OK_returns_result_E
+ local.known_ptrs_known_ptr object_ptr_kinds_eq3)
+ have "p \<in> set children"
+ using assms(5) children children' p_in_children'
+ by blast
+ then show "h \<turnstile> get_parent p \<rightarrow>\<^sub>r Some parent"
+ using child_parent_dual assms(1) children known_ptrs type_wf by blast
+ qed
+
+ have 2: "\<And>p host. h' \<turnstile> get_host p \<rightarrow>\<^sub>r host \<Longrightarrow> h \<turnstile> get_host p \<rightarrow>\<^sub>r host"
+ proof -
+ fix p host
+ assume "h' \<turnstile> get_host p \<rightarrow>\<^sub>r host"
+ then have "h' \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some p"
+ using local.shadow_root_host_dual by blast
+ then have "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some p"
+ by (metis assms(6) element_ptr_kinds_commutes is_OK_returns_result_I local.get_shadow_root_ok
+ local.get_shadow_root_ptr_in_heap node_ptr_kinds_commutes object_ptr_kinds_eq3 option.distinct(1)
+ returns_result_select_result type_wf)
+ then show "h \<turnstile> get_host p \<rightarrow>\<^sub>r host"
+ by (metis assms(1) is_OK_returns_result_E known_ptrs local.get_host_ok
+ local.get_shadow_root_shadow_root_ptr_in_heap local.shadow_root_host_dual local.shadow_root_same_host
+ type_wf)
+
+ qed
+
+
+ show ?case
+ proof (cases "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child")
+ case None
+ then show ?thesis
+ using step(4) step(5) \<open>node \<noteq> child\<close>
+ apply(auto simp add: get_ancestors_si_def[of child] elim!: bind_returns_result_E2
+ split: option.splits)[1]
+ by (metis "2" assms(1) shadow_root_same_host list.set_intros(2) shadow_root_host_dual
+ step.hyps(2) step.prems(3) type_wf)
+ next
+ case (Some node_child)
+ then
+ show ?thesis
+ using step(4) step(5) \<open>node \<noteq> child\<close>
+ apply(auto simp add: get_ancestors_si_def[of child] elim!: bind_returns_result_E2
+ split: option.splits)[1]
+ apply (meson "1" option.distinct(1) returns_result_eq)
+ by (metis "1" list.set_intros(2) option.inject returns_result_eq step.hyps(1) step.prems(3))
+ qed
+ qed
+qed
+
+
+lemma get_ancestors_si_ptrs_in_heap:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_ancestors_si ptr \<rightarrow>\<^sub>r ancestors"
+ assumes "ptr' \<in> set ancestors"
+ shows "ptr' |\<in>| object_ptr_kinds h"
+proof (insert assms(4) assms(5), induct ancestors arbitrary: ptr)
+ case Nil
+ then show ?case
+ by(auto)
+next
+ case (Cons a ancestors)
+ then obtain x where x: "h \<turnstile> get_ancestors_si x \<rightarrow>\<^sub>r a # ancestors"
+ by(auto simp add: get_ancestors_si_def[of a] elim!: bind_returns_result_E2 split: option.splits)
+ then have "x = a"
+ by(auto simp add: get_ancestors_si_def[of x] elim!: bind_returns_result_E2 split: option.splits)
+ then show ?case
+ proof (cases "ptr' = a")
+ case True
+ then show ?thesis
+ using Cons.hyps Cons.prems(2) get_ancestors_si_ptr_in_heap x
+ using \<open>x = a\<close> by blast
+ next
+ case False
+ obtain ptr'' where ptr'': "h \<turnstile> get_ancestors_si ptr'' \<rightarrow>\<^sub>r ancestors"
+ using \<open> h \<turnstile> get_ancestors_si x \<rightarrow>\<^sub>r a # ancestors\<close> Cons.prems(2) False
+ apply(auto simp add: get_ancestors_si_def elim!: bind_returns_result_E2)[1]
+ apply(auto elim!: bind_returns_result_E2 split: option.splits intro!: bind_pure_I)[1]
+ apply(auto elim!: bind_returns_result_E2 split: option.splits intro!: bind_pure_I)[1]
+ apply (metis local.get_ancestors_si_def)
+ by (simp add: local.get_ancestors_si_def)
+ then show ?thesis
+ using Cons.hyps Cons.prems(2) False by auto
+ qed
+qed
+
+lemma get_ancestors_si_reads:
+ assumes "heap_is_wellformed h"
+ shows "reads get_ancestors_si_locs (get_ancestors_si node_ptr) h h'"
+proof (insert assms(1), induct rule: heap_wellformed_induct_rev_si)
+ case (step child)
+ then show ?case
+ using [[simproc del: Product_Type.unit_eq]] get_parent_reads[unfolded reads_def]
+ get_host_reads[unfolded reads_def]
+ apply(simp (no_asm) add: get_ancestors_si_def)
+ by(auto simp add: get_ancestors_si_locs_def get_parent_reads_pointers
+ intro!: reads_bind_pure reads_subset[OF check_in_heap_reads] reads_subset[OF return_reads]
+ reads_subset[OF get_parent_reads] reads_subset[OF get_child_nodes_reads]
+ reads_subset[OF get_host_reads]
+ split: option.splits)
+qed
+
+
+lemma get_ancestors_si_subset:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_ancestors_si ptr \<rightarrow>\<^sub>r ancestors"
+ and "ancestor \<in> set ancestors"
+ and "h \<turnstile> get_ancestors_si ancestor \<rightarrow>\<^sub>r ancestor_ancestors"
+ and type_wf: "type_wf h"
+ and known_ptrs: "known_ptrs h"
+ shows "set ancestor_ancestors \<subseteq> set ancestors"
+proof (insert assms(1) assms(2) assms(3), induct ptr arbitrary: ancestors
+ rule: heap_wellformed_induct_rev_si)
+ case (step child)
+ have "child |\<in>| object_ptr_kinds h"
+ using get_ancestors_si_ptr_in_heap step(4) by auto
+ (* then have "h \<turnstile> check_in_heap child \<rightarrow>\<^sub>r ()"
+ using returns_result_select_result by force *)
+
+
+ obtain tl_ancestors where tl_ancestors: "ancestors = child # tl_ancestors"
+ using step(4)
+ by(auto simp add: get_ancestors_si_def[of child] intro!: bind_pure_I
+ elim!: bind_returns_result_E2 split: option.splits)
+ show ?case
+ proof (induct "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child")
+ case None
+ show ?case
+ proof (induct "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child")
+ case None
+ then show ?case
+ using step(4) \<open>None = cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child\<close>
+ apply(auto simp add: get_ancestors_si_def[of child] elim!: bind_returns_result_E2)[1]
+ by (metis (no_types, lifting) assms(4) empty_iff empty_set select_result_I2 set_ConsD
+ step.prems(1) step.prems(2))
+ next
+ case (Some shadow_root_child)
+ then
+ have "cast shadow_root_child |\<in>| document_ptr_kinds h"
+ using \<open>child |\<in>| object_ptr_kinds h\<close>
+ apply(auto simp add: document_ptr_kinds_def split: option.splits)[1]
+ by (metis (mono_tags, lifting) document_ptr_casts_commute3 document_ptr_kinds_commutes
+ document_ptr_kinds_def fset.map_comp shadow_root_ptr_casts_commute)
+ then
+ have "shadow_root_child |\<in>| shadow_root_ptr_kinds h"
+ using shadow_root_ptr_kinds_commutes by blast
+ obtain host where host: "h \<turnstile> get_host shadow_root_child \<rightarrow>\<^sub>r host"
+ using get_host_ok assms
+ by (meson \<open>shadow_root_child |\<in>| shadow_root_ptr_kinds h\<close> is_OK_returns_result_E)
+ then
+ have "h \<turnstile> get_ancestors_si (cast host) \<rightarrow>\<^sub>r tl_ancestors"
+ using Some step(4) tl_ancestors None
+ by(auto simp add: get_ancestors_si_def[of child] intro!: bind_pure_returns_result_I
+ elim!: bind_returns_result_E2 split: option.splits dest: returns_result_eq)
+ then
+ show ?case
+ using step(2) Some host step(5) tl_ancestors
+ using assms(4) dual_order.trans eq_iff returns_result_eq set_ConsD set_subset_Cons
+ shadow_root_ptr_casts_commute document_ptr_casts_commute step.prems(1)
+ by (smt case_optionE local.shadow_root_host_dual option.case_distrib option.distinct(1))
+ qed
+ next
+ case (Some child_node)
+ note s1 = Some
+ obtain parent_opt where parent_opt: "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r parent_opt"
+ using \<open>child |\<in>| object_ptr_kinds h\<close> assms(1) Some[symmetric] get_parent_ok[OF type_wf known_ptrs]
+ by (metis (no_types, lifting) is_OK_returns_result_E known_ptrs get_parent_ok
+ l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms node_ptr_casts_commute node_ptr_kinds_commutes)
+ then show ?case
+ proof (induct parent_opt)
+ case None
+ then have "ancestors = [child]"
+ using step(4) s1
+ apply(simp add: get_ancestors_si_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits dest: returns_result_eq)
+ show ?case
+ using step(4) step(5)
+ apply(auto simp add: \<open>ancestors = [child]\<close>)[1]
+ using assms(4) returns_result_eq by fastforce
+ next
+ case (Some parent)
+ then
+ have "h \<turnstile> get_ancestors_si parent \<rightarrow>\<^sub>r tl_ancestors"
+ using s1 tl_ancestors step(4)
+ by(auto simp add: get_ancestors_si_def[of child] elim!: bind_returns_result_E2
+ split: option.splits dest: returns_result_eq)
+ show ?case
+ by (metis (no_types, lifting) Some.prems \<open>h \<turnstile> get_ancestors_si parent \<rightarrow>\<^sub>r tl_ancestors\<close>
+ assms(4) eq_iff node_ptr_casts_commute order_trans s1 select_result_I2 set_ConsD set_subset_Cons
+ step.hyps(1) step.prems(1) step.prems(2) tl_ancestors)
+ qed
+ qed
+qed
+
+lemma get_ancestors_si_also_parent:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_ancestors_si some_ptr \<rightarrow>\<^sub>r ancestors"
+ and "cast child \<in> set ancestors"
+ and "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some parent"
+ and type_wf: "type_wf h"
+ and known_ptrs: "known_ptrs h"
+ shows "parent \<in> set ancestors"
+proof -
+ obtain child_ancestors where child_ancestors: "h \<turnstile> get_ancestors_si (cast child) \<rightarrow>\<^sub>r child_ancestors"
+ by (meson assms(1) assms(4) get_ancestors_si_ok is_OK_returns_result_I known_ptrs
+ local.get_parent_ptr_in_heap node_ptr_kinds_commutes returns_result_select_result
+ type_wf)
+ then have "parent \<in> set child_ancestors"
+ apply(simp add: get_ancestors_si_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits dest!: returns_result_eq[OF assms(4)]
+ get_ancestors_si_ptr)
+ then show ?thesis
+ using assms child_ancestors get_ancestors_si_subset by blast
+qed
+
+lemma get_ancestors_si_also_host:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_ancestors_si some_ptr \<rightarrow>\<^sub>r ancestors"
+ and "cast shadow_root \<in> set ancestors"
+ and "h \<turnstile> get_host shadow_root \<rightarrow>\<^sub>r host"
+ and type_wf: "type_wf h"
+ and known_ptrs: "known_ptrs h"
+ shows "cast host \<in> set ancestors"
+proof -
+ obtain child_ancestors where child_ancestors: "h \<turnstile> get_ancestors_si (cast shadow_root) \<rightarrow>\<^sub>r child_ancestors"
+ by (meson assms(1) assms(2) assms(3) get_ancestors_si_ok get_ancestors_si_ptrs_in_heap
+ is_OK_returns_result_E known_ptrs type_wf)
+ then have "cast host \<in> set child_ancestors"
+ apply(simp add: get_ancestors_si_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits dest!: returns_result_eq[OF assms(4)]
+ get_ancestors_si_ptr)
+ then show ?thesis
+ using assms child_ancestors get_ancestors_si_subset by blast
+qed
+
+
+lemma get_ancestors_si_obtains_children_or_shadow_root:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ and "h \<turnstile> get_ancestors_si ptr \<rightarrow>\<^sub>r ancestors"
+ and "ancestor \<noteq> ptr"
+ and "ancestor \<in> set ancestors"
+ shows "((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ancestor \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast ancestor_child \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)
+ \<or> ((\<forall>ancestor_element shadow_root. ancestor = cast ancestor_element \<longrightarrow>
+h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root \<longrightarrow> cast shadow_root \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow>
+thesis)"
+proof (insert assms(4) assms(5) assms(6), induct ptr arbitrary: ancestors
+ rule: heap_wellformed_induct_rev_si[OF assms(1)])
+ case (1 child)
+ then show ?case
+ proof (cases "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child")
+ case None
+ then obtain shadow_root where shadow_root: "child = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root"
+ using 1(4) 1(5) 1(6)
+ by(auto simp add: get_ancestors_si_def[of child] elim!: bind_returns_result_E2
+ split: option.splits)
+ then obtain host where host: "h \<turnstile> get_host shadow_root \<rightarrow>\<^sub>r host"
+ by (metis "1.prems"(1) assms(1) assms(2) assms(3) document_ptr_kinds_commutes
+ get_ancestors_si_ptrs_in_heap is_OK_returns_result_E local.get_ancestors_si_ptr local.get_host_ok
+ shadow_root_ptr_kinds_commutes)
+ then obtain host_ancestors where host_ancestors: "h \<turnstile> get_ancestors_si (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) \<rightarrow>\<^sub>r host_ancestors"
+ by (metis "1.prems"(1) assms(1) assms(2) assms(3) get_ancestors_si_also_host get_ancestors_si_ok
+ get_ancestors_si_ptrs_in_heap is_OK_returns_result_E local.get_ancestors_si_ptr shadow_root)
+ then have "ancestors = cast shadow_root # host_ancestors"
+ using 1(4) 1(5) 1(3) None shadow_root host
+ by(auto simp add: get_ancestors_si_def[of child, simplified shadow_root]
+ elim!: bind_returns_result_E2 dest!: returns_result_eq[OF host] split: option.splits)
+ then show ?thesis
+ proof (cases "ancestor = cast host")
+ case True
+ then show ?thesis
+ using "1.prems"(1) host local.get_ancestors_si_ptr local.shadow_root_host_dual shadow_root
+ by blast
+ next
+ case False
+ have "ancestor \<in> set ancestors"
+ using host host_ancestors 1(3) get_ancestors_si_also_host assms(1) assms(2) assms(3)
+ using "1.prems"(3) by blast
+ then have "((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ancestor \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_child \<in> set host_ancestors \<longrightarrow> thesis) \<longrightarrow>
+thesis) \<or>
+ ((\<forall>ancestor_element shadow_root. ancestor = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_element \<longrightarrow>
+h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root \<longrightarrow>
+cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root \<in> set host_ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)"
+ using "1.hyps"(2) "1.prems"(2) False \<open>ancestors = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root # host_ancestors\<close>
+ host host_ancestors shadow_root
+ by auto
+ then show ?thesis
+ using \<open>ancestors = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root # host_ancestors\<close> by auto
+ qed
+ next
+ case (Some child_node)
+ then obtain parent where parent: "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent"
+ using 1(4) 1(5) 1(6)
+ by(auto simp add: get_ancestors_si_def[of child] elim!: bind_returns_result_E2
+ split: option.splits)
+ then obtain parent_ancestors where parent_ancestors: "h \<turnstile> get_ancestors_si parent \<rightarrow>\<^sub>r parent_ancestors"
+ by (meson assms(1) assms(2) assms(3) get_ancestors_si_ok is_OK_returns_result_E
+ local.get_parent_parent_in_heap)
+ then have "ancestors = cast child_node # parent_ancestors"
+ using 1(4) 1(5) 1(3) Some
+ by(auto simp add: get_ancestors_si_def[of child, simplified Some]
+ elim!: bind_returns_result_E2 dest!: returns_result_eq[OF parent] split: option.splits)
+ then show ?thesis
+ proof (cases "ancestor = parent")
+ case True
+ then show ?thesis
+ by (metis (no_types, lifting) "1.prems"(1) Some local.get_ancestors_si_ptr
+ local.get_parent_child_dual node_ptr_casts_commute parent)
+ next
+ case False
+ have "ancestor \<in> set ancestors"
+ by (simp add: "1.prems"(3))
+ then have "((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ancestor \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_child \<in> set parent_ancestors \<longrightarrow> thesis) \<longrightarrow>
+thesis) \<or>
+ ((\<forall>ancestor_element shadow_root. ancestor = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_element \<longrightarrow>
+h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root \<longrightarrow>
+cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root \<in> set parent_ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)"
+ using "1.hyps"(1) "1.prems"(2) False Some \<open>ancestors = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node # parent_ancestors\<close>
+ parent parent_ancestors
+ by auto
+ then show ?thesis
+ using \<open>ancestors = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node # parent_ancestors\<close> by auto
+ qed
+ qed
+qed
+
+lemma a_host_shadow_root_rel_shadow_root:
+ "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root \<Longrightarrow> (cast host, cast shadow_root) \<in> a_host_shadow_root_rel h"
+ by(auto simp add: is_OK_returns_result_I get_shadow_root_ptr_in_heap a_host_shadow_root_rel_def)
+
+lemma get_ancestors_si_parent_child_a_host_shadow_root_rel:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ assumes "h \<turnstile> get_ancestors_si child \<rightarrow>\<^sub>r ancestors"
+ shows "(ptr, child) \<in> (parent_child_rel h \<union> a_host_shadow_root_rel h)\<^sup>* \<longleftrightarrow> ptr \<in> set ancestors"
+proof
+ assume "(ptr, child) \<in> (parent_child_rel h \<union> local.a_host_shadow_root_rel h)\<^sup>* "
+ then show "ptr \<in> set ancestors"
+ proof (induct ptr rule: heap_wellformed_induct_si[OF assms(1)])
+ case (1 ptr)
+ then show ?case
+ proof (cases "ptr = child")
+ case True
+ then show ?thesis
+ using assms(4) local.get_ancestors_si_ptr by blast
+ next
+ case False
+ obtain ptr_child where
+ ptr_child: "(ptr, ptr_child) \<in> (parent_child_rel h \<union> local.a_host_shadow_root_rel h) \<and>
+(ptr_child, child) \<in> (parent_child_rel h \<union> local.a_host_shadow_root_rel h)\<^sup>*"
+ using converse_rtranclE[OF 1(4)] \<open>ptr \<noteq> child\<close>
+ by metis
+ then show ?thesis
+ proof(cases "(ptr, ptr_child) \<in> parent_child_rel h")
+ case True
+
+ then obtain ptr_child_node
+ where ptr_child_ptr_child_node: "ptr_child = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr_child_node"
+ using ptr_child node_ptr_casts_commute3 CD.parent_child_rel_node_ptr
+ by (metis)
+ then obtain children where
+ children: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children" and
+ ptr_child_node: "ptr_child_node \<in> set children"
+ proof -
+ assume a1: "\<And>children. \<lbrakk>h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children; ptr_child_node \<in> set children\<rbrakk>
+ \<Longrightarrow> thesis"
+
+ have "ptr |\<in>| object_ptr_kinds h"
+ using CD.parent_child_rel_parent_in_heap True by blast
+ moreover have "ptr_child_node \<in> set |h \<turnstile> get_child_nodes ptr|\<^sub>r"
+ by (metis True assms(2) assms(3) calculation local.CD.parent_child_rel_child
+ local.get_child_nodes_ok local.known_ptrs_known_ptr ptr_child_ptr_child_node
+ returns_result_select_result)
+ ultimately show ?thesis
+ using a1 get_child_nodes_ok \<open>type_wf h\<close> \<open>known_ptrs h\<close>
+ by (meson local.known_ptrs_known_ptr returns_result_select_result)
+ qed
+ moreover have "(cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr_child_node, child) \<in> (parent_child_rel h \<union> local.a_host_shadow_root_rel h)\<^sup>*"
+ using ptr_child True ptr_child_ptr_child_node by auto
+ ultimately have "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr_child_node \<in> set ancestors"
+ using 1 by auto
+ moreover have "h \<turnstile> get_parent ptr_child_node \<rightarrow>\<^sub>r Some ptr"
+ using assms(1) children ptr_child_node child_parent_dual
+ using \<open>known_ptrs h\<close> \<open>type_wf h\<close> by blast
+ ultimately show ?thesis
+ using get_ancestors_si_also_parent assms \<open>type_wf h\<close> by blast
+ next
+ case False
+ then
+ obtain host where host: "ptr = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host"
+ using ptr_child
+ by(auto simp add: a_host_shadow_root_rel_def)
+ then obtain shadow_root where shadow_root: "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root"
+ and ptr_child_shadow_root: "ptr_child = cast shadow_root"
+ using ptr_child False
+ apply(auto simp add: a_host_shadow_root_rel_def)[1]
+ by (metis (no_types, lifting) assms(3) local.get_shadow_root_ok select_result_I)
+
+ moreover have "(cast shadow_root, child) \<in> (parent_child_rel h \<union> local.a_host_shadow_root_rel h)\<^sup>*"
+ using ptr_child ptr_child_shadow_root by blast
+ ultimately have "cast shadow_root \<in> set ancestors"
+ using "1.hyps"(2) host by blast
+ moreover have "h \<turnstile> get_host shadow_root \<rightarrow>\<^sub>r host"
+ by (metis assms(1) assms(2) assms(3) is_OK_returns_result_E local.get_host_ok
+ local.get_shadow_root_shadow_root_ptr_in_heap local.shadow_root_host_dual local.shadow_root_same_host
+ shadow_root)
+ ultimately show ?thesis
+ using get_ancestors_si_also_host assms(1) assms(2) assms(3) assms(4) host
+ by blast
+ qed
+ qed
+ qed
+next
+ assume "ptr \<in> set ancestors"
+ then show "(ptr, child) \<in> (parent_child_rel h \<union> local.a_host_shadow_root_rel h)\<^sup>*"
+ proof (induct ptr rule: heap_wellformed_induct_si[OF assms(1)])
+ case (1 ptr)
+ then show ?case
+ proof (cases "ptr = child")
+ case True
+ then show ?thesis
+ by simp
+ next
+ case False
+ have "\<And>thesis. ((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast ancestor_child \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)
+ \<or> ((\<forall>ancestor_element shadow_root. ptr = cast ancestor_element \<longrightarrow>
+h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root \<longrightarrow> cast shadow_root \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow>
+thesis)"
+ using "1.prems" False assms(1) assms(2) assms(3) assms(4) get_ancestors_si_obtains_children_or_shadow_root
+ by blast
+ then show ?thesis
+ proof (cases "\<forall>thesis. ((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast ancestor_child \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)")
+ case True
+ then obtain children ancestor_child
+ where "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ and "ancestor_child \<in> set children"
+ and "cast ancestor_child \<in> set ancestors"
+ by blast
+ then show ?thesis
+ by (meson "1.hyps"(1) in_rtrancl_UnI local.CD.parent_child_rel_child r_into_rtrancl rtrancl_trans)
+ next
+ case False
+ obtain ancestor_element shadow_root
+ where "ptr = cast ancestor_element"
+ and "h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root"
+ and "cast shadow_root \<in> set ancestors"
+ using False \<open>\<And>thesis. ((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_child \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow> thesis) \<or>
+((\<forall>ancestor_element shadow_root. ptr = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_element \<longrightarrow>
+h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root \<longrightarrow>
+cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)\<close>
+ by blast
+
+ then show ?thesis
+ using 1(2) a_host_shadow_root_rel_shadow_root
+ apply(simp)
+ by (meson Un_iff converse_rtrancl_into_rtrancl)
+ qed
+ qed
+ qed
+qed
+
+lemma get_root_node_si_root_in_heap:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node_si ptr \<rightarrow>\<^sub>r root"
+ shows "root |\<in>| object_ptr_kinds h"
+ using assms
+ apply(auto simp add: get_root_node_si_def elim!: bind_returns_result_E2)[1]
+ by (simp add: get_ancestors_si_never_empty get_ancestors_si_ptrs_in_heap)
+
+lemma get_root_node_si_same_no_parent:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node_si ptr \<rightarrow>\<^sub>r cast child"
+ shows "h \<turnstile> get_parent child \<rightarrow>\<^sub>r None"
+proof (insert assms(1) assms(4), induct ptr rule: heap_wellformed_induct_rev_si)
+ case (step c)
+ then show ?case
+ proof (cases "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r c")
+ case None
+ then show ?thesis
+ using step(4)
+ by(auto simp add: get_root_node_si_def get_ancestors_si_def[of c] elim!: bind_returns_result_E2
+ split: if_splits option.splits intro!: step(2) bind_pure_returns_result_I)
+ next
+ case (Some child_node)
+ note s = this
+ then obtain parent_opt where parent_opt: "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r parent_opt"
+ using step(4)
+ apply(auto simp add: get_root_node_si_def get_ancestors_si_def intro!: bind_pure_I
+ elim!: bind_returns_result_E2)[1]
+ by(auto split: option.splits)
+ then show ?thesis
+ proof(induct parent_opt)
+ case None
+ then show ?case
+ using Some get_root_node_si_no_parent returns_result_eq step.prems by fastforce
+ next
+ case (Some parent)
+ then show ?case
+ using step(4) s
+ apply(auto simp add: get_root_node_si_def get_ancestors_si_def[of c]
+ elim!: bind_returns_result_E2 split: option.splits list.splits if_splits)[1]
+ using assms(1) get_ancestors_si_never_empty apply blast
+ by(auto simp add: get_root_node_si_def dest: returns_result_eq
+ intro!: step(1) bind_pure_returns_result_I)
+ qed
+ qed
+qed
+
+lemma get_root_node_si_parent_child_a_host_shadow_root_rel:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ assumes "h \<turnstile> get_root_node_si ptr \<rightarrow>\<^sub>r root"
+ shows "(root, ptr) \<in> (parent_child_rel h \<union> a_host_shadow_root_rel h)\<^sup>*"
+ using assms
+ using get_ancestors_si_parent_child_a_host_shadow_root_rel get_ancestors_si_never_empty
+ by(auto simp add: get_root_node_si_def elim!: bind_returns_result_E2 intro!: bind_pure_returns_result_I)
+end
+
+interpretation i_get_root_node_si_wf?: l_get_root_node_si_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_host get_host_locs get_ancestors_si get_ancestors_si_locs get_root_node_si get_root_node_si_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs get_tag_name
+ get_tag_name_locs heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_document
+ get_disconnected_document_locs
+ by(auto simp add: l_get_root_node_si_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_root_node_si_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_disconnected\_document\<close>
+
+locale l_get_disconnected_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_disconnected_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent_wf +
+ l_get_parent
+begin
+
+lemma get_disconnected_document_ok:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r None"
+ shows "h \<turnstile> ok (get_disconnected_document node_ptr)"
+proof -
+ have "node_ptr |\<in>| node_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_result_I local.get_parent_ptr_in_heap)
+ have "\<not>(\<exists>parent \<in> fset (object_ptr_kinds h). node_ptr \<in> set |h \<turnstile> get_child_nodes parent|\<^sub>r)"
+ apply(auto)[1]
+ using assms(4) child_parent_dual[OF assms(1)]
+ assms(1) assms(2) assms(3) known_ptrs_known_ptr option.simps(3)
+ returns_result_eq returns_result_select_result
+ by (metis (no_types, lifting) CD.get_child_nodes_ok)
+ then
+ have "(\<exists>document_ptr \<in> fset (document_ptr_kinds h). node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)"
+ using heap_is_wellformed_children_disc_nodes
+ using \<open>node_ptr |\<in>| node_ptr_kinds h\<close> assms(1) by blast
+ then obtain some_owner_document where
+ "some_owner_document \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))" and
+ "node_ptr \<in> set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r"
+ by auto
+
+ have h5: "\<exists>!x. x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h))) \<and> h \<turnstile> Heap_Error_Monad.bind (get_disconnected_nodes x)
+ (\<lambda>children. return (node_ptr \<in> set children)) \<rightarrow>\<^sub>r True"
+ apply(auto intro!: bind_pure_returns_result_I)[1]
+ apply (smt CD.get_disconnected_nodes_ok CD.get_disconnected_nodes_pure
+ \<open>\<exists>document_ptr\<in>fset (document_ptr_kinds h). node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r\<close>
+ assms(2) bind_pure_returns_result_I2 notin_fset return_returns_result select_result_I2)
+
+ apply(auto elim!: bind_returns_result_E2 intro!: bind_pure_returns_result_I)[1]
+ using heap_is_wellformed_one_disc_parent assms(1)
+ by blast
+ let ?filter_M = "filter_M
+ (\<lambda>document_ptr.
+ Heap_Error_Monad.bind (get_disconnected_nodes document_ptr)
+ (\<lambda>disconnected_nodes. return (node_ptr \<in> set disconnected_nodes)))
+ (sorted_list_of_set (fset (document_ptr_kinds h)))"
+ have "h \<turnstile> ok (?filter_M)"
+ using CD.get_disconnected_nodes_ok
+ by (smt CD.get_disconnected_nodes_pure DocumentMonad.ptr_kinds_M_ptr_kinds
+ DocumentMonad.ptr_kinds_ptr_kinds_M assms(2) bind_is_OK_pure_I bind_pure_I document_ptr_kinds_M_def
+ filter_M_is_OK_I l_ptr_kinds_M.ptr_kinds_M_ok return_ok return_pure returns_result_select_result)
+ then
+ obtain candidates where candidates: "h \<turnstile> filter_M
+ (\<lambda>document_ptr.
+ Heap_Error_Monad.bind (get_disconnected_nodes document_ptr)
+ (\<lambda>disconnected_nodes. return (node_ptr \<in> set disconnected_nodes)))
+ (sorted_list_of_set (fset (document_ptr_kinds h)))
+ \<rightarrow>\<^sub>r candidates"
+ by auto
+ have "candidates = [some_owner_document]"
+ apply(rule filter_M_ex1[OF candidates \<open>some_owner_document \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))\<close> h5])
+ using \<open>node_ptr \<in> set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r\<close>
+ \<open>some_owner_document \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))\<close>
+ by(auto simp add: CD.get_disconnected_nodes_ok assms(2) intro!: bind_pure_I
+ intro!: bind_pure_returns_result_I)
+ then show ?thesis
+ using candidates \<open>node_ptr |\<in>| node_ptr_kinds h\<close>
+ apply(auto simp add: get_disconnected_document_def intro!: bind_is_OK_pure_I filter_M_pure_I bind_pure_I
+ split: list.splits)[1]
+ apply (meson not_Cons_self2 returns_result_eq)
+ by (meson list.distinct(1) list.inject returns_result_eq)
+qed
+end
+
+interpretation i_get_disconnected_document_wf?: l_get_disconnected_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs known_ptr type_wf
+ heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs
+ get_disconnected_document get_disconnected_document_locs known_ptrs get_parent get_parent_locs
+ by(auto simp add: l_get_disconnected_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_disconnected_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+
+subsubsection \<open>get\_ancestors\_di\<close>
+
+locale l_get_ancestors_di_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_ancestors_di\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent_wf +
+ l_get_parent_get_host_wf +
+ l_get_host_wf +
+ l_get_disconnected_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent_get_host_get_disconnected_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma get_ancestors_di_ok:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ and "ptr |\<in>| object_ptr_kinds h"
+ shows "h \<turnstile> ok (get_ancestors_di ptr)"
+proof (insert assms(1) assms(4), induct rule: heap_wellformed_induct_rev_si)
+ case (step child)
+ then show ?case
+ using assms(2) assms(3)
+ apply(auto simp add: get_ancestors_di_def[of child] assms(1) get_parent_parent_in_heap
+ intro!: bind_is_OK_pure_I bind_pure_I split: option.splits)[1]
+ using local.get_parent_ok apply blast
+ using assms(1) get_disconnected_document_ok apply blast
+ apply(simp add: get_ancestors_di_def )
+ apply(auto intro!: bind_is_OK_pure_I split: option.splits)[1]
+ apply (metis (no_types, lifting) bind_is_OK_E document_ptr_kinds_commutes is_OK_returns_heap_I
+ local.get_ancestors_di_def local.get_disconnected_document_disconnected_document_in_heap step.hyps(3))
+ apply (metis (no_types, lifting) bind_is_OK_E document_ptr_kinds_commutes is_OK_returns_heap_I
+ local.get_ancestors_di_def local.get_disconnected_document_disconnected_document_in_heap step.hyps(3))
+ using assms(1) local.get_disconnected_document_disconnected_document_in_heap local.get_host_ok
+ shadow_root_ptr_kinds_commutes apply blast
+ apply (smt assms(1) bind_returns_heap_E document_ptr_casts_commute2 is_OK_returns_heap_E
+ is_OK_returns_heap_I l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M.shadow_root_same_host
+ local.get_disconnected_document_disconnected_document_in_heap local.get_host_pure
+ local.l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms local.shadow_root_host_dual option.simps(4) option.simps(5)
+ pure_returns_heap_eq shadow_root_ptr_casts_commute2)
+ using get_host_ok assms(1) apply blast
+ by (meson assms(1) is_OK_returns_result_I local.get_shadow_root_ptr_in_heap local.shadow_root_host_dual)
+qed
+
+lemma get_ancestors_di_ptrs_in_heap:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_ancestors_di ptr \<rightarrow>\<^sub>r ancestors"
+ assumes "ptr' \<in> set ancestors"
+ shows "ptr' |\<in>| object_ptr_kinds h"
+proof (insert assms(4) assms(5), induct ancestors arbitrary: ptr)
+ case Nil
+ then show ?case
+ by(auto)
+next
+ case (Cons a ancestors)
+ then obtain x where x: "h \<turnstile> get_ancestors_di x \<rightarrow>\<^sub>r a # ancestors"
+ by(auto simp add: get_ancestors_di_def[of a] elim!: bind_returns_result_E2 split: option.splits)
+ then have "x = a"
+ by(auto simp add: get_ancestors_di_def[of x] intro!: bind_pure_I elim!: bind_returns_result_E2
+ split: option.splits)
+ then show ?case
+ proof (cases "ptr' = a")
+ case True
+ then show ?thesis
+ using Cons.hyps Cons.prems(2) get_ancestors_di_ptr_in_heap x
+ using \<open>x = a\<close> by blast
+ next
+ case False
+ obtain ptr'' where ptr'': "h \<turnstile> get_ancestors_di ptr'' \<rightarrow>\<^sub>r ancestors"
+ using \<open> h \<turnstile> get_ancestors_di x \<rightarrow>\<^sub>r a # ancestors\<close> Cons.prems(2) False
+ apply(auto simp add: get_ancestors_di_def elim!: bind_returns_result_E2)[1]
+ apply(auto elim!: bind_returns_result_E2 split: option.splits intro!: bind_pure_I)[1]
+ apply(auto elim!: bind_returns_result_E2 split: option.splits intro!: bind_pure_I)[1]
+ apply (metis (no_types, lifting) local.get_ancestors_di_def)
+ apply (metis (no_types, lifting) local.get_ancestors_di_def)
+ by (simp add: local.get_ancestors_di_def)
+ then show ?thesis
+ using Cons.hyps Cons.prems(2) False by auto
+ qed
+qed
+
+lemma get_ancestors_di_reads:
+ assumes "heap_is_wellformed h"
+ shows "reads get_ancestors_di_locs (get_ancestors_di node_ptr) h h'"
+proof (insert assms(1), induct rule: heap_wellformed_induct_rev_si)
+ case (step child)
+ then show ?case
+ using (* [[simproc del: Product_Type.unit_eq]] *) get_parent_reads[unfolded reads_def]
+ get_host_reads[unfolded reads_def] get_disconnected_document_reads[unfolded reads_def]
+ apply(auto simp add: get_ancestors_di_def[of child])[1]
+ by(auto simp add: get_ancestors_di_locs_def get_parent_reads_pointers
+ intro!: bind_pure_I reads_bind_pure reads_subset[OF check_in_heap_reads] reads_subset[OF return_reads]
+ reads_subset[OF get_parent_reads] reads_subset[OF get_child_nodes_reads]
+ reads_subset[OF get_host_reads] reads_subset[OF get_disconnected_document_reads]
+ split: option.splits list.splits
+ )
+
+qed
+
+lemma get_ancestors_di_subset:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_ancestors_di ptr \<rightarrow>\<^sub>r ancestors"
+ and "ancestor \<in> set ancestors"
+ and "h \<turnstile> get_ancestors_di ancestor \<rightarrow>\<^sub>r ancestor_ancestors"
+ and type_wf: "type_wf h"
+ and known_ptrs: "known_ptrs h"
+ shows "set ancestor_ancestors \<subseteq> set ancestors"
+proof (insert assms(1) assms(2) assms(3), induct ptr arbitrary: ancestors
+ rule: heap_wellformed_induct_rev_si)
+ case (step child)
+ have "child |\<in>| object_ptr_kinds h"
+ using get_ancestors_di_ptr_in_heap step(4) by auto
+ (* then have "h \<turnstile> check_in_heap child \<rightarrow>\<^sub>r ()"
+ using returns_result_select_result by force *)
+
+
+ obtain tl_ancestors where tl_ancestors: "ancestors = child # tl_ancestors"
+ using step(4)
+ by(auto simp add: get_ancestors_di_def[of child] intro!: bind_pure_I
+ elim!: bind_returns_result_E2 split: option.splits)
+ show ?case
+ proof (induct "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child")
+ case None
+ show ?case
+ proof (induct "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child")
+ case None
+ then show ?case
+ using step(4) \<open>None = cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child\<close>
+ apply(auto simp add: get_ancestors_di_def[of child] elim!: bind_returns_result_E2)[1]
+ by (metis (no_types, lifting) assms(4) empty_iff empty_set select_result_I2 set_ConsD
+ step.prems(1) step.prems(2))
+ next
+ case (Some shadow_root_child)
+ then
+ have "cast shadow_root_child |\<in>| document_ptr_kinds h"
+ using \<open>child |\<in>| object_ptr_kinds h\<close>
+ apply(auto simp add: document_ptr_kinds_def split: option.splits)[1]
+ by (metis (mono_tags, lifting) document_ptr_casts_commute3 document_ptr_kinds_commutes
+ document_ptr_kinds_def fset.map_comp shadow_root_ptr_casts_commute)
+ then
+ have "shadow_root_child |\<in>| shadow_root_ptr_kinds h"
+ using shadow_root_ptr_kinds_commutes by blast
+ obtain host where host: "h \<turnstile> get_host shadow_root_child \<rightarrow>\<^sub>r host"
+ using get_host_ok assms
+ by (meson \<open>shadow_root_child |\<in>| shadow_root_ptr_kinds h\<close> is_OK_returns_result_E)
+ then
+ have "h \<turnstile> get_ancestors_di (cast host) \<rightarrow>\<^sub>r tl_ancestors"
+ using Some step(4) tl_ancestors None
+ by(auto simp add: get_ancestors_di_def[of child] intro!: bind_pure_returns_result_I
+ elim!: bind_returns_result_E2 split: option.splits dest: returns_result_eq)
+ then
+ show ?case
+ using step(2) Some host step(5) tl_ancestors
+ using assms(4) dual_order.trans eq_iff returns_result_eq set_ConsD set_subset_Cons
+ shadow_root_ptr_casts_commute document_ptr_casts_commute step.prems(1)
+ by (smt case_optionE local.shadow_root_host_dual option.case_distrib option.distinct(1))
+ qed
+ next
+ case (Some child_node)
+ note s1 = Some
+ obtain parent_opt where parent_opt: "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r parent_opt"
+ using \<open>child |\<in>| object_ptr_kinds h\<close> assms(1) Some[symmetric] get_parent_ok[OF type_wf known_ptrs]
+ by (metis (no_types, lifting) is_OK_returns_result_E known_ptrs get_parent_ok
+ l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms node_ptr_casts_commute node_ptr_kinds_commutes)
+ then show ?case
+ proof (induct parent_opt)
+ case None
+ then obtain disc_doc where disc_doc: "h \<turnstile> get_disconnected_document child_node \<rightarrow>\<^sub>r disc_doc"
+ and "h \<turnstile> get_ancestors_di (cast disc_doc) \<rightarrow>\<^sub>r tl_ancestors"
+ using step(4) s1 tl_ancestors
+ apply(simp add: get_ancestors_di_def[of child])
+ by(auto elim!: bind_returns_result_E2 intro!: bind_pure_I split: option.splits dest: returns_result_eq)
+ then show ?thesis
+ using step(3) step(4) step(5)
+ by (metis (no_types, lifting) assms(4) dual_order.trans eq_iff node_ptr_casts_commute s1
+ select_result_I2 set_ConsD set_subset_Cons tl_ancestors)
+ next
+ case (Some parent)
+ then
+ have "h \<turnstile> get_ancestors_di parent \<rightarrow>\<^sub>r tl_ancestors"
+ using s1 tl_ancestors step(4)
+ by(auto simp add: get_ancestors_di_def[of child] elim!: bind_returns_result_E2
+ split: option.splits dest: returns_result_eq)
+ show ?case
+ by (metis (no_types, lifting) Some.prems \<open>h \<turnstile> get_ancestors_di parent \<rightarrow>\<^sub>r tl_ancestors\<close>
+ assms(4) eq_iff node_ptr_casts_commute order_trans s1 select_result_I2 set_ConsD set_subset_Cons
+ step.hyps(1) step.prems(1) step.prems(2) tl_ancestors)
+ qed
+ qed
+qed
+
+lemma get_ancestors_di_also_parent:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_ancestors_di some_ptr \<rightarrow>\<^sub>r ancestors"
+ and "cast child \<in> set ancestors"
+ and "h \<turnstile> get_parent child \<rightarrow>\<^sub>r Some parent"
+ and type_wf: "type_wf h"
+ and known_ptrs: "known_ptrs h"
+ shows "parent \<in> set ancestors"
+proof -
+ obtain child_ancestors where child_ancestors: "h \<turnstile> get_ancestors_di (cast child) \<rightarrow>\<^sub>r child_ancestors"
+ by (meson assms(1) assms(4) get_ancestors_di_ok is_OK_returns_result_I known_ptrs
+ local.get_parent_ptr_in_heap node_ptr_kinds_commutes returns_result_select_result
+ type_wf)
+ then have "parent \<in> set child_ancestors"
+ apply(simp add: get_ancestors_di_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits dest!: returns_result_eq[OF assms(4)]
+ get_ancestors_di_ptr)
+ then show ?thesis
+ using assms child_ancestors get_ancestors_di_subset by blast
+qed
+
+lemma get_ancestors_di_also_host:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_ancestors_di some_ptr \<rightarrow>\<^sub>r ancestors"
+ and "cast shadow_root \<in> set ancestors"
+ and "h \<turnstile> get_host shadow_root \<rightarrow>\<^sub>r host"
+ and type_wf: "type_wf h"
+ and known_ptrs: "known_ptrs h"
+ shows "cast host \<in> set ancestors"
+proof -
+ obtain child_ancestors where child_ancestors: "h \<turnstile> get_ancestors_di (cast shadow_root) \<rightarrow>\<^sub>r child_ancestors"
+ by (meson assms(1) assms(2) assms(3) get_ancestors_di_ok get_ancestors_di_ptrs_in_heap
+ is_OK_returns_result_E known_ptrs type_wf)
+ then have "cast host \<in> set child_ancestors"
+ apply(simp add: get_ancestors_di_def)
+ by(auto elim!: bind_returns_result_E2 split: option.splits dest!: returns_result_eq[OF assms(4)]
+ get_ancestors_di_ptr)
+ then show ?thesis
+ using assms child_ancestors get_ancestors_di_subset by blast
+qed
+
+lemma get_ancestors_di_also_disconnected_document:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> get_ancestors_di some_ptr \<rightarrow>\<^sub>r ancestors"
+ and "cast disc_node \<in> set ancestors"
+ and "h \<turnstile> get_disconnected_document disc_node \<rightarrow>\<^sub>r disconnected_document"
+ and type_wf: "type_wf h"
+ and known_ptrs: "known_ptrs h"
+ and "h \<turnstile> get_parent disc_node \<rightarrow>\<^sub>r None"
+ shows "cast disconnected_document \<in> set ancestors"
+proof -
+ obtain child_ancestors where child_ancestors: "h \<turnstile> get_ancestors_di (cast disc_node) \<rightarrow>\<^sub>r child_ancestors"
+ by (meson assms(1) assms(2) assms(3) get_ancestors_di_ok get_ancestors_di_ptrs_in_heap
+ is_OK_returns_result_E known_ptrs type_wf)
+ then have "cast disconnected_document \<in> set child_ancestors"
+ apply(simp add: get_ancestors_di_def)
+ by(auto elim!: bind_returns_result_E2 intro!: bind_pure_I split: option.splits
+ dest!: returns_result_eq[OF assms(4)] returns_result_eq[OF assms(7)]
+ get_ancestors_di_ptr)
+ then show ?thesis
+ using assms child_ancestors get_ancestors_di_subset by blast
+qed
+
+lemma disc_node_disc_doc_dual:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r None"
+ assumes "h \<turnstile> get_disconnected_nodes disc_doc \<rightarrow>\<^sub>r disc_nodes"
+ assumes "node_ptr \<in> set disc_nodes"
+ shows "h \<turnstile> get_disconnected_document node_ptr \<rightarrow>\<^sub>r disc_doc"
+proof -
+ have "node_ptr |\<in>| node_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_result_I local.get_parent_ptr_in_heap)
+ then
+ have "\<not>(\<exists>parent \<in> fset (object_ptr_kinds h). node_ptr \<in> set |h \<turnstile> get_child_nodes parent|\<^sub>r)"
+ apply(auto)[1]
+ using child_parent_dual[OF assms(1)]
+ assms known_ptrs_known_ptr option.simps(3)
+ returns_result_eq returns_result_select_result
+ by (metis (no_types, lifting) get_child_nodes_ok)
+ then
+ have "(\<exists>document_ptr \<in> fset (document_ptr_kinds h). node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)"
+ using heap_is_wellformed_children_disc_nodes
+ using \<open>node_ptr |\<in>| node_ptr_kinds h\<close> assms(1) by blast
+ (* then obtain some_owner_document where
+ "some_owner_document \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))" and
+ "node_ptr \<in> set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r"
+ by auto *)
+ then have "disc_doc \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))" and
+ "node_ptr \<in> set |h \<turnstile> get_disconnected_nodes disc_doc|\<^sub>r"
+ using CD.get_disconnected_nodes_ptr_in_heap assms(5)
+ assms(6) by auto
+
+
+ have h5: "\<exists>!x. x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h))) \<and>
+h \<turnstile> Heap_Error_Monad.bind (get_disconnected_nodes x)
+ (\<lambda>children. return (node_ptr \<in> set children)) \<rightarrow>\<^sub>r True"
+ apply(auto intro!: bind_pure_returns_result_I)[1]
+ apply (smt CD.get_disconnected_nodes_ok CD.get_disconnected_nodes_pure
+ \<open>\<exists>document_ptr\<in>fset (document_ptr_kinds h). node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r\<close>
+ assms(2) bind_pure_returns_result_I2 notin_fset return_returns_result select_result_I2)
+
+ apply(auto elim!: bind_returns_result_E2 intro!: bind_pure_returns_result_I)[1]
+ using heap_is_wellformed_one_disc_parent assms(1)
+ by blast
+ let ?filter_M = "filter_M
+ (\<lambda>document_ptr.
+ Heap_Error_Monad.bind (get_disconnected_nodes document_ptr)
+ (\<lambda>disconnected_nodes. return (node_ptr \<in> set disconnected_nodes)))
+ (sorted_list_of_set (fset (document_ptr_kinds h)))"
+ have "h \<turnstile> ok (?filter_M)"
+ using CD.get_disconnected_nodes_ok
+ by (smt CD.get_disconnected_nodes_pure DocumentMonad.ptr_kinds_M_ptr_kinds
+ DocumentMonad.ptr_kinds_ptr_kinds_M assms(2) bind_is_OK_pure_I bind_pure_I document_ptr_kinds_M_def
+ filter_M_is_OK_I l_ptr_kinds_M.ptr_kinds_M_ok return_ok return_pure returns_result_select_result)
+ then
+ obtain candidates where candidates: "h \<turnstile> ?filter_M \<rightarrow>\<^sub>r candidates"
+ by auto
+ have "candidates = [disc_doc]"
+ apply(rule filter_M_ex1[OF candidates \<open>disc_doc \<in>
+set (sorted_list_of_set (fset (document_ptr_kinds h)))\<close> h5])
+ using \<open>node_ptr \<in> set |h \<turnstile> get_disconnected_nodes disc_doc|\<^sub>r\<close>
+ \<open>disc_doc \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))\<close>
+ by(auto simp add: CD.get_disconnected_nodes_ok assms(2) intro!: bind_pure_I
+ intro!: bind_pure_returns_result_I)
+
+ then
+ show ?thesis
+ using \<open>node_ptr |\<in>| node_ptr_kinds h\<close> candidates
+ by(auto simp add: bind_pure_I get_disconnected_document_def
+ elim!: bind_returns_result_E2
+ intro!: bind_pure_returns_result_I filter_M_pure_I)
+qed
+
+lemma get_ancestors_di_obtains_children_or_shadow_root_or_disconnected_node:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ and "h \<turnstile> get_ancestors_di ptr \<rightarrow>\<^sub>r ancestors"
+ and "ancestor \<noteq> ptr"
+ and "ancestor \<in> set ancestors"
+ shows "((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ancestor \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast ancestor_child \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)
+ \<or> ((\<forall>ancestor_element shadow_root. ancestor = cast ancestor_element \<longrightarrow>
+h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root \<longrightarrow> cast shadow_root \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow>
+thesis)
+ \<or> ((\<forall>disc_doc disc_nodes disc_node. ancestor = cast disc_doc \<longrightarrow>
+h \<turnstile> get_disconnected_nodes disc_doc \<rightarrow>\<^sub>r disc_nodes \<longrightarrow> disc_node \<in> set disc_nodes \<longrightarrow>
+cast disc_node \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)"
+proof (insert assms(4) assms(5) assms(6), induct ptr arbitrary: ancestors
+ rule: heap_wellformed_induct_rev_si[OF assms(1)])
+ case (1 child)
+ then show ?case
+ proof (cases "cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child")
+ case None
+ then obtain shadow_root where shadow_root: "child = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root"
+ using 1(4) 1(5) 1(6)
+ by(auto simp add: get_ancestors_di_def[of child] elim!: bind_returns_result_E2
+ split: option.splits)
+ then obtain host where host: "h \<turnstile> get_host shadow_root \<rightarrow>\<^sub>r host"
+ by (metis "1.prems"(1) assms(1) assms(2) assms(3) document_ptr_kinds_commutes
+ get_ancestors_di_ptrs_in_heap is_OK_returns_result_E local.get_ancestors_di_ptr local.get_host_ok
+ shadow_root_ptr_kinds_commutes)
+ then obtain host_ancestors where host_ancestors:
+ "h \<turnstile> get_ancestors_di (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host) \<rightarrow>\<^sub>r host_ancestors"
+ by (metis "1.prems"(1) assms(1) assms(2) assms(3) get_ancestors_di_also_host get_ancestors_di_ok
+ get_ancestors_di_ptrs_in_heap is_OK_returns_result_E local.get_ancestors_di_ptr shadow_root)
+ then have "ancestors = cast shadow_root # host_ancestors"
+ using 1(4) 1(5) 1(3) None shadow_root host
+ by(auto simp add: get_ancestors_di_def[of child, simplified shadow_root]
+ elim!: bind_returns_result_E2 dest!: returns_result_eq[OF host] split: option.splits)
+ then show ?thesis
+ proof (cases "ancestor = cast host")
+ case True
+ then show ?thesis
+ using "1.prems"(1) host local.get_ancestors_di_ptr local.shadow_root_host_dual shadow_root
+ by blast
+ next
+ case False
+ have "ancestor \<in> set ancestors"
+ using host host_ancestors 1(3) get_ancestors_di_also_host assms(1) assms(2) assms(3)
+ using "1.prems"(3) by blast
+ then have "((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ancestor \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_child \<in> set host_ancestors \<longrightarrow> thesis) \<longrightarrow>
+thesis) \<or>
+ ((\<forall>ancestor_element shadow_root. ancestor = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_element \<longrightarrow>
+h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root \<longrightarrow>
+cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root \<in> set host_ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)
+ \<or> ((\<forall>disc_doc disc_nodes disc_node. ancestor = cast disc_doc \<longrightarrow>
+h \<turnstile> get_disconnected_nodes disc_doc \<rightarrow>\<^sub>r disc_nodes \<longrightarrow> disc_node \<in> set disc_nodes \<longrightarrow>
+cast disc_node \<in> set host_ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)"
+ using "1.hyps"(2) "1.prems"(2) False \<open>ancestors = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root # host_ancestors\<close>
+ host host_ancestors shadow_root
+ by auto
+ then show ?thesis
+ using \<open>ancestors = cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root # host_ancestors\<close>
+ by auto
+ qed
+ next
+ case (Some child_node)
+ then obtain parent_opt where parent_opt: "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r parent_opt"
+ by (metis (no_types, lifting) "1.prems"(1) assms(1) assms(2) assms(3)
+ get_ancestors_di_ptrs_in_heap is_OK_returns_result_E local.get_ancestors_di_ptr
+ local.get_parent_ok node_ptr_casts_commute node_ptr_kinds_commutes)
+ then show ?thesis
+ proof (induct parent_opt)
+ case None
+ then obtain disc_doc where disc_doc: "h \<turnstile> get_disconnected_document child_node \<rightarrow>\<^sub>r disc_doc"
+ by (meson assms(1) assms(2) assms(3) is_OK_returns_result_E local.get_disconnected_document_ok)
+ then obtain parent_ancestors where parent_ancestors: "h \<turnstile> get_ancestors_di (cast disc_doc) \<rightarrow>\<^sub>r parent_ancestors"
+ by (meson assms(1) assms(2) assms(3) document_ptr_kinds_commutes is_OK_returns_result_E
+ l_get_ancestors_di_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M.get_ancestors_di_ok l_get_ancestors_di_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms
+ local.get_disconnected_document_disconnected_document_in_heap)
+ then have "ancestors = cast child_node # parent_ancestors"
+ using 1(4) 1(5) 1(6) Some \<open>cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child = Some child_node\<close>
+ apply(auto simp add: get_ancestors_di_def[of child,
+ simplified \<open>cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child = Some child_node\<close>] intro!: bind_pure_I
+ elim!: bind_returns_result_E2 dest!: returns_result_eq[OF disc_doc] split: option.splits)[1]
+ apply (simp add: returns_result_eq)
+ by (meson None.prems option.distinct(1) returns_result_eq)
+ then show ?thesis
+ proof (cases "ancestor = cast disc_doc")
+ case True
+ then show ?thesis
+ by (metis \<open>ancestors = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node # parent_ancestors\<close> disc_doc
+ list.set_intros(1) local.disc_doc_disc_node_dual)
+ next
+ case False
+ have "ancestor \<in> set ancestors"
+ by (simp add: "1.prems"(3))
+ then have "((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ancestor \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_child \<in> set parent_ancestors \<longrightarrow> thesis) \<longrightarrow>
+thesis) \<or>
+ ((\<forall>ancestor_element shadow_root. ancestor = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_element \<longrightarrow>
+h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root \<longrightarrow>
+cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root \<in> set parent_ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)
+ \<or> ((\<forall>disc_doc disc_nodes disc_node. ancestor = cast disc_doc \<longrightarrow>
+h \<turnstile> get_disconnected_nodes disc_doc \<rightarrow>\<^sub>r disc_nodes \<longrightarrow> disc_node \<in> set disc_nodes \<longrightarrow>
+cast disc_node \<in> set parent_ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)"
+ using "1.hyps"(3) "1.prems"(2) False Some \<open>cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child = Some child_node\<close>
+ \<open>ancestors = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node # parent_ancestors\<close> disc_doc parent_ancestors
+ by auto
+ then show ?thesis
+ using \<open>ancestors = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node # parent_ancestors\<close> by auto
+ qed
+ next
+ case (Some option)
+ then obtain parent where parent: "h \<turnstile> get_parent child_node \<rightarrow>\<^sub>r Some parent"
+ using 1(4) 1(5) 1(6)
+ by(auto simp add: get_ancestors_di_def[of child] intro!: bind_pure_I
+ elim!: bind_returns_result_E2 split: option.splits)
+ then obtain parent_ancestors where parent_ancestors:
+ "h \<turnstile> get_ancestors_di parent \<rightarrow>\<^sub>r parent_ancestors"
+ by (meson assms(1) assms(2) assms(3) get_ancestors_di_ok is_OK_returns_result_E
+ local.get_parent_parent_in_heap)
+ then have "ancestors = cast child_node # parent_ancestors"
+ using 1(4) 1(5) 1(6) Some \<open>cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child = Some child_node\<close>
+ by(auto simp add: get_ancestors_di_def[of child, simplified
+ \<open>cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child = Some child_node\<close>] dest!: elim!: bind_returns_result_E2
+ dest!: returns_result_eq[OF parent] split: option.splits)
+ then show ?thesis
+ proof (cases "ancestor = parent")
+ case True
+ then show ?thesis
+ by (metis \<open>ancestors = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node # parent_ancestors\<close>
+ list.set_intros(1) local.get_parent_child_dual parent)
+ next
+ case False
+ have "ancestor \<in> set ancestors"
+ by (simp add: "1.prems"(3))
+ then have "((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ancestor \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_child \<in> set parent_ancestors \<longrightarrow> thesis) \<longrightarrow> thesis) \<or>
+ ((\<forall>ancestor_element shadow_root. ancestor = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ancestor_element \<longrightarrow>
+h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root \<longrightarrow> cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root \<in> set parent_ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)
+ \<or> ((\<forall>disc_doc disc_nodes disc_node. ancestor = cast disc_doc \<longrightarrow>
+h \<turnstile> get_disconnected_nodes disc_doc \<rightarrow>\<^sub>r disc_nodes \<longrightarrow> disc_node \<in> set disc_nodes \<longrightarrow>
+cast disc_node \<in> set parent_ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)"
+ using "1.hyps"(1) "1.prems"(2) False Some \<open>cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child = Some child_node\<close>
+ \<open>ancestors = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node # parent_ancestors\<close> parent parent_ancestors
+ by auto
+ then show ?thesis
+ using \<open>ancestors = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child_node # parent_ancestors\<close>
+ by auto
+ qed
+ qed
+ qed
+qed
+
+lemma get_ancestors_di_parent_child_a_host_shadow_root_rel:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ assumes "h \<turnstile> get_ancestors_di child \<rightarrow>\<^sub>r ancestors"
+ shows "(ptr, child) \<in> (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>* \<longleftrightarrow> ptr \<in> set ancestors"
+proof
+ assume "(ptr, child) \<in> (parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>* "
+ then show "ptr \<in> set ancestors"
+ proof (induct ptr rule: heap_wellformed_induct_si[OF assms(1)])
+ case (1 ptr)
+ then show ?case
+ proof (cases "ptr = child")
+ case True
+ then show ?thesis
+ using assms(4) get_ancestors_di_ptr by blast
+ next
+ case False
+ obtain ptr_child where
+ ptr_child: "(ptr, ptr_child) \<in> (parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h) \<and>
+(ptr_child, child) \<in> (parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ using converse_rtranclE[OF 1(4)] \<open>ptr \<noteq> child\<close>
+ by metis
+ then show ?thesis
+ proof(cases "(ptr, ptr_child) \<in> parent_child_rel h")
+ case True
+
+ then obtain ptr_child_node
+ where ptr_child_ptr_child_node: "ptr_child = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr_child_node"
+ using ptr_child node_ptr_casts_commute3 CD.parent_child_rel_node_ptr
+ by (metis)
+ then obtain children where
+ children: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children" and
+ ptr_child_node: "ptr_child_node \<in> set children"
+ proof -
+ assume a1: "\<And>children. \<lbrakk>h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children; ptr_child_node \<in> set children\<rbrakk>
+ \<Longrightarrow> thesis"
+
+ have "ptr |\<in>| object_ptr_kinds h"
+ using CD.parent_child_rel_parent_in_heap True by blast
+ moreover have "ptr_child_node \<in> set |h \<turnstile> get_child_nodes ptr|\<^sub>r"
+ by (metis True assms(2) assms(3) calculation local.CD.parent_child_rel_child
+ local.get_child_nodes_ok local.known_ptrs_known_ptr ptr_child_ptr_child_node
+ returns_result_select_result)
+ ultimately show ?thesis
+ using a1 get_child_nodes_ok \<open>type_wf h\<close> \<open>known_ptrs h\<close>
+ by (meson local.known_ptrs_known_ptr returns_result_select_result)
+ qed
+ moreover have "(cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr_child_node, child) \<in>
+(parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ using ptr_child True ptr_child_ptr_child_node by auto
+ ultimately have "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr_child_node \<in> set ancestors"
+ using 1 by auto
+ moreover have "h \<turnstile> get_parent ptr_child_node \<rightarrow>\<^sub>r Some ptr"
+ using assms(1) children ptr_child_node child_parent_dual
+ using \<open>known_ptrs h\<close> \<open>type_wf h\<close> by blast
+ ultimately show ?thesis
+ using get_ancestors_di_also_parent assms \<open>type_wf h\<close> by blast
+ next
+ case False
+ then show ?thesis
+ proof (cases "(ptr, ptr_child) \<in> a_host_shadow_root_rel h")
+ case True
+ then
+ obtain host where host: "ptr = cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r host"
+ using ptr_child
+ by(auto simp add: a_host_shadow_root_rel_def)
+ then obtain shadow_root where shadow_root: "h \<turnstile> get_shadow_root host \<rightarrow>\<^sub>r Some shadow_root"
+ and ptr_child_shadow_root: "ptr_child = cast shadow_root"
+ using False True
+ apply(auto simp add: a_host_shadow_root_rel_def)[1]
+ by (metis (no_types, lifting) assms(3) local.get_shadow_root_ok select_result_I)
+
+ moreover have "(cast shadow_root, child) \<in>
+(parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ using ptr_child ptr_child_shadow_root by blast
+ ultimately have "cast shadow_root \<in> set ancestors"
+ using "1.hyps"(2) host by blast
+ moreover have "h \<turnstile> get_host shadow_root \<rightarrow>\<^sub>r host"
+ by (metis assms(1) assms(2) assms(3) is_OK_returns_result_E local.get_host_ok
+ local.get_shadow_root_shadow_root_ptr_in_heap local.shadow_root_host_dual local.shadow_root_same_host
+ shadow_root)
+ ultimately show ?thesis
+ using get_ancestors_di_also_host assms(1) assms(2) assms(3) assms(4) host
+ by blast
+ next
+ case False
+ then
+ obtain disc_doc where disc_doc: "ptr = cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r disc_doc"
+ using ptr_child \<open>(ptr, ptr_child) \<notin> parent_child_rel h\<close>
+ by(auto simp add: a_ptr_disconnected_node_rel_def)
+ then obtain disc_node disc_nodes where disc_nodes:
+ "h \<turnstile> get_disconnected_nodes disc_doc \<rightarrow>\<^sub>r disc_nodes"
+ and disc_node: "disc_node \<in> set disc_nodes"
+ and ptr_child_disc_node: "ptr_child = cast disc_node"
+ using False \<open>(ptr, ptr_child) \<notin> parent_child_rel h\<close> ptr_child
+ apply(auto simp add: a_ptr_disconnected_node_rel_def)[1]
+ by (metis (no_types, lifting) CD.get_disconnected_nodes_ok assms(3)
+ returns_result_select_result)
+
+ moreover have "(cast disc_node, child) \<in>
+(parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ using ptr_child ptr_child_disc_node by blast
+ ultimately have "cast disc_node \<in> set ancestors"
+ using "1.hyps"(3) disc_doc by blast
+ moreover have "h \<turnstile> get_parent disc_node \<rightarrow>\<^sub>r None"
+ using \<open>(ptr, ptr_child) \<notin> parent_child_rel h\<close>
+ apply(auto simp add: parent_child_rel_def ptr_child_disc_node)[1]
+ by (smt assms(1) assms(2) assms(3) assms(4) calculation disc_node disc_nodes
+ get_ancestors_di_ptrs_in_heap is_OK_returns_result_E local.CD.a_heap_is_wellformed_def
+ local.CD.distinct_lists_no_parent local.CD.heap_is_wellformed_impl local.get_parent_child_dual
+ local.get_parent_ok local.get_parent_parent_in_heap local.heap_is_wellformed_def
+ node_ptr_kinds_commutes select_result_I2 split_option_ex)
+ then
+ have "h \<turnstile> get_disconnected_document disc_node \<rightarrow>\<^sub>r disc_doc"
+ using disc_node_disc_doc_dual disc_nodes disc_node assms(1) assms(2) assms(3)
+ by blast
+ ultimately show ?thesis
+ using \<open>h \<turnstile> get_parent disc_node \<rightarrow>\<^sub>r None\<close> assms(1) assms(2) assms(3) assms(4)
+ disc_doc get_ancestors_di_also_disconnected_document
+ by blast
+ qed
+ qed
+ qed
+ qed
+next
+ assume "ptr \<in> set ancestors"
+ then show "(ptr, child) \<in> (parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ proof (induct ptr rule: heap_wellformed_induct_si[OF assms(1)])
+ case (1 ptr)
+ then show ?case
+ proof (cases "ptr = child")
+ case True
+ then show ?thesis
+ by simp
+ next
+ case False
+ have 2: "\<And>thesis. ((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast ancestor_child \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)
+ \<or> ((\<forall>ancestor_element shadow_root. ptr = cast ancestor_element \<longrightarrow>
+h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root \<longrightarrow> cast shadow_root \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow>
+thesis)
+ \<or> ((\<forall>disc_doc disc_nodes disc_node. ptr = cast disc_doc \<longrightarrow>
+h \<turnstile> get_disconnected_nodes disc_doc \<rightarrow>\<^sub>r disc_nodes \<longrightarrow> disc_node \<in> set disc_nodes \<longrightarrow>
+cast disc_node \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)"
+ using "1.prems" False assms(1) assms(2) assms(3) assms(4)
+ get_ancestors_di_obtains_children_or_shadow_root_or_disconnected_node by blast
+ then show ?thesis
+ proof (cases "\<forall>thesis. ((\<forall>children ancestor_child. h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<longrightarrow>
+ancestor_child \<in> set children \<longrightarrow> cast ancestor_child \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)")
+ case True
+ then obtain children ancestor_child
+ where "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ and "ancestor_child \<in> set children"
+ and "cast ancestor_child \<in> set ancestors"
+ by blast
+ then show ?thesis
+ by (meson "1.hyps"(1) in_rtrancl_UnI local.CD.parent_child_rel_child r_into_rtrancl
+ rtrancl_trans)
+ next
+ case False
+ note f1 = this
+ then show ?thesis
+ proof (cases "\<forall>thesis. ((\<forall>disc_doc disc_nodes disc_node. ptr = cast disc_doc \<longrightarrow>
+h \<turnstile> get_disconnected_nodes disc_doc \<rightarrow>\<^sub>r disc_nodes \<longrightarrow> disc_node \<in> set disc_nodes \<longrightarrow>
+cast disc_node \<in> set ancestors \<longrightarrow> thesis) \<longrightarrow> thesis)")
+ case True
+ then obtain disc_doc disc_nodes disc_node
+ where "ptr = cast disc_doc"
+ and "h \<turnstile> get_disconnected_nodes disc_doc \<rightarrow>\<^sub>r disc_nodes"
+ and "disc_node \<in> set disc_nodes"
+ and "cast disc_node \<in> set ancestors"
+ by blast
+ then show ?thesis
+ by (meson "1.hyps"(3) in_rtrancl_UnI
+ local.a_ptr_disconnected_node_rel_disconnected_node r_into_rtrancl rtrancl_trans)
+ next
+ case False
+ then
+ obtain ancestor_element shadow_root
+ where "ptr = cast ancestor_element"
+ and "h \<turnstile> get_shadow_root ancestor_element \<rightarrow>\<^sub>r Some shadow_root"
+ and "cast shadow_root \<in> set ancestors"
+ using f1 2 by smt
+ then show ?thesis
+ by (meson "1.hyps"(2) in_rtrancl_UnI local.a_host_shadow_root_rel_shadow_root
+ r_into_rtrancl rtrancl_trans)
+ qed
+ qed
+ qed
+ qed
+qed
+end
+interpretation i_get_ancestors_di_wf?: l_get_ancestors_di_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr known_ptrs get_parent get_parent_locs get_child_nodes get_child_nodes_locs
+ get_host get_host_locs get_disconnected_document get_disconnected_document_locs get_ancestors_di
+ get_ancestors_di_locs get_disconnected_nodes get_disconnected_nodes_locs get_shadow_root
+ get_shadow_root_locs get_tag_name get_tag_name_locs heap_is_wellformed parent_child_rel
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ by(auto simp add: l_get_ancestors_di_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_get_ancestors_di_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_owner\_document\<close>
+
+locale l_get_owner_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_disconnected_nodes +
+ l_get_child_nodes +
+ l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent_wf +
+ l_known_ptrs +
+ l_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ assumes known_ptr_impl: "known_ptr = ShadowRootClass.known_ptr"
+begin
+lemma get_owner_document_disconnected_nodes:
+ assumes "heap_is_wellformed h"
+ assumes "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes"
+ assumes "node_ptr \<in> set disc_nodes"
+ assumes known_ptrs: "known_ptrs h"
+ assumes type_wf: "type_wf h"
+ shows "h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r document_ptr"
+proof -
+ have 2: "node_ptr |\<in>| node_ptr_kinds h"
+ using assms
+ apply(auto simp add: heap_is_wellformed_def CD.heap_is_wellformed_def CD.a_all_ptrs_in_heap_def)[1]
+ using assms(1) local.heap_is_wellformed_disc_nodes_in_heap by blast
+ have 3: "document_ptr |\<in>| document_ptr_kinds h"
+ using assms(2) get_disconnected_nodes_ptr_in_heap by blast
+ then have 4: "\<not>(\<exists>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h \<and> node_ptr \<in> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r)"
+ using CD.distinct_lists_no_parent assms unfolding heap_is_wellformed_def CD.heap_is_wellformed_def
+ by simp
+ moreover have "(\<exists>document_ptr. document_ptr |\<in>| document_ptr_kinds h \<and>
+node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r) \<or>
+ (\<exists>parent_ptr. parent_ptr |\<in>| object_ptr_kinds h \<and> node_ptr \<in> set |h \<turnstile> get_child_nodes parent_ptr|\<^sub>r)"
+ using assms(1) 2 "3" assms(2) assms(3) by auto
+ ultimately have 0: "\<exists>!document_ptr\<in>set |h \<turnstile> document_ptr_kinds_M|\<^sub>r.
+node_ptr \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ using concat_map_distinct assms(1) known_ptrs_implies
+ by (smt CD.heap_is_wellformed_one_disc_parent DocumentMonad.ptr_kinds_ptr_kinds_M
+ disjoint_iff_not_equal local.get_disconnected_nodes_ok local.heap_is_wellformed_def
+ returns_result_select_result type_wf)
+
+
+ have "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r None"
+ using 4 2
+ apply(auto simp add: get_parent_def intro!: bind_pure_returns_result_I filter_M_pure_I bind_pure_I )[1]
+ apply(auto intro!: filter_M_empty_I bind_pure_I bind_pure_returns_result_I)[1]
+ using get_child_nodes_ok assms(4) type_wf
+ by (metis get_child_nodes_ok known_ptrs_known_ptr returns_result_select_result)
+
+
+ then have 4: "h \<turnstile> get_root_node (cast node_ptr) \<rightarrow>\<^sub>r cast node_ptr"
+ using get_root_node_no_parent
+ by simp
+ obtain document_ptrs where document_ptrs: "h \<turnstile> document_ptr_kinds_M \<rightarrow>\<^sub>r document_ptrs"
+ by simp
+ then have "h \<turnstile> ok (filter_M (\<lambda>document_ptr. do {
+ disconnected_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ return (((cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)) \<in> cast ` set disconnected_nodes)
+ }) document_ptrs)"
+ using assms(1) get_disconnected_nodes_ok type_wf
+ by(auto intro!: bind_is_OK_I2 filter_M_is_OK_I bind_pure_I)
+ then obtain candidates where
+ candidates: "h \<turnstile> filter_M (\<lambda>document_ptr. do {
+ disconnected_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ return (((cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)) \<in> cast ` set disconnected_nodes)
+ }) document_ptrs \<rightarrow>\<^sub>r candidates"
+ by auto
+
+ have filter: "filter (\<lambda>document_ptr. |h \<turnstile> do {
+ disconnected_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ return (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr \<in> cast ` set disconnected_nodes)
+ }|\<^sub>r) document_ptrs = [document_ptr]"
+ apply(rule filter_ex1)
+ using 0 document_ptrs apply(simp)[1]
+ apply (smt "0" "3" assms bind_is_OK_pure_I bind_pure_returns_result_I bind_pure_returns_result_I2
+ bind_returns_result_E2 bind_returns_result_E3 document_ptr_kinds_M_def get_disconnected_nodes_ok
+ get_disconnected_nodes_pure image_eqI is_OK_returns_result_E l_ptr_kinds_M.ptr_kinds_ptr_kinds_M return_ok
+ return_returns_result returns_result_eq select_result_E select_result_I select_result_I2 select_result_I2)
+ using assms(2) assms(3)
+ apply (smt bind_is_OK_I2 bind_returns_result_E3 get_disconnected_nodes_pure image_eqI
+ is_OK_returns_result_I return_ok return_returns_result select_result_E)
+ using document_ptrs 3 apply(simp)
+ using document_ptrs
+ by simp
+ have "h \<turnstile> filter_M (\<lambda>document_ptr. do {
+ disconnected_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ return (((cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr)) \<in> cast ` set disconnected_nodes)
+ }) document_ptrs \<rightarrow>\<^sub>r [document_ptr]"
+ apply(rule filter_M_filter2)
+ using get_disconnected_nodes_ok document_ptrs 3 assms(1) type_wf filter
+ by(auto intro: bind_pure_I bind_is_OK_I2)
+
+ with 4 document_ptrs have "h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r document_ptr"
+ by(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: bind_pure_returns_result_I
+ filter_M_pure_I bind_pure_I split: option.splits)
+ moreover have "known_ptr (cast node_ptr)"
+ using known_ptrs_known_ptr[OF known_ptrs, where ptr="cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr"] 2
+ known_ptrs_implies by(simp)
+ ultimately show ?thesis
+ using 2
+ apply(auto simp add: CD.a_get_owner_document_tups_def get_owner_document_def
+ a_get_owner_document_tups_def known_ptr_impl)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ apply(drule(1) known_ptr_not_shadow_root_ptr)
+ apply(drule(1) known_ptr_not_document_ptr)
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ by(auto split: option.splits intro!: bind_pure_returns_result_I)
+qed
+
+lemma in_disconnected_nodes_no_parent:
+ assumes "heap_is_wellformed h"
+ assumes "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r None"
+ assumes "h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r owner_document"
+ assumes "h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes"
+ assumes "known_ptrs h"
+ assumes "type_wf h"
+ shows "node_ptr \<in> set disc_nodes"
+proof -
+ have "\<And>parent. parent |\<in>| object_ptr_kinds h \<Longrightarrow> node_ptr \<notin> set |h \<turnstile> get_child_nodes parent|\<^sub>r"
+ using assms(2)
+ by (meson get_child_nodes_ok assms(1) assms(5) assms(6) local.child_parent_dual
+ local.known_ptrs_known_ptr option.distinct(1) returns_result_eq returns_result_select_result)
+ then show ?thesis
+ by (smt assms(1) assms(2) assms(3) assms(4) assms(5) assms(6) finite_set_in
+ is_OK_returns_result_I local.get_disconnected_nodes_ok local.get_owner_document_disconnected_nodes
+ local.get_parent_ptr_in_heap local.heap_is_wellformed_children_disc_nodes returns_result_select_result
+ select_result_I2)
+qed
+
+
+lemma get_owner_document_owner_document_in_heap_node:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document"
+ shows "owner_document |\<in>| document_ptr_kinds h"
+proof -
+ obtain root where
+ root: "h \<turnstile> get_root_node (cast node_ptr) \<rightarrow>\<^sub>r root"
+ using assms(4)
+ by(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ split: option.splits)
+
+ then show ?thesis
+ proof (cases "is_document_ptr root")
+ case True
+ then show ?thesis
+ using assms(4) root
+ apply(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ intro!: filter_M_pure_I bind_pure_I split: option.splits)[1]
+ apply(drule(1) returns_result_eq) apply(auto)[1]
+ using assms document_ptr_kinds_commutes get_root_node_root_in_heap
+ by blast
+ next
+ case False
+ have "known_ptr root"
+ using assms local.get_root_node_root_in_heap local.known_ptrs_known_ptr root by blast
+ have "root |\<in>| object_ptr_kinds h"
+ using root
+ using assms local.get_root_node_root_in_heap
+ by blast
+
+ show ?thesis
+ proof (cases "is_shadow_root_ptr root")
+ case True
+ then show ?thesis
+ using assms(4) root
+ apply(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ intro!: filter_M_pure_I bind_pure_I split: option.splits)[1]
+ apply(drule(1) returns_result_eq) apply(auto)[1]
+ using assms document_ptr_kinds_commutes get_root_node_root_in_heap
+ by blast
+ next
+ case False
+ then have "is_node_ptr_kind root"
+ using \<open>\<not> is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root\<close> \<open>known_ptr root\<close> \<open>root |\<in>| object_ptr_kinds h\<close>
+ apply(simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs)
+ using is_node_ptr_kind_none
+ by force
+ then
+ have "(\<exists>document_ptr \<in> fset (document_ptr_kinds h). root \<in> cast ` set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)"
+ using local.child_parent_dual local.get_child_nodes_ok local.get_root_node_same_no_parent
+ local.heap_is_wellformed_children_disc_nodes local.known_ptrs_known_ptr node_ptr_casts_commute3
+ node_ptr_inclusion node_ptr_kinds_commutes notin_fset option.distinct(1) returns_result_eq
+ returns_result_select_result root
+ by (metis (no_types, lifting) assms \<open>root |\<in>| object_ptr_kinds h\<close>)
+ then obtain some_owner_document where
+ "some_owner_document |\<in>| document_ptr_kinds h" and
+ "root \<in> cast ` set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r"
+ by auto
+ then
+ obtain candidates where
+ candidates: "h \<turnstile> filter_M
+ (\<lambda>document_ptr.
+ Heap_Error_Monad.bind (get_disconnected_nodes document_ptr)
+ (\<lambda>disconnected_nodes. return (root \<in> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ` set disconnected_nodes)))
+ (sorted_list_of_set (fset (document_ptr_kinds h)))
+ \<rightarrow>\<^sub>r candidates"
+ by (metis (no_types, lifting) assms bind_is_OK_I2 bind_pure_I filter_M_is_OK_I finite_fset
+ is_OK_returns_result_E local.get_disconnected_nodes_ok local.get_disconnected_nodes_pure notin_fset
+ return_ok return_pure sorted_list_of_set(1))
+ then have "some_owner_document \<in> set candidates"
+ apply(rule filter_M_in_result_if_ok)
+ using \<open>some_owner_document |\<in>| document_ptr_kinds h\<close>
+ \<open>root \<in> cast ` set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r\<close>
+ apply(auto intro!: bind_pure_I bind_pure_returns_result_I)[1]
+ using \<open>some_owner_document |\<in>| document_ptr_kinds h\<close>
+ \<open>root \<in> cast ` set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r\<close>
+ apply(auto intro!: bind_pure_I bind_pure_returns_result_I)[1]
+ using \<open>some_owner_document |\<in>| document_ptr_kinds h\<close>
+ \<open>root \<in> cast ` set |h \<turnstile> get_disconnected_nodes some_owner_document|\<^sub>r\<close>
+ apply(auto simp add: assms local.get_disconnected_nodes_ok
+ intro!: bind_pure_I bind_pure_returns_result_I)[1]
+ done
+
+ then have "candidates \<noteq> []"
+ by auto
+ then have "owner_document \<in> set candidates"
+ using assms(4) root
+ apply(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ intro!: filter_M_pure_I bind_pure_I split: option.splits)[1]
+ apply (metis candidates list.set_sel(1) returns_result_eq)
+ by (metis \<open>is_node_ptr_kind root\<close> node_ptr_no_document_ptr_cast returns_result_eq)
+
+ then show ?thesis
+ using candidates
+ by (meson bind_pure_I bind_returns_result_E2 filter_M_holds_for_result is_OK_returns_result_I
+ local.get_disconnected_nodes_ptr_in_heap local.get_disconnected_nodes_pure return_pure)
+ qed
+ qed
+qed
+
+lemma get_owner_document_owner_document_in_heap:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ shows "owner_document |\<in>| document_ptr_kinds h"
+ using assms
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_split_asm)+
+proof -
+ assume "h \<turnstile> invoke [] ptr () \<rightarrow>\<^sub>r owner_document"
+ then show "owner_document |\<in>| document_ptr_kinds h"
+ by (meson invoke_empty is_OK_returns_result_I)
+next
+ assume "h \<turnstile> Heap_Error_Monad.bind (check_in_heap ptr)
+ (\<lambda>_. (CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) ptr ())
+ \<rightarrow>\<^sub>r owner_document"
+ then show "owner_document |\<in>| document_ptr_kinds h"
+ by(auto simp add: CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ split: if_splits)
+next
+ assume 0: "heap_is_wellformed h"
+ and 1: "type_wf h"
+ and 2: "known_ptrs h"
+ and 3: "\<not> is_element_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ and 4: "is_character_data_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ and 5: "h \<turnstile> Heap_Error_Monad.bind (check_in_heap ptr)
+(\<lambda>_. (CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r) ptr ()) \<rightarrow>\<^sub>r owner_document"
+ then show ?thesis
+ by (metis bind_returns_result_E2 check_in_heap_pure comp_apply
+ get_owner_document_owner_document_in_heap_node)
+next
+ assume 0: "heap_is_wellformed h"
+ and 1: "type_wf h"
+ and 2: "known_ptrs h"
+ and 3: "is_element_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ and 4: "h \<turnstile> Heap_Error_Monad.bind (check_in_heap ptr)
+(\<lambda>_. (CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r) ptr ()) \<rightarrow>\<^sub>r owner_document"
+ then show ?thesis
+ by (metis bind_returns_result_E2 check_in_heap_pure comp_apply get_owner_document_owner_document_in_heap_node)
+next
+ assume 0: "heap_is_wellformed h"
+ and 1: "type_wf h"
+ and 2: "known_ptrs h"
+ and 3: "\<not> is_element_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ and 4: "\<not> is_character_data_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ and 5: "\<not> is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ and 6: "is_shadow_root_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr"
+ and 7: "h \<turnstile> Heap_Error_Monad.bind (check_in_heap ptr)
+(\<lambda>_. (local.a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r \<circ> the \<circ> cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) ptr ()) \<rightarrow>\<^sub>r owner_document"
+ then show "owner_document |\<in>| document_ptr_kinds h"
+ by(auto simp add: CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ elim!: bind_returns_result_E2 split: if_splits)
+qed
+
+lemma get_owner_document_ok:
+ assumes "heap_is_wellformed h" "known_ptrs h" "type_wf h"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ shows "h \<turnstile> ok (get_owner_document ptr)"
+proof -
+ have "known_ptr ptr"
+ using assms(2) assms(4) local.known_ptrs_known_ptr
+ by blast
+ then show ?thesis
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ apply(auto simp add: known_ptr_impl)[1]
+ using NodeClass.a_known_ptr_def known_ptr_not_character_data_ptr known_ptr_not_document_ptr
+ known_ptr_not_shadow_root_ptr known_ptr_not_element_ptr apply blast
+ using assms(4)
+ apply(auto simp add: get_root_node_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ intro!: bind_is_OK_pure_I filter_M_pure_I bind_pure_I filter_M_is_OK_I
+ split: option.splits)[1]
+ using assms(4)
+ apply(auto simp add: get_root_node_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: bind_is_OK_pure_I
+ filter_M_pure_I bind_pure_I filter_M_is_OK_I split: option.splits)[1]
+ using assms(4)
+ apply(auto simp add: assms(1) assms(2) assms(3) local.get_ancestors_ok get_disconnected_nodes_ok
+ get_root_node_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: bind_is_OK_pure_I filter_M_pure_I bind_pure_I
+ filter_M_is_OK_I split: option.splits)[1]
+ using assms(4)
+ apply(auto simp add: assms(1) assms(2) assms(3) local.get_ancestors_ok get_disconnected_nodes_ok
+ get_root_node_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def intro!: bind_is_OK_pure_I filter_M_pure_I bind_pure_I
+ filter_M_is_OK_I split: option.splits)[1]
+ done
+qed
+
+lemma get_owner_document_child_same:
+ assumes "heap_is_wellformed h" "known_ptrs h" "type_wf h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ assumes "child \<in> set children"
+ shows "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<longleftrightarrow> h \<turnstile> get_owner_document (cast child) \<rightarrow>\<^sub>r owner_document"
+proof -
+ have "ptr |\<in>| object_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_result_I local.get_child_nodes_ptr_in_heap)
+ then have "known_ptr ptr"
+ using assms(2) local.known_ptrs_known_ptr by blast
+
+ have "cast child |\<in>| object_ptr_kinds h"
+ using assms(1) assms(4) assms(5) local.heap_is_wellformed_children_in_heap node_ptr_kinds_commutes
+ by blast
+ then
+ have "known_ptr (cast child)"
+ using assms(2) local.known_ptrs_known_ptr by blast
+ then have "is_character_data_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast child) \<or> is_element_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast child)"
+ by(auto simp add: known_ptr_impl NodeClass.a_known_ptr_def ElementClass.a_known_ptr_def
+ CharacterDataClass.a_known_ptr_def DocumentClass.a_known_ptr_def a_known_ptr_def
+ split: option.splits)
+ obtain root where root: "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ by (meson \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(1) assms(2) assms(3) is_OK_returns_result_E
+ local.get_root_node_ok)
+ then have "h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root"
+ using assms(1) assms(2) assms(3) assms(4) assms(5) local.child_parent_dual local.get_root_node_parent_same
+ by blast
+
+ have "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<longleftrightarrow> h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child () \<rightarrow>\<^sub>r owner_document"
+ proof (cases "is_document_ptr ptr")
+ case True
+ then obtain document_ptr where document_ptr: "cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr = ptr"
+ using case_optionE document_ptr_casts_commute by blast
+ then have "root = cast document_ptr"
+ using root
+ by(auto simp add: get_root_node_def get_ancestors_def elim!: bind_returns_result_E2
+ split: option.splits)
+
+ then have "h \<turnstile> CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr () \<rightarrow>\<^sub>r owner_document \<longleftrightarrow>
+h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child () \<rightarrow>\<^sub>r owner_document"
+ using document_ptr \<open>h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root\<close>[simplified \<open>root = cast document_ptr\<close>
+ document_ptr]
+ apply(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ elim!: bind_returns_result_E2 dest!: bind_returns_result_E3[rotated, OF
+ \<open>h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root\<close>[simplified \<open>root = cast document_ptr\<close> document_ptr], rotated]
+ intro!: bind_pure_returns_result_I filter_M_pure_I bind_pure_I split: if_splits option.splits)[1]
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> document_ptr_kinds_commutes by blast
+ then show ?thesis
+ using \<open>known_ptr ptr\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def known_ptr_impl)[1]
+ apply(split invoke_splits, ((rule conjI | rule impI)+)?)+
+ apply(drule(1) known_ptr_not_shadow_root_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_document_ptr)
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> True
+ by(auto simp add: document_ptr[symmetric] intro!: bind_pure_returns_result_I
+ split: option.splits)
+ next
+ case False
+ then show ?thesis
+ proof (cases "is_shadow_root_ptr ptr")
+ case True
+ then obtain shadow_root_ptr where shadow_root_ptr: "cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr = ptr"
+ using case_optionE shadow_root_ptr_casts_commute
+ by (metis (no_types, lifting) document_ptr_casts_commute3 is_document_ptr_kind_none option.case_eq_if)
+ then have "root = cast shadow_root_ptr"
+ using root
+ by(auto simp add: get_root_node_def get_ancestors_def elim!: bind_returns_result_E2
+ split: option.splits)
+
+ then have "h \<turnstile> a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r shadow_root_ptr () \<rightarrow>\<^sub>r owner_document \<longleftrightarrow>
+h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child () \<rightarrow>\<^sub>r owner_document"
+ using shadow_root_ptr \<open>h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root\<close>[simplified \<open>root = cast shadow_root_ptr\<close>
+ shadow_root_ptr]
+ apply(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ dest!: bind_returns_result_E3[rotated, OF \<open>h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root\<close>[simplified
+ \<open>root = cast shadow_root_ptr\<close> shadow_root_ptr], rotated] intro!: bind_pure_returns_result_I
+ filter_M_pure_I bind_pure_I split: if_splits option.splits)[1]
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> shadow_root_ptr_kinds_commutes document_ptr_kinds_commutes
+ by blast
+ then show ?thesis
+ using \<open>known_ptr ptr\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def known_ptr_impl)[1]
+ apply(split invoke_splits, ((rule conjI | rule impI)+)?)+
+ apply(drule(1) known_ptr_not_shadow_root_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_document_ptr)
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> True
+ using False
+ by(auto simp add: a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def shadow_root_ptr[symmetric]
+ intro!: bind_pure_returns_result_I split: option.splits)
+ next
+ case False
+ then obtain node_ptr where node_ptr: "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr = ptr"
+ using \<open>known_ptr ptr\<close> \<open>\<not> is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr\<close>
+ by(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+ then have "h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document \<longleftrightarrow>
+h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r child () \<rightarrow>\<^sub>r owner_document"
+ using root \<open>h \<turnstile> get_root_node (cast child) \<rightarrow>\<^sub>r root\<close>
+ unfolding CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ by (meson bind_pure_returns_result_I bind_returns_result_E3 local.get_root_node_pure)
+ then show ?thesis
+ using \<open>known_ptr ptr\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def known_ptr_impl)[1]
+ apply(split invoke_splits, ((rule conjI | rule impI)+)?)+
+ apply(drule(1) known_ptr_not_shadow_root_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_document_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close> False \<open>\<not> is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr\<close>
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close> False \<open>\<not> is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr\<close>
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close> False \<open>\<not> is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr\<close>
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close> False \<open>\<not> is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr\<close>
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close> False \<open>\<not> is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr\<close>
+ apply(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I split: )[1]
+ apply(split invoke_splits, ((rule conjI | rule impI)+)?)+
+ by(auto simp add: node_ptr[symmetric] intro!: bind_pure_returns_result_I dest!: is_OK_returns_result_I)
+ qed
+ qed
+ then show ?thesis
+ using \<open>is_character_data_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<or> is_element_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child)\<close>
+ using \<open>cast child |\<in>| object_ptr_kinds h\<close>
+ by(auto simp add: get_owner_document_def[of "cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child"]
+ a_get_owner_document_tups_def CD.a_get_owner_document_tups_def split: invoke_splits)
+qed
+
+lemma get_owner_document_rel:
+ assumes "heap_is_wellformed h" "known_ptrs h" "type_wf h"
+ assumes "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ assumes "ptr \<noteq> cast owner_document"
+ shows "(cast owner_document, ptr) \<in> (parent_child_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+proof -
+ have "ptr |\<in>| object_ptr_kinds h"
+ using assms
+ by (meson is_OK_returns_result_I local.get_owner_document_ptr_in_heap)
+ then
+ have "known_ptr ptr"
+ using known_ptrs_known_ptr[OF assms(2)] by simp
+ have "is_node_ptr_kind ptr"
+ proof (rule ccontr)
+ assume "\<not> is_node_ptr_kind ptr"
+ then
+ show False
+ using assms(4) \<open>known_ptr ptr\<close>
+ apply(auto simp add: known_ptr_impl get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits)+
+ apply(drule(1) known_ptr_not_shadow_root_ptr)
+ apply(drule(1) known_ptr_not_document_ptr)
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(5)
+ by(auto simp add: CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ elim!: bind_returns_result_E2 split: if_splits option.splits)
+ qed
+ then obtain node_ptr where node_ptr: "ptr = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr"
+ by (metis node_ptr_casts_commute3)
+ then have "h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document"
+ using assms(4) \<open>known_ptr ptr\<close>
+ apply(auto simp add: known_ptr_impl get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits)+
+ apply(drule(1) known_ptr_not_shadow_root_ptr)
+ apply(drule(1) known_ptr_not_document_ptr)
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close>
+ by (auto simp add: is_document_ptr_kind_none)
+ then obtain root where root: "h \<turnstile> get_root_node (cast node_ptr) \<rightarrow>\<^sub>r root"
+ by(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2)
+ then have "root |\<in>| object_ptr_kinds h"
+ using assms(1) assms(2) assms(3) local.get_root_node_root_in_heap by blast
+ then
+ have "known_ptr root"
+ using \<open>known_ptrs h\<close> local.known_ptrs_known_ptr by blast
+
+ have "(root, cast node_ptr) \<in> (parent_child_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ using root
+ by (simp add: assms(1) assms(2) assms(3) in_rtrancl_UnI local.get_root_node_parent_child_rel)
+
+ show ?thesis
+ proof (cases "is_document_ptr_kind root")
+ case True
+ then have "root = cast owner_document"
+ using \<open>h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document\<close> root
+ by(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def is_document_ptr_kind_def
+ dest!: bind_returns_result_E3[rotated, OF root, rotated] split: option.splits)
+ then have "(root, cast node_ptr) \<in> (parent_child_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ using assms(1) assms(2) assms(3) in_rtrancl_UnI local.get_root_node_parent_child_rel root
+ by blast
+ then show ?thesis
+ using \<open>root = cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r owner_document\<close> node_ptr by blast
+ next
+ case False
+ then obtain root_node where root_node: "root = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node"
+ using assms(2) \<open>root |\<in>| object_ptr_kinds h\<close>
+ by(auto simp add: known_ptr_impl ShadowRootClass.known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ dest!: known_ptrs_known_ptr split: option.splits)
+ have "h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node () \<rightarrow>\<^sub>r owner_document"
+ using \<open>h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document\<close> root False
+ apply(auto simp add: root_node CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ dest!: bind_returns_result_E3[rotated, OF root, rotated] split: option.splits
+ intro!: bind_pure_returns_result_I filter_M_pure_I bind_pure_I)[1]
+ by (simp add: assms(1) assms(2) assms(3) local.get_root_node_no_parent local.get_root_node_same_no_parent)
+ then
+ have "h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document"
+ using \<open>known_ptr root\<close>
+ apply(auto simp add: get_owner_document_def CD.a_get_owner_document_tups_def
+ a_get_owner_document_tups_def known_ptr_impl)[1]
+ apply(split invoke_splits, ((rule conjI | rule impI)+)?)+
+ apply(drule(1) known_ptr_not_shadow_root_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_document_ptr)
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ using \<open>h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document\<close> root
+ False \<open>root |\<in>| object_ptr_kinds h\<close>
+ apply(auto intro!: bind_pure_returns_result_I split: option.splits)[1]
+ using \<open>h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document\<close> root
+ False \<open>root |\<in>| object_ptr_kinds h\<close>
+ apply(auto intro!: bind_pure_returns_result_I split: option.splits)[1]
+ using \<open>h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document\<close> root
+ False \<open>root |\<in>| object_ptr_kinds h\<close>
+ apply(auto simp add: root_node intro!: bind_pure_returns_result_I split: option.splits)[1]
+ using \<open>h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document\<close> root
+ False \<open>root |\<in>| object_ptr_kinds h\<close>
+ apply(auto simp add: root_node intro!: bind_pure_returns_result_I split: option.splits)[1]
+ done
+ have "\<not> (\<exists>parent\<in>fset (object_ptr_kinds h). root_node \<in> set |h \<turnstile> get_child_nodes parent|\<^sub>r)"
+ using root_node
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) local.child_parent_dual
+ local.get_child_nodes_ok local.get_root_node_same_no_parent local.known_ptrs_known_ptr
+ notin_fset option.distinct(1) returns_result_eq returns_result_select_result root)
+ have "root_node |\<in>| node_ptr_kinds h"
+ using assms(1) assms(2) assms(3) local.get_root_node_root_in_heap node_ptr_kinds_commutes root root_node
+ by blast
+ then have "\<exists>document_ptr\<in>fset (document_ptr_kinds h). root_node \<in> set |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ using \<open>\<not> (\<exists>parent\<in>fset (object_ptr_kinds h). root_node \<in> set |h \<turnstile> get_child_nodes parent|\<^sub>r)\<close> assms(1)
+ local.heap_is_wellformed_children_disc_nodes by blast
+ then obtain disc_nodes document_ptr where "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes"
+ and "root_node \<in> set disc_nodes"
+ by (meson assms(3) local.get_disconnected_nodes_ok notin_fset returns_result_select_result)
+ then have "document_ptr |\<in>| document_ptr_kinds h"
+ by (meson is_OK_returns_result_I local.get_disconnected_nodes_ptr_in_heap)
+ then have "document_ptr = owner_document"
+ by (metis \<open>h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes\<close>
+ \<open>h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document\<close> \<open>root_node \<in> set disc_nodes\<close> assms(1) assms(2)
+ assms(3) local.get_owner_document_disconnected_nodes returns_result_eq root_node)
+ then have "(cast owner_document, cast root_node) \<in> a_ptr_disconnected_node_rel h"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def)[1]
+ using \<open>h \<turnstile> local.CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document\<close> assms(1)
+ assms(2) assms(3) get_owner_document_owner_document_in_heap_node
+ by (metis (no_types, lifting) \<open>h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes\<close>
+ \<open>root_node \<in> set disc_nodes\<close> case_prodI mem_Collect_eq pair_imageI select_result_I2)
+ moreover have "(cast root_node, cast node_ptr) \<in>
+(parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ by (metis assms(1) assms(2) assms(3) in_rtrancl_UnI local.get_root_node_parent_child_rel
+ root root_node)
+ ultimately show ?thesis
+ by (metis (no_types, lifting) assms(1) assms(2) assms(3) in_rtrancl_UnI
+ local.get_root_node_parent_child_rel node_ptr r_into_rtrancl root root_node rtrancl_trans)
+ qed
+qed
+end
+
+interpretation i_get_owner_document_wf?: l_get_owner_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf get_disconnected_nodes get_disconnected_nodes_locs known_ptr get_child_nodes
+ get_child_nodes_locs DocumentClass.known_ptr get_parent get_parent_locs DocumentClass.type_wf
+ get_root_node get_root_node_locs CD.a_get_owner_document get_host get_host_locs get_owner_document
+ get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs heap_is_wellformed
+ parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_document get_disconnected_document_locs
+ known_ptrs get_ancestors get_ancestors_locs
+ by(auto simp add: l_get_owner_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def l_get_owner_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_get_owner_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+lemma get_owner_document_wf_is_l_get_owner_document_wf [instances]:
+ "l_get_owner_document_wf heap_is_wellformed type_wf known_ptr known_ptrs get_disconnected_nodes
+get_owner_document get_parent get_child_nodes"
+ apply(auto simp add: l_get_owner_document_wf_def l_get_owner_document_wf_axioms_def instances)[1]
+ using get_owner_document_disconnected_nodes apply fast
+ using in_disconnected_nodes_no_parent apply fast
+ using get_owner_document_owner_document_in_heap apply fast
+ using get_owner_document_ok apply fast
+ using get_owner_document_child_same apply (fast, fast)
+ done
+
+paragraph \<open>get\_owner\_document\<close>
+
+locale l_get_owner_document_wf_get_root_node_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_owner_document\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_root_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_root_node_wf +
+ l_get_owner_document_wf +
+ assumes known_ptr_impl: "known_ptr = a_known_ptr"
+begin
+
+lemma get_root_node_document:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ assumes "is_document_ptr_kind root"
+ shows "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r the (cast root)"
+proof -
+ have "ptr |\<in>| object_ptr_kinds h"
+ using assms(4)
+ by (meson is_OK_returns_result_I local.get_root_node_ptr_in_heap)
+ then have "known_ptr ptr"
+ using assms(3) local.known_ptrs_known_ptr by blast
+ {
+ assume "is_document_ptr_kind ptr"
+ then have "ptr = root"
+ using assms(4)
+ by(auto simp add: get_root_node_def get_ancestors_def elim!: bind_returns_result_E2
+ split: option.splits)
+ then have ?thesis
+ using \<open>is_document_ptr_kind ptr\<close> \<open>known_ptr ptr\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close>
+ apply(auto simp add: known_ptr_impl get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ apply(drule(1) known_ptr_not_shadow_root_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_document_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ by(auto simp add: CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ intro!: bind_pure_returns_result_I split: option.splits)
+ }
+ moreover
+ {
+ assume "is_node_ptr_kind ptr"
+ then have ?thesis
+ using \<open>known_ptr ptr\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close>
+ apply(auto simp add: known_ptr_impl get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ apply(drule(1) known_ptr_not_shadow_root_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_document_ptr[folded known_ptr_impl])
+ apply(drule(1) known_ptr_not_character_data_ptr)
+ apply(drule(1) known_ptr_not_element_ptr)
+ apply(simp add: NodeClass.known_ptr_defs)
+ apply(auto split: option.splits)[1]
+ using \<open>h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root\<close> assms(5)
+ by(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def is_document_ptr_kind_def
+ intro!: bind_pure_returns_result_I split: option.splits)
+ }
+ ultimately
+ show ?thesis
+ using \<open>known_ptr ptr\<close>
+ by(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ split: option.splits)
+qed
+
+lemma get_root_node_same_owner_document:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_root_node ptr \<rightarrow>\<^sub>r root"
+ shows "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document \<longleftrightarrow> h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document"
+proof -
+ have "ptr |\<in>| object_ptr_kinds h"
+ by (meson assms(4) is_OK_returns_result_I local.get_root_node_ptr_in_heap)
+ have "root |\<in>| object_ptr_kinds h"
+ using assms(1) assms(2) assms(3) assms(4) local.get_root_node_root_in_heap by blast
+ have "known_ptr ptr"
+ using \<open>ptr |\<in>| object_ptr_kinds h\<close> assms(3) local.known_ptrs_known_ptr by blast
+ have "known_ptr root"
+ using \<open>root |\<in>| object_ptr_kinds h\<close> assms(3) local.known_ptrs_known_ptr by blast
+ show ?thesis
+ proof (cases "is_document_ptr_kind ptr")
+ case True
+ then
+ have "ptr = root"
+ using assms(4)
+ apply(auto simp add: get_root_node_def elim!: bind_returns_result_E2)[1]
+ by (metis document_ptr_casts_commute3 last_ConsL local.get_ancestors_not_node node_ptr_no_document_ptr_cast)
+ then show ?thesis
+ by auto
+ next
+ case False
+ then have "is_node_ptr_kind ptr"
+ using \<open>known_ptr ptr\<close>
+ by(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ split: option.splits)
+ then obtain node_ptr where node_ptr: "ptr = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr"
+ by (metis node_ptr_casts_commute3)
+ show ?thesis
+ proof
+ assume "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ then have "h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document"
+ using node_ptr
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits)+
+ apply (meson invoke_empty is_OK_returns_result_I)
+ by(auto elim!: bind_returns_result_E2 split: option.splits)
+
+ show "h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document"
+ proof (cases "is_document_ptr_kind root")
+ case True
+ then show ?thesis
+ proof (cases "is_shadow_root_ptr root")
+ case True
+ then
+ have "is_shadow_root_ptr root"
+ using True \<open>known_ptr root\<close>
+ by(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ split: option.splits)
+ have "root = cast owner_document"
+ using \<open>is_document_ptr_kind root\<close>
+ by (smt \<open>h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document\<close> assms(1) assms(2) assms(3) assms(4)
+ document_ptr_casts_commute3 get_root_node_document returns_result_eq)
+ then show ?thesis
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ using \<open>is_shadow_root_ptr root\<close> apply blast
+ using \<open>root |\<in>| object_ptr_kinds h\<close>
+ apply(simp add: a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ is_node_ptr_kind_none)
+ apply (metis \<open>h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document\<close> assms(1) assms(2) assms(3)
+ case_optionE document_ptr_kinds_def is_shadow_root_ptr_kind_none l_get_owner_document_wf.get_owner_document_owner_document_in_heap local.l_get_owner_document_wf_axioms not_None_eq return_bind shadow_root_ptr_casts_commute3 shadow_root_ptr_kinds_commutes shadow_root_ptr_kinds_def)
+ using \<open>root |\<in>| object_ptr_kinds h\<close> document_ptr_kinds_commutes
+ apply(auto simp add: a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ is_node_ptr_kind_none intro!: bind_pure_returns_result_I)[1]
+ using \<open>root |\<in>| object_ptr_kinds h\<close> document_ptr_kinds_commutes
+ apply(auto simp add: a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ is_node_ptr_kind_none intro!: bind_pure_returns_result_I)[1]
+ using \<open>root |\<in>| object_ptr_kinds h\<close> document_ptr_kinds_commutes
+ apply(auto simp add: a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ is_node_ptr_kind_none intro!: bind_pure_returns_result_I)[1]
+ done
+ next
+ case False
+ then
+ have "is_document_ptr root"
+ using True \<open>known_ptr root\<close>
+ by(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+ have "root = cast owner_document"
+ using True
+ by (smt \<open>h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document\<close> assms(1) assms(2) assms(3) assms(4)
+ document_ptr_casts_commute3 get_root_node_document returns_result_eq)
+ then show ?thesis
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ using \<open>is_document_ptr\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root\<close> apply blast
+ using \<open>root |\<in>| object_ptr_kinds h\<close>
+ apply(auto simp add: a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ is_node_ptr_kind_none)[1]
+ apply (metis \<open>h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document\<close> assms(1) assms(2) assms(3)
+ case_optionE document_ptr_kinds_def is_shadow_root_ptr_kind_none
+ l_get_owner_document_wf.get_owner_document_owner_document_in_heap local.l_get_owner_document_wf_axioms
+ not_None_eq return_bind shadow_root_ptr_casts_commute3 shadow_root_ptr_kinds_commutes shadow_root_ptr_kinds_def)
+ using \<open>root |\<in>| object_ptr_kinds h\<close> document_ptr_kinds_commutes
+ apply(auto simp add: a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ is_node_ptr_kind_none intro!: bind_pure_returns_result_I)[1]
+ using \<open>root |\<in>| object_ptr_kinds h\<close> document_ptr_kinds_commutes
+ apply(auto simp add: a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ is_node_ptr_kind_none intro!: bind_pure_returns_result_I)[1]
+ using \<open>root |\<in>| object_ptr_kinds h\<close> document_ptr_kinds_commutes
+ apply(auto simp add: a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ is_node_ptr_kind_none intro!: bind_pure_returns_result_I)[1]
+ done
+ qed
+ next
+ case False
+ then have "is_node_ptr_kind root"
+ using \<open>known_ptr root\<close>
+ by(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ split: option.splits)
+ then obtain root_node_ptr where root_node_ptr: "root = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node_ptr"
+ by (metis node_ptr_casts_commute3)
+ then have "h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node_ptr () \<rightarrow>\<^sub>r owner_document"
+ using \<open>h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document\<close> assms(4)
+ apply(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ intro!: bind_pure_returns_result_I filter_M_pure_I bind_pure_I split: option.splits)[1]
+ apply (metis assms(1) assms(2) assms(3) local.get_root_node_no_parent
+ local.get_root_node_same_no_parent node_ptr returns_result_eq)
+ using \<open>is_node_ptr_kind root\<close> node_ptr returns_result_eq by fastforce
+ then show ?thesis
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ using \<open>is_node_ptr_kind root\<close> \<open>known_ptr root\<close>
+ apply(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ split: option.splits)[1]
+ using \<open>is_node_ptr_kind root\<close> \<open>known_ptr root\<close>
+ apply(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ split: option.splits)[1]
+ using \<open>is_node_ptr_kind root\<close> \<open>known_ptr root\<close>
+ apply(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ split: option.splits)[1]
+ using \<open>root |\<in>| object_ptr_kinds h\<close>
+ by(auto simp add: root_node_ptr)
+ qed
+ next
+ assume "h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document"
+ show "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ proof (cases "is_document_ptr_kind root")
+ case True
+ have "root = cast owner_document"
+ using \<open>h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits)+
+ apply (meson invoke_empty is_OK_returns_result_I)
+ apply(auto simp add: True CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2 split: if_splits option.splits)[1]
+ apply(auto simp add: True CD.a_get_owner_document\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ a_get_owner_document\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2 split: if_splits option.splits)[1]
+ apply (metis True cast_document_ptr_not_node_ptr(2) is_document_ptr_kind_obtains
+ is_node_ptr_kind_none node_ptr_casts_commute3 option.case_eq_if)
+ by (metis True cast_document_ptr_not_node_ptr(1) document_ptr_casts_commute3
+ is_node_ptr_kind_none node_ptr_casts_commute3 option.case_eq_if)
+ then show ?thesis
+ using assms(1) assms(2) assms(3) assms(4) get_root_node_document
+ by fastforce
+ next
+ case False
+ then have "is_node_ptr_kind root"
+ using \<open>known_ptr root\<close>
+ by(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs split: option.splits)
+ then obtain root_node_ptr where root_node_ptr: "root = cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node_ptr"
+ by (metis node_ptr_casts_commute3)
+ then have "h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r root_node_ptr () \<rightarrow>\<^sub>r owner_document"
+ using \<open>h \<turnstile> get_owner_document root \<rightarrow>\<^sub>r owner_document\<close>
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits)+
+ apply (meson invoke_empty is_OK_returns_result_I)
+ by(auto simp add: is_document_ptr_kind_none elim!: bind_returns_result_E2)
+ then have "h \<turnstile> CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r node_ptr () \<rightarrow>\<^sub>r owner_document"
+ apply(auto simp add: CD.a_get_owner_document\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def elim!: bind_returns_result_E2
+ intro!: bind_pure_returns_result_I filter_M_pure_I bind_pure_I split: option.splits)[1]
+ using assms(1) assms(2) assms(3) assms(4) local.get_root_node_no_parent
+ local.get_root_node_same_no_parent node_ptr returns_result_eq root_node_ptr
+ by fastforce+
+ then show ?thesis
+ apply(auto simp add: get_owner_document_def a_get_owner_document_tups_def
+ CD.a_get_owner_document_tups_def)[1]
+ apply(split invoke_splits, (rule conjI | rule impI)+)+
+ using node_ptr \<open>known_ptr ptr\<close> \<open>ptr |\<in>| object_ptr_kinds h\<close>
+
+ by(auto simp add: known_ptr_impl known_ptr_defs DocumentClass.known_ptr_defs
+ CharacterDataClass.known_ptr_defs ElementClass.known_ptr_defs NodeClass.known_ptr_defs
+ intro!: bind_pure_returns_result_I split: option.splits)
+ qed
+ qed
+ qed
+qed
+end
+
+interpretation i_get_owner_document_wf_get_root_node_wf?: l_get_owner_document_wf_get_root_node_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ DocumentClass.known_ptr get_parent get_parent_locs DocumentClass.type_wf get_disconnected_nodes
+ get_disconnected_nodes_locs get_root_node get_root_node_locs CD.a_get_owner_document
+ get_host get_host_locs get_owner_document get_child_nodes get_child_nodes_locs type_wf known_ptr
+ known_ptrs get_ancestors get_ancestors_locs heap_is_wellformed parent_child_rel
+ by(auto simp add: l_get_owner_document_wf_get_root_node_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def
+ l_get_owner_document_wf_get_root_node_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms_def instances)
+declare l_get_owner_document_wf_get_root_node_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma get_owner_document_wf_get_root_node_wf_is_l_get_owner_document_wf_get_root_node_wf [instances]:
+ "l_get_owner_document_wf_get_root_node_wf heap_is_wellformed type_wf known_ptr known_ptrs get_root_node get_owner_document"
+ apply(auto simp add: l_get_owner_document_wf_get_root_node_wf_def l_get_owner_document_wf_get_root_node_wf_axioms_def instances)[1]
+ using get_root_node_document apply blast
+ using get_root_node_same_owner_document apply (blast, blast)
+ done
+
+
+subsubsection \<open>remove\_child\<close>
+
+locale l_remove_child_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_set_disconnected_nodes_get_disconnected_nodes +
+ l_get_child_nodes +
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_owner_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_set_child_nodes_get_shadow_root +
+ l_set_disconnected_nodes_get_shadow_root +
+ l_set_child_nodes_get_tag_name +
+ l_set_disconnected_nodes_get_tag_name +
+ CD: l_remove_child_wf2\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma remove_child_preserves_type_wf:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h'"
+ shows "type_wf h'"
+ using CD.remove_child_heap_is_wellformed_preserved(1) assms
+ unfolding heap_is_wellformed_def
+ by auto
+
+lemma remove_child_preserves_known_ptrs:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h'"
+ shows "known_ptrs h'"
+ using CD.remove_child_heap_is_wellformed_preserved(2) assms
+ unfolding heap_is_wellformed_def
+ by auto
+
+
+lemma remove_child_heap_is_wellformed_preserved:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> remove_child ptr child \<rightarrow>\<^sub>h h'"
+ shows "heap_is_wellformed h'"
+proof -
+ obtain owner_document children_h h2 disconnected_nodes_h where
+ owner_document: "h \<turnstile> get_owner_document (cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r child) \<rightarrow>\<^sub>r owner_document" and
+ children_h: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children_h" and
+ child_in_children_h: "child \<in> set children_h" and
+ disconnected_nodes_h: "h \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disconnected_nodes_h" and
+ h2: "h \<turnstile> set_disconnected_nodes owner_document (child # disconnected_nodes_h) \<rightarrow>\<^sub>h h2" and
+ h': "h2 \<turnstile> set_child_nodes ptr (remove1 child children_h) \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ apply(auto simp add: remove_child_def elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_child_nodes_pure] split: if_splits)[1]
+ using pure_returns_heap_eq by fastforce
+
+ have "heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M h'"
+ using CD.remove_child_heap_is_wellformed_preserved(3) assms
+ unfolding heap_is_wellformed_def
+ by auto
+
+ have "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document"
+ using owner_document children_h child_in_children_h
+ using local.get_owner_document_child_same assms by blast
+
+ have shadow_root_eq: "\<And>ptr' shadow_root_ptr_opt. h \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt =
+h' \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt"
+ using get_shadow_root_reads remove_child_writes assms(4)
+ apply(rule reads_writes_preserved)
+ by(auto simp add: remove_child_locs_def set_child_nodes_get_shadow_root
+ set_disconnected_nodes_get_shadow_root)
+ then
+ have shadow_root_eq2: "\<And>ptr'. |h \<turnstile> get_shadow_root ptr'|\<^sub>r = |h' \<turnstile> get_shadow_root ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have tag_name_eq: "\<And>ptr' tag. h \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r tag = h' \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r tag"
+ using get_tag_name_reads remove_child_writes assms(4)
+ apply(rule reads_writes_preserved)
+ by(auto simp add: remove_child_locs_def set_child_nodes_get_tag_name
+ set_disconnected_nodes_get_tag_name)
+ then
+ have tag_name_eq2: "\<And>ptr'. |h \<turnstile> get_tag_name ptr'|\<^sub>r = |h' \<turnstile> get_tag_name ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have object_ptr_kinds_eq: "object_ptr_kinds h = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF remove_child_writes assms(4)])
+ unfolding remove_child_locs_def
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+
+ have document_ptr_kinds_eq: "document_ptr_kinds h = document_ptr_kinds h'"
+ using object_ptr_kinds_eq
+ by(auto simp add: document_ptr_kinds_def document_ptr_kinds_def)
+
+ have shadow_root_ptr_kinds_eq: "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
+ using object_ptr_kinds_eq
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ have element_ptr_kinds_eq: "element_ptr_kinds h = element_ptr_kinds h'"
+ using object_ptr_kinds_eq
+ by(auto simp add: element_ptr_kinds_def node_ptr_kinds_def)
+
+ have "parent_child_rel h' \<subseteq> parent_child_rel h"
+ using \<open>heap_is_wellformed h\<close> heap_is_wellformed_def
+ using CD.remove_child_parent_child_rel_subset
+ using \<open>known_ptrs h\<close> \<open>type_wf h\<close> assms(4)
+ by simp
+
+ have "known_ptr ptr"
+ using assms(3)
+ using children_h get_child_nodes_ptr_in_heap local.known_ptrs_known_ptr by blast
+ have "type_wf h2"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'",
+ OF set_disconnected_nodes_writes h2]
+ using set_disconnected_nodes_types_preserved \<open>type_wf h\<close>
+ by(auto simp add: reflp_def transp_def)
+
+ have children_eq:
+ "\<And>ptr' children. ptr \<noteq> ptr' \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children =
+h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ apply(rule reads_writes_preserved[OF get_child_nodes_reads remove_child_writes assms(4)])
+ unfolding remove_child_locs_def
+ using set_disconnected_nodes_get_child_nodes set_child_nodes_get_child_nodes_different_pointers
+ by fast
+ then have children_eq2:
+ "\<And>ptr' children. ptr \<noteq> ptr' \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children_h"
+ apply(rule reads_writes_separate_forwards[OF get_child_nodes_reads
+ set_disconnected_nodes_writes h2 children_h] )
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+
+ have children_h': "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r remove1 child children_h"
+ using assms(4) owner_document h2 disconnected_nodes_h children_h
+ apply(auto simp add: remove_child_def split: if_splits)[1]
+ apply(drule bind_returns_heap_E3)
+ apply(auto split: if_splits)[1]
+ apply(simp)
+ apply(auto split: if_splits)[1]
+ apply(drule bind_returns_heap_E3)
+ apply(auto)[1]
+ apply(simp)
+ apply(drule bind_returns_heap_E3)
+ apply(auto)[1]
+ apply(simp)
+ apply(drule bind_returns_heap_E4)
+ apply(auto)[1]
+ apply simp
+ using \<open>type_wf h2\<close> set_child_nodes_get_child_nodes \<open>known_ptr ptr\<close> h'
+ by blast
+
+ have disconnected_nodes_eq: "\<And>ptr' disc_nodes. ptr' \<noteq> owner_document \<Longrightarrow>
+h \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes = h2 \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using local.get_disconnected_nodes_reads set_disconnected_nodes_writes h2
+ apply(rule reads_writes_preserved)
+ by (metis local.set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then
+ have disconnected_nodes_eq2: "\<And>ptr'. ptr' \<noteq> owner_document \<Longrightarrow>
+|h \<turnstile> get_disconnected_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes ptr'|\<^sub>r"
+ by (meson select_result_eq)
+ have "h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r child # disconnected_nodes_h"
+ using h2 local.set_disconnected_nodes_get_disconnected_nodes
+ by blast
+
+ have disconnected_nodes_eq_h2:
+ "\<And>ptr' disc_nodes. h2 \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes = h' \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using local.get_disconnected_nodes_reads set_child_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ using local.set_child_nodes_get_disconnected_nodes by blast
+ then
+ have disconnected_nodes_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_disconnected_nodes ptr'|\<^sub>r = |h' \<turnstile> get_disconnected_nodes ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have "a_host_shadow_root_rel h' = a_host_shadow_root_rel h"
+ by(auto simp add: a_host_shadow_root_rel_def shadow_root_eq2 element_ptr_kinds_eq)
+ moreover
+ have "(ptr, cast child) \<in> parent_child_rel h"
+ using child_in_children_h children_h local.CD.parent_child_rel_child by blast
+ moreover
+ have "a_ptr_disconnected_node_rel h' = insert (cast owner_document, cast child) (a_ptr_disconnected_node_rel h)"
+ using \<open>h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r child # disconnected_nodes_h\<close> disconnected_nodes_eq2 disconnected_nodes_h
+ apply(auto simp add: a_ptr_disconnected_node_rel_def disconnected_nodes_eq2_h2[symmetric] document_ptr_kinds_eq[symmetric])[1]
+ apply(case_tac "aa = owner_document")
+ apply(auto)[1]
+ apply(auto)[1]
+ apply (metis (no_types, lifting) assms(4) case_prodI disconnected_nodes_eq_h2 h2
+ is_OK_returns_heap_I local.remove_child_in_disconnected_nodes
+ local.set_disconnected_nodes_ptr_in_heap mem_Collect_eq owner_document pair_imageI select_result_I2)
+ by (metis (no_types, lifting) case_prodI list.set_intros(2) mem_Collect_eq pair_imageI select_result_I2)
+ then
+ have "a_ptr_disconnected_node_rel h' = a_ptr_disconnected_node_rel h \<union> {(cast owner_document, cast child)}"
+ by auto
+ moreover have "acyclic (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)"
+ using assms(1) local.heap_is_wellformed_def by blast
+ moreover have "parent_child_rel h' = parent_child_rel h - {(ptr, cast child)}"
+ apply(auto simp add: CD.parent_child_rel_def object_ptr_kinds_eq children_eq2)[1]
+ apply (metis (no_types, lifting) children_eq2 children_h children_h' notin_set_remove1 select_result_I2)
+ using \<open>h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r child # disconnected_nodes_h\<close>
+ \<open>heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M h'\<close> disconnected_nodes_eq_h2 local.CD.distinct_lists_no_parent
+ local.CD.heap_is_wellformed_def apply auto[1]
+ by (metis (no_types, lifting) children_eq2 children_h children_h' in_set_remove1 select_result_I2)
+
+ moreover have "(cast owner_document, ptr) \<in> (parent_child_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ using \<open>h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document\<close> get_owner_document_rel
+ using assms(1) assms(2) assms(3) by blast
+ then have "(cast owner_document, ptr) \<in> (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ by (metis (no_types, lifting) in_rtrancl_UnI inf_sup_aci(5) inf_sup_aci(7))
+ ultimately
+ have "acyclic (parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h')"
+ by (smt Un_assoc Un_insert_left Un_insert_right acyclic_insert insert_Diff_single
+ insert_absorb2 mk_disjoint_insert prod.inject rtrancl_Un_separator_converseE rtrancl_trans
+ singletonD sup_bot.comm_neutral)
+
+ show ?thesis
+ using \<open>heap_is_wellformed h\<close>
+ using \<open>heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M h'\<close>
+ using \<open>acyclic (parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h')\<close>
+ apply(auto simp add: heap_is_wellformed_def CD.heap_is_wellformed_def CD.acyclic_heap_def
+ host_shadow_root_rel_def a_all_ptrs_in_heap_def a_distinct_lists_def a_shadow_root_valid_def)[1]
+ by(auto simp add: object_ptr_kinds_eq element_ptr_kinds_eq shadow_root_ptr_kinds_eq
+ shadow_root_eq shadow_root_eq2 tag_name_eq tag_name_eq2)
+qed
+
+lemma remove_preserves_type_wf:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> remove child \<rightarrow>\<^sub>h h'"
+ shows "type_wf h'"
+ using CD.remove_heap_is_wellformed_preserved(1) assms
+ unfolding heap_is_wellformed_def
+ by auto
+
+lemma remove_preserves_known_ptrs:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> remove child \<rightarrow>\<^sub>h h'"
+ shows "known_ptrs h'"
+ using CD.remove_heap_is_wellformed_preserved(2) assms
+ unfolding heap_is_wellformed_def
+ by auto
+
+
+lemma remove_heap_is_wellformed_preserved:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> remove child \<rightarrow>\<^sub>h h'"
+ shows "heap_is_wellformed h'"
+ using assms
+ by(auto simp add: remove_def elim!: bind_returns_heap_E2
+ intro: remove_child_heap_is_wellformed_preserved split: option.splits)
+
+lemma remove_child_removes_child:
+ "heap_is_wellformed h \<Longrightarrow> h \<turnstile> remove_child ptr' child \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children
+ \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h
+ \<Longrightarrow> child \<notin> set children"
+ using CD.remove_child_removes_child local.heap_is_wellformed_def by blast
+lemma remove_child_removes_first_child:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r node_ptr # children \<Longrightarrow>
+h \<turnstile> remove_child ptr node_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using CD.remove_child_removes_first_child local.heap_is_wellformed_def by blast
+lemma remove_removes_child:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r node_ptr # children \<Longrightarrow>
+h \<turnstile> remove node_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using CD.remove_removes_child local.heap_is_wellformed_def by blast
+lemma remove_for_all_empty_children:
+ "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow>
+h \<turnstile> forall_M remove children \<rightarrow>\<^sub>h h' \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r []"
+ using CD.remove_for_all_empty_children local.heap_is_wellformed_def by blast
+
+end
+
+interpretation i_remove_child_wf2?: l_remove_child_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs known_ptr get_child_nodes get_child_nodes_locs get_shadow_root
+ get_shadow_root_locs get_tag_name get_tag_name_locs heap_is_wellformed parent_child_rel
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document get_disconnected_document_locs
+ DocumentClass.known_ptr get_parent get_parent_locs DocumentClass.type_wf get_root_node get_root_node_locs
+ CD.a_get_owner_document get_owner_document known_ptrs get_ancestors get_ancestors_locs set_child_nodes
+ set_child_nodes_locs remove_child remove_child_locs remove
+ by(auto simp add: l_remove_child_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_remove_child_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+lemma remove_child_wf2_is_l_remove_child_wf2 [instances]:
+ "l_remove_child_wf2 type_wf known_ptr known_ptrs remove_child heap_is_wellformed get_child_nodes remove"
+ apply(auto simp add: l_remove_child_wf2_def l_remove_child_wf2_axioms_def instances)[1]
+ using remove_child_preserves_type_wf apply fast
+ using remove_child_preserves_known_ptrs apply fast
+ using remove_child_heap_is_wellformed_preserved apply (fast)
+ using remove_preserves_type_wf apply fast
+ using remove_preserves_known_ptrs apply fast
+ using remove_heap_is_wellformed_preserved apply (fast)
+ using remove_child_removes_child apply fast
+ using remove_child_removes_first_child apply fast
+ using remove_removes_child apply fast
+ using remove_for_all_empty_children apply fast
+ done
+
+
+
+subsubsection \<open>adopt\_node\<close>
+
+locale l_adopt_node_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ CD: l_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M _ _ _ _ _ _ _ _ _ adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma adopt_node_removes_first_child: "heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r node # children
+ \<Longrightarrow> h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ by (smt CD.adopt_node_removes_first_child bind_returns_heap_E error_returns_heap
+ l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M.adopt_node_def local.CD.adopt_node_impl local.get_ancestors_di_pure
+ local.l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms pure_returns_heap_eq)
+lemma adopt_node_document_in_heap: "heap_is_wellformed h \<Longrightarrow> known_ptrs h \<Longrightarrow> type_wf h
+ \<Longrightarrow> h \<turnstile> ok (adopt_node owner_document node)
+ \<Longrightarrow> owner_document |\<in>| document_ptr_kinds h"
+ by (metis (no_types, lifting) bind_returns_heap_E document_ptr_kinds_commutes is_OK_returns_heap_E
+ is_OK_returns_result_I local.adopt_node_def local.get_ancestors_di_ptr_in_heap)
+end
+
+locale l_adopt_node_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes +
+ l_get_disconnected_nodes +
+ l_set_child_nodes_get_shadow_root +
+ l_set_disconnected_nodes_get_shadow_root +
+ l_set_child_nodes_get_tag_name +
+ l_set_disconnected_nodes_get_tag_name +
+ l_get_owner_document +
+ l_remove_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M+
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_root_node +
+ l_set_disconnected_nodes_get_child_nodes +
+ l_get_owner_document_wf +
+ l_remove_child_wf2 +
+ l_adopt_node_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_parent_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_disconnected_document +
+ l_get_ancestors_di\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_get_ancestors_di_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma adopt_node_removes_child:
+ assumes wellformed: "heap_is_wellformed h"
+ and adopt_node: "h \<turnstile> adopt_node owner_document node_ptr \<rightarrow>\<^sub>h h2"
+ and children: "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "node_ptr \<notin> set children"
+proof -
+ obtain old_document parent_opt h' where
+ old_document: "h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r old_document" and
+ parent_opt: "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r parent_opt" and
+ h': "h \<turnstile> (case parent_opt of Some parent \<Rightarrow> remove_child parent node_ptr | None \<Rightarrow> return () ) \<rightarrow>\<^sub>h h'"
+ using adopt_node
+ by(auto simp add: adopt_node_def CD.adopt_node_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_ancestors_di_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_owner_document_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ split: if_splits)
+
+ then have "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using adopt_node
+ apply(auto simp add: adopt_node_def CD.adopt_node_def
+ dest!: bind_returns_heap_E3[rotated, OF old_document, rotated]
+ bind_returns_heap_E3[rotated, OF parent_opt, rotated]
+ elim!: bind_returns_heap_E2[rotated, OF get_ancestors_di_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_owner_document_pure, rotated]
+ bind_returns_heap_E4[rotated, OF h', rotated] split: if_splits)[1]
+ apply(auto split: if_splits elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_ancestors_di_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated])[1]
+ apply (simp add: set_disconnected_nodes_get_child_nodes children
+ reads_writes_preserved[OF get_child_nodes_reads set_disconnected_nodes_writes])
+ using children by blast
+ show ?thesis
+ proof(insert parent_opt h', induct parent_opt)
+ case None
+ then show ?case
+ using child_parent_dual wellformed known_ptrs type_wf \<open>h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children\<close>
+ returns_result_eq by fastforce
+ next
+ case (Some option)
+ then show ?case
+ using remove_child_removes_child \<open>h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children\<close> known_ptrs type_wf wellformed
+ by auto
+ qed
+qed
+
+lemma adopt_node_preserves_wellformedness:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> adopt_node document_ptr child \<rightarrow>\<^sub>h h'"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "heap_is_wellformed h'"
+proof -
+ obtain old_document parent_opt h2 ancestors where
+ "h \<turnstile> get_ancestors_di (cast document_ptr) \<rightarrow>\<^sub>r ancestors" and
+ "cast child \<notin> set ancestors" and
+ old_document: "h \<turnstile> get_owner_document (cast child) \<rightarrow>\<^sub>r old_document" and
+ parent_opt: "h \<turnstile> get_parent child \<rightarrow>\<^sub>r parent_opt" and
+ h2: "h \<turnstile> (case parent_opt of Some parent \<Rightarrow> remove_child parent child | None \<Rightarrow> return ()) \<rightarrow>\<^sub>h h2" and
+ h': "h2 \<turnstile> (if document_ptr \<noteq> old_document then do {
+ old_disc_nodes \<leftarrow> get_disconnected_nodes old_document;
+ set_disconnected_nodes old_document (remove1 child old_disc_nodes);
+ disc_nodes \<leftarrow> get_disconnected_nodes document_ptr;
+ set_disconnected_nodes document_ptr (child # disc_nodes)
+ } else do {
+ return ()
+ }) \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ apply(auto simp add: adopt_node_def[unfolded CD.adopt_node_def] elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_ancestors_di_pure])[1]
+ apply(split if_splits)
+ by(auto simp add: elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_parent_pure])
+
+ have object_ptr_kinds_h_eq3: "object_ptr_kinds h = object_ptr_kinds h2"
+ using h2 apply(simp split: option.splits)
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'", OF remove_child_writes])
+ using remove_child_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h: "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ unfolding object_ptr_kinds_M_defs by simp
+ then have object_ptr_kinds_eq_h: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq_h: "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+
+ have wellformed_h2: "heap_is_wellformed h2"
+ using h2 remove_child_heap_is_wellformed_preserved known_ptrs type_wf
+ by (metis (no_types, lifting) assms(1) option.case_eq_if pure_returns_heap_eq return_pure)
+ then show "heap_is_wellformed h'"
+ proof(cases "document_ptr = old_document")
+ case True
+ then show "heap_is_wellformed h'"
+ using h' wellformed_h2 by auto
+ next
+ case False
+ then obtain h3 old_disc_nodes disc_nodes_document_ptr_h3 where
+ docs_neq: "document_ptr \<noteq> old_document" and
+ old_disc_nodes: "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r old_disc_nodes" and
+ h3: "h2 \<turnstile> set_disconnected_nodes old_document (remove1 child old_disc_nodes) \<rightarrow>\<^sub>h h3" and
+ disc_nodes_document_ptr_h3: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_document_ptr_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (child # disc_nodes_document_ptr_h3) \<rightarrow>\<^sub>h h'"
+ using h'
+ by(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+
+ have object_ptr_kinds_h2_eq3: "object_ptr_kinds h2 = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'", OF set_disconnected_nodes_writes h3])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h2: "\<And>ptrs. h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq_h2: "|h2 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+ then have node_ptr_kinds_eq_h2: "|h2 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ then have node_ptr_kinds_eq3_h2: "node_ptr_kinds h2 = node_ptr_kinds h3"
+ by auto
+ have document_ptr_kinds_eq2_h2: "|h2 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq_h2 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3_h2: "document_ptr_kinds h2 = document_ptr_kinds h3"
+ using object_ptr_kinds_eq_h2 document_ptr_kinds_M_eq by auto
+ have children_eq_h2: "\<And>ptr children. h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h2: "\<And>ptr. |h2 \<turnstile> get_child_nodes ptr|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have object_ptr_kinds_h3_eq3: "object_ptr_kinds h3 = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'", OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h3: "\<And>ptrs. h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq_h3: "|h3 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+ then have node_ptr_kinds_eq_h3: "|h3 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ then have node_ptr_kinds_eq3_h3: "node_ptr_kinds h3 = node_ptr_kinds h'"
+ by auto
+ have document_ptr_kinds_eq2_h3: "|h3 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h' \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq_h3 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3_h3: "document_ptr_kinds h3 = document_ptr_kinds h'"
+ using object_ptr_kinds_eq_h3 document_ptr_kinds_M_eq by auto
+ have children_eq_h3: "\<And>ptr children. h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h3: "\<And>ptr. |h3 \<turnstile> get_child_nodes ptr|\<^sub>r = |h' \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. old_document \<noteq> doc_ptr \<Longrightarrow>
+h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. old_document \<noteq> doc_ptr \<Longrightarrow>
+|h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ obtain disc_nodes_old_document_h2 where disc_nodes_old_document_h2:
+ "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disc_nodes_old_document_h2"
+ using old_disc_nodes by blast
+ then have disc_nodes_old_document_h3:
+ "h3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r remove1 child disc_nodes_old_document_h2"
+ using h3 old_disc_nodes returns_result_eq set_disconnected_nodes_get_disconnected_nodes
+ by fastforce
+ have "distinct disc_nodes_old_document_h2"
+ using disc_nodes_old_document_h2 local.heap_is_wellformed_disconnected_nodes_distinct wellformed_h2
+ by blast
+
+
+ have "type_wf h2"
+ proof (insert h2, induct parent_opt)
+ case None
+ then show ?case
+ using type_wf by simp
+ next
+ case (Some option)
+ then show ?case
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF remove_child_writes]
+ type_wf remove_child_types_preserved
+ by (simp add: reflp_def transp_def)
+ qed
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h3]
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then have "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have disconnected_nodes_eq_h3:
+ "\<And>doc_ptr disc_nodes. document_ptr \<noteq> doc_ptr \<Longrightarrow>
+h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h3:
+ "\<And>doc_ptr. document_ptr \<noteq> doc_ptr \<Longrightarrow>
+|h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have disc_nodes_document_ptr_h2:
+ "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_document_ptr_h3"
+ using disconnected_nodes_eq_h2 docs_neq disc_nodes_document_ptr_h3 by auto
+ have disc_nodes_document_ptr_h':
+ "h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r child # disc_nodes_document_ptr_h3"
+ using h' disc_nodes_document_ptr_h3
+ using set_disconnected_nodes_get_disconnected_nodes by blast
+
+ have document_ptr_in_heap: "document_ptr |\<in>| document_ptr_kinds h2"
+ using disc_nodes_document_ptr_h3 document_ptr_kinds_eq2_h2 get_disconnected_nodes_ok assms(1)
+ unfolding heap_is_wellformed_def
+ using disc_nodes_document_ptr_h2 get_disconnected_nodes_ptr_in_heap by blast
+ have old_document_in_heap: "old_document |\<in>| document_ptr_kinds h2"
+ using disc_nodes_old_document_h3 document_ptr_kinds_eq2_h2 get_disconnected_nodes_ok assms(1)
+ unfolding heap_is_wellformed_def
+ using get_disconnected_nodes_ptr_in_heap old_disc_nodes by blast
+
+ have "child \<in> set disc_nodes_old_document_h2"
+ proof (insert parent_opt h2, induct parent_opt)
+ case None
+ then have "h = h2"
+ by(auto)
+ moreover have "CD.a_owner_document_valid h"
+ using assms(1) by(simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ ultimately show ?case
+ using old_document disc_nodes_old_document_h2 None(1) child_parent_dual[OF assms(1)]
+ in_disconnected_nodes_no_parent assms(1) known_ptrs type_wf by blast
+ next
+ case (Some option)
+ then show ?case
+ apply(simp split: option.splits)
+ using assms(1) disc_nodes_old_document_h2 old_document remove_child_in_disconnected_nodes known_ptrs
+ by blast
+ qed
+ have "child \<notin> set (remove1 child disc_nodes_old_document_h2)"
+ using disc_nodes_old_document_h3 h3 known_ptrs wellformed_h2 \<open>distinct disc_nodes_old_document_h2\<close>
+ by auto
+ have "child \<notin> set disc_nodes_document_ptr_h3"
+ proof -
+ have "CD.a_distinct_lists h2"
+ using heap_is_wellformed_def CD.heap_is_wellformed_def wellformed_h2 by blast
+ then have 0: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+|h2 \<turnstile> document_ptr_kinds_M|\<^sub>r))"
+ by(simp add: CD.a_distinct_lists_def)
+ show ?thesis
+ using distinct_concat_map_E(1)[OF 0] \<open>child \<in> set disc_nodes_old_document_h2\<close>
+ disc_nodes_old_document_h2 disc_nodes_document_ptr_h2
+ by (meson \<open>type_wf h2\<close> docs_neq known_ptrs local.get_owner_document_disconnected_nodes
+ local.known_ptrs_preserved object_ptr_kinds_h_eq3 returns_result_eq wellformed_h2)
+ qed
+
+ have child_in_heap: "child |\<in>| node_ptr_kinds h"
+ using get_owner_document_ptr_in_heap[OF is_OK_returns_result_I[OF old_document]] node_ptr_kinds_commutes
+ by blast
+ have "CD.a_acyclic_heap h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ have "parent_child_rel h' \<subseteq> parent_child_rel h2"
+ proof
+ fix x
+ assume "x \<in> parent_child_rel h'"
+ then show "x \<in> parent_child_rel h2"
+ using object_ptr_kinds_h2_eq3 object_ptr_kinds_h3_eq3 children_eq2_h2 children_eq2_h3
+ mem_Collect_eq object_ptr_kinds_M_eq_h3 select_result_eq split_cong
+ unfolding CD.parent_child_rel_def
+ by(simp)
+ qed
+ then have " CD.a_acyclic_heap h'"
+ using \<open> CD.a_acyclic_heap h2\<close> CD.acyclic_heap_def acyclic_subset by blast
+
+ moreover have " CD.a_all_ptrs_in_heap h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_all_ptrs_in_heap h3"
+ apply(auto simp add: CD.a_all_ptrs_in_heap_def node_ptr_kinds_eq3_h2 children_eq_h2)[1]
+ apply (metis CD.l_heap_is_wellformed_axioms \<open>type_wf h2\<close> children_eq2_h2 known_ptrs
+ l_heap_is_wellformed.heap_is_wellformed_children_in_heap local.get_child_nodes_ok
+ local.known_ptrs_known_ptr node_ptr_kinds_eq3_h2 object_ptr_kinds_h2_eq3 object_ptr_kinds_h_eq3
+ returns_result_select_result wellformed_h2)
+ by (metis (no_types, lifting) disc_nodes_old_document_h2 disc_nodes_old_document_h3
+ disconnected_nodes_eq2_h2 document_ptr_kinds_eq3_h2 finite_set_in select_result_I2 set_remove1_subset
+ subsetD)
+ then have "CD.a_all_ptrs_in_heap h'"
+ by (smt \<open>child \<in> set disc_nodes_old_document_h2\<close> children_eq2_h3 disc_nodes_document_ptr_h'
+ disc_nodes_document_ptr_h2 disc_nodes_old_document_h2 disconnected_nodes_eq2_h3 document_ptr_kinds_eq3_h3
+ finite_set_in local.CD.a_all_ptrs_in_heap_def local.heap_is_wellformed_disc_nodes_in_heap
+ node_ptr_kinds_eq3_h2 node_ptr_kinds_eq3_h3 object_ptr_kinds_h3_eq3 select_result_I2 set_ConsD
+ subset_code(1) wellformed_h2)
+
+ moreover have "CD.a_owner_document_valid h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_owner_document_valid h'"
+ apply(simp add: CD.a_owner_document_valid_def node_ptr_kinds_eq_h2 node_ptr_kinds_eq3_h3
+ object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3
+ children_eq2_h2 children_eq2_h3 )
+ by (metis (no_types) disc_nodes_document_ptr_h' disc_nodes_document_ptr_h2
+ disc_nodes_old_document_h2 disc_nodes_old_document_h3 disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3 document_ptr_in_heap document_ptr_kinds_eq3_h2 document_ptr_kinds_eq3_h3
+ in_set_remove1 list.set_intros(1) list.set_intros(2) node_ptr_kinds_eq3_h2 node_ptr_kinds_eq3_h3
+ object_ptr_kinds_h2_eq3 object_ptr_kinds_h3_eq3 select_result_I2)
+
+ have a_distinct_lists_h2: "CD.a_distinct_lists h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_distinct_lists h'"
+ apply(auto simp add: CD.a_distinct_lists_def object_ptr_kinds_eq_h3 object_ptr_kinds_eq_h2
+ children_eq2_h2 children_eq2_h3)[1]
+ proof -
+ assume 1: "distinct (concat (map (\<lambda>ptr. |h' \<turnstile> get_child_nodes ptr|\<^sub>r) (sorted_list_of_set
+(fset (object_ptr_kinds h')))))"
+ and 2: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+(sorted_list_of_set (fset (document_ptr_kinds h2)))))"
+ and 3: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r) \<inter>
+(\<Union>x\<in>fset (document_ptr_kinds h2). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ show "distinct (concat (map (\<lambda>document_ptr. |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+(sorted_list_of_set (fset (document_ptr_kinds h')))))"
+ proof(rule distinct_concat_map_I)
+ show "distinct (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ by(auto simp add: document_ptr_kinds_M_def )
+ next
+ fix x
+ assume a1: "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ have 4: "distinct |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using a_distinct_lists_h2 "2" a1 concat_map_all_distinct document_ptr_kinds_eq2_h2
+ document_ptr_kinds_eq2_h3
+ by fastforce
+ then show "distinct |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ proof (cases "old_document \<noteq> x")
+ case True
+ then show ?thesis
+ proof (cases "document_ptr \<noteq> x")
+ case True
+ then show ?thesis
+ using disconnected_nodes_eq2_h2[OF \<open>old_document \<noteq> x\<close>]
+ disconnected_nodes_eq2_h3[OF \<open>document_ptr \<noteq> x\<close>] 4
+ by(auto)
+ next
+ case False
+ then show ?thesis
+ using disc_nodes_document_ptr_h3 disc_nodes_document_ptr_h' 4
+ \<open>child \<notin> set disc_nodes_document_ptr_h3\<close>
+ by(auto simp add: disconnected_nodes_eq2_h2[OF \<open>old_document \<noteq> x\<close>] )
+ qed
+ next
+ case False
+ then show ?thesis
+ by (metis (no_types, hide_lams) \<open>distinct disc_nodes_old_document_h2\<close>
+ disc_nodes_old_document_h3 disconnected_nodes_eq2_h3 distinct_remove1 docs_neq select_result_I2)
+ qed
+ next
+ fix x y
+ assume a0: "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ and a1: "y \<in> set (sorted_list_of_set (fset (document_ptr_kinds h')))"
+ and a2: "x \<noteq> y"
+
+ moreover have 5: "set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ using 2 calculation by (auto simp add: document_ptr_kinds_eq3_h2 document_ptr_kinds_eq3_h3
+ dest: distinct_concat_map_E(1))
+ ultimately show "set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ proof(cases "old_document = x")
+ case True
+ have "old_document \<noteq> y"
+ using \<open>x \<noteq> y\<close> \<open>old_document = x\<close> by simp
+ have "document_ptr \<noteq> x"
+ using docs_neq \<open>old_document = x\<close> by auto
+ show ?thesis
+ proof(cases "document_ptr = y")
+ case True
+ then show ?thesis
+ using 5 True select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2] select_result_I2[OF disc_nodes_old_document_h3]
+ \<open>old_document = x\<close>
+ by (metis (no_types, lifting) \<open>child \<notin> set (remove1 child disc_nodes_old_document_h2)\<close>
+ \<open>document_ptr \<noteq> x\<close> disconnected_nodes_eq2_h3 disjoint_iff_not_equal notin_set_remove1 set_ConsD)
+ next
+ case False
+ then show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2] select_result_I2[OF disc_nodes_old_document_h3]
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 \<open>old_document = x\<close>
+ docs_neq \<open>old_document \<noteq> y\<close>
+ by (metis (no_types, lifting) disjoint_iff_not_equal notin_set_remove1)
+ qed
+ next
+ case False
+ then show ?thesis
+ proof(cases "old_document = y")
+ case True
+ then show ?thesis
+ proof(cases "document_ptr = x")
+ case True
+ show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3] \<open>old_document \<noteq> x\<close> \<open>old_document = y\<close> \<open>document_ptr = x\<close>
+ apply(simp)
+ by (metis (no_types, lifting) \<open>child \<notin> set (remove1 child disc_nodes_old_document_h2)\<close>
+ disconnected_nodes_eq2_h3 disjoint_iff_not_equal notin_set_remove1)
+ next
+ case False
+ then show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3] \<open>old_document \<noteq> x\<close> \<open>old_document = y\<close>
+ \<open>document_ptr \<noteq> x\<close>
+ by (metis (no_types, lifting) disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ disjoint_iff_not_equal docs_neq notin_set_remove1)
+ qed
+ next
+ case False
+ have "set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}"
+ by (metis DocumentMonad.ptr_kinds_M_ok DocumentMonad.ptr_kinds_M_ptr_kinds False
+ \<open>type_wf h2\<close> a1 disc_nodes_old_document_h2 document_ptr_kinds_M_def document_ptr_kinds_eq2_h2
+ document_ptr_kinds_eq2_h3 l_ptr_kinds_M.ptr_kinds_ptr_kinds_M local.get_disconnected_nodes_ok
+ local.heap_is_wellformed_one_disc_parent returns_result_select_result wellformed_h2)
+ then show ?thesis
+ proof(cases "document_ptr = x")
+ case True
+ then have "document_ptr \<noteq> y"
+ using \<open>x \<noteq> y\<close> by auto
+ have "set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}"
+ using \<open>set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}\<close>
+ by blast
+ then show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_document_ptr_h2]
+ select_result_I2[OF disc_nodes_old_document_h2]
+ select_result_I2[OF disc_nodes_old_document_h3] \<open>old_document \<noteq> x\<close> \<open>old_document \<noteq> y\<close>
+ \<open>document_ptr = x\<close> \<open>document_ptr \<noteq> y\<close>
+ \<open>child \<in> set disc_nodes_old_document_h2\<close> disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3 \<open>set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}\<close>
+ by(auto)
+ next
+ case False
+ then show ?thesis
+ proof(cases "document_ptr = y")
+ case True
+ have f1: "set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set disc_nodes_document_ptr_h3 = {}"
+ using 2 a1 document_ptr_in_heap document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3
+ \<open>document_ptr \<noteq> x\<close> select_result_I2[OF disc_nodes_document_ptr_h3, symmetric]
+ disconnected_nodes_eq2_h2[OF docs_neq[symmetric], symmetric]
+ by (simp add: "5" True)
+ moreover have f1: "set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes old_document|\<^sub>r = {}"
+ using 2 a1 old_document_in_heap document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3
+ \<open>old_document \<noteq> x\<close>
+ by (metis (no_types, lifting) a0 distinct_concat_map_E(1) document_ptr_kinds_eq3_h2
+ document_ptr_kinds_eq3_h3 finite_fset fmember.rep_eq set_sorted_list_of_set)
+ ultimately show ?thesis
+ using 5 select_result_I2[OF disc_nodes_document_ptr_h']
+ select_result_I2[OF disc_nodes_old_document_h2] \<open>old_document \<noteq> x\<close>
+ \<open>document_ptr \<noteq> x\<close> \<open>document_ptr = y\<close>
+ \<open>child \<in> set disc_nodes_old_document_h2\<close> disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3
+ by auto
+ next
+ case False
+ then show ?thesis
+ using 5
+ select_result_I2[OF disc_nodes_old_document_h2] \<open>old_document \<noteq> x\<close>
+ \<open>document_ptr \<noteq> x\<close> \<open>document_ptr \<noteq> y\<close>
+ \<open>child \<in> set disc_nodes_old_document_h2\<close> disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3
+ by (metis \<open>set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r \<inter> set disc_nodes_old_document_h2 = {}\<close>
+ empty_iff inf.idem)
+ qed
+ qed
+ qed
+ qed
+ qed
+ next
+ fix x xa xb
+ assume 0: "distinct (concat (map (\<lambda>ptr. |h' \<turnstile> get_child_nodes ptr|\<^sub>r)
+(sorted_list_of_set (fset (object_ptr_kinds h')))))"
+ and 1: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+(sorted_list_of_set (fset (document_ptr_kinds h2)))))"
+ and 2: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r) \<inter>
+(\<Union>x\<in>fset (document_ptr_kinds h2). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 3: "xa |\<in>| object_ptr_kinds h'"
+ and 4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 5: "xb |\<in>| document_ptr_kinds h'"
+ and 6: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ then show False
+ using \<open>child \<in> set disc_nodes_old_document_h2\<close> disc_nodes_document_ptr_h'
+ disc_nodes_document_ptr_h2 disc_nodes_old_document_h2 disc_nodes_old_document_h3
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3
+ old_document_in_heap
+ apply(auto)[1]
+ apply(cases "xb = old_document")
+ proof -
+ assume a1: "xb = old_document"
+ assume a2: "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disc_nodes_old_document_h2"
+ assume a3: "h3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r remove1 child disc_nodes_old_document_h2"
+ assume a4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ assume "document_ptr_kinds h2 = document_ptr_kinds h'"
+ assume a5: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r) \<inter>
+(\<Union>x\<in>fset (document_ptr_kinds h'). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ have f6: "old_document |\<in>| document_ptr_kinds h'"
+ using a1 \<open>xb |\<in>| document_ptr_kinds h'\<close> by blast
+ have f7: "|h2 \<turnstile> get_disconnected_nodes old_document|\<^sub>r = disc_nodes_old_document_h2"
+ using a2 by simp
+ have "x \<in> set disc_nodes_old_document_h2"
+ using f6 a3 a1 by (metis (no_types) \<open>type_wf h'\<close> \<open>x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r\<close>
+ disconnected_nodes_eq_h3 docs_neq get_disconnected_nodes_ok returns_result_eq
+ returns_result_select_result set_remove1_subset subsetCE)
+ then have "set |h' \<turnstile> get_child_nodes xa|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes xb|\<^sub>r = {}"
+ using f7 f6 a5 a4 \<open>xa |\<in>| object_ptr_kinds h'\<close>
+ by fastforce
+ then show ?thesis
+ using \<open>x \<in> set disc_nodes_old_document_h2\<close> a1 a4 f7 by blast
+ next
+ assume a1: "xb \<noteq> old_document"
+ assume a2: "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_document_ptr_h3"
+ assume a3: "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disc_nodes_old_document_h2"
+ assume a4: "xa |\<in>| object_ptr_kinds h'"
+ assume a5: "h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r child # disc_nodes_document_ptr_h3"
+ assume a6: "old_document |\<in>| document_ptr_kinds h'"
+ assume a7: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ assume a8: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ assume a9: "document_ptr_kinds h2 = document_ptr_kinds h'"
+ assume a10: "\<And>doc_ptr. old_document \<noteq> doc_ptr \<Longrightarrow>
+|h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ assume a11: "\<And>doc_ptr. document_ptr \<noteq> doc_ptr \<Longrightarrow>
+|h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ assume a12: "(\<Union>x\<in>fset (object_ptr_kinds h'). set |h' \<turnstile> get_child_nodes x|\<^sub>r) \<inter>
+(\<Union>x\<in>fset (document_ptr_kinds h'). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ have f13: "\<And>d. d \<notin> set |h' \<turnstile> document_ptr_kinds_M|\<^sub>r \<or> h2 \<turnstile> ok get_disconnected_nodes d"
+ using a9 \<open>type_wf h2\<close> get_disconnected_nodes_ok
+ by simp
+ then have f14: "|h2 \<turnstile> get_disconnected_nodes old_document|\<^sub>r = disc_nodes_old_document_h2"
+ using a6 a3 by simp
+ have "x \<notin> set |h2 \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ using a12 a8 a4 \<open>xb |\<in>| document_ptr_kinds h'\<close>
+ by (meson UN_I disjoint_iff_not_equal fmember.rep_eq)
+ then have "x = child"
+ using f13 a11 a10 a7 a5 a2 a1
+ by (metis (no_types, lifting) select_result_I2 set_ConsD)
+ then have "child \<notin> set disc_nodes_old_document_h2"
+ using f14 a12 a8 a6 a4
+ by (metis \<open>type_wf h'\<close> adopt_node_removes_child assms(1) assms(2) type_wf
+ get_child_nodes_ok known_ptrs local.known_ptrs_known_ptr object_ptr_kinds_h2_eq3
+ object_ptr_kinds_h3_eq3 object_ptr_kinds_h_eq3 returns_result_select_result)
+ then show ?thesis
+ using \<open>child \<in> set disc_nodes_old_document_h2\<close> by fastforce
+ qed
+ qed
+ ultimately have "heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M h'"
+ using \<open>type_wf h'\<close> \<open>CD.a_owner_document_valid h'\<close> CD.heap_is_wellformed_def by blast
+
+
+
+ have shadow_root_eq_h2: "\<And>ptr' shadow_root_ptr_opt. h2 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt =
+h3 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt"
+ using get_shadow_root_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: adopt_node_locs_def remove_child_locs_def set_child_nodes_get_shadow_root
+ set_disconnected_nodes_get_shadow_root)
+ then
+ have shadow_root_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_shadow_root ptr'|\<^sub>r = |h3 \<turnstile> get_shadow_root ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have shadow_root_eq_h3: "\<And>ptr' shadow_root_ptr_opt. h3 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt =
+h' \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt"
+ using get_shadow_root_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: adopt_node_locs_def remove_child_locs_def set_child_nodes_get_shadow_root
+ set_disconnected_nodes_get_shadow_root)
+ then
+ have shadow_root_eq2_h3: "\<And>ptr'. |h3 \<turnstile> get_shadow_root ptr'|\<^sub>r = |h' \<turnstile> get_shadow_root ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have tag_name_eq_h2: "\<And>ptr' tag. h2 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r tag = h3 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r tag"
+ using get_tag_name_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: adopt_node_locs_def remove_child_locs_def set_child_nodes_get_tag_name
+ set_disconnected_nodes_get_tag_name)
+ then
+ have tag_name_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_tag_name ptr'|\<^sub>r = |h3 \<turnstile> get_tag_name ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have tag_name_eq_h3: "\<And>ptr' tag. h3 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r tag = h' \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r tag"
+ using get_tag_name_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: adopt_node_locs_def remove_child_locs_def set_child_nodes_get_tag_name
+ set_disconnected_nodes_get_tag_name)
+ then
+ have tag_name_eq2_h3: "\<And>ptr'. |h3 \<turnstile> get_tag_name ptr'|\<^sub>r = |h' \<turnstile> get_tag_name ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h2 = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h3])
+ unfolding adopt_node_locs_def remove_child_locs_def
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def split: if_splits)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h3 = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h'])
+ unfolding adopt_node_locs_def remove_child_locs_def
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def split: if_splits)
+
+ have document_ptr_kinds_eq_h2: "document_ptr_kinds h2 = document_ptr_kinds h3"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: document_ptr_kinds_def)
+
+ have shadow_root_ptr_kinds_eq_h2: "shadow_root_ptr_kinds h2 = shadow_root_ptr_kinds h3"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ have element_ptr_kinds_eq_h2: "element_ptr_kinds h2 = element_ptr_kinds h3"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: element_ptr_kinds_def node_ptr_kinds_def)
+
+ have document_ptr_kinds_eq_h3: "document_ptr_kinds h3 = document_ptr_kinds h'"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: document_ptr_kinds_def)
+ have shadow_root_ptr_kinds_eq_h3: "shadow_root_ptr_kinds h3 = shadow_root_ptr_kinds h'"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ have element_ptr_kinds_eq_h3: "element_ptr_kinds h3 = element_ptr_kinds h'"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: element_ptr_kinds_def node_ptr_kinds_def)
+
+ have "a_host_shadow_root_rel h' = a_host_shadow_root_rel h3" and
+ "a_host_shadow_root_rel h3 = a_host_shadow_root_rel h2"
+ by(auto simp add: a_host_shadow_root_rel_def shadow_root_eq2_h2 shadow_root_eq2_h3
+ element_ptr_kinds_eq_h2 element_ptr_kinds_eq_h3)
+ have "parent_child_rel h' = parent_child_rel h3" and "parent_child_rel h3 = parent_child_rel h2"
+ by(auto simp add: CD.parent_child_rel_def children_eq2_h2 children_eq2_h3
+ object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3)
+
+
+ have "parent_child_rel h2 \<subseteq> parent_child_rel h"
+ using h2 parent_opt
+ proof (induct parent_opt)
+ case None
+ then show ?case
+ by simp
+ next
+ case (Some parent)
+ then
+ have h2: "h \<turnstile> remove_child parent child \<rightarrow>\<^sub>h h2"
+ by auto
+ have child_nodes_eq_h: "\<And>ptr children. parent \<noteq> ptr \<Longrightarrow>
+h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads remove_child_writes h2
+ apply(rule reads_writes_preserved)
+ apply(auto simp add: remove_child_locs_def)[1]
+ by (simp add: set_child_nodes_get_child_nodes_different_pointers)
+ moreover obtain children where children: "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children"
+ using Some local.get_parent_child_dual by blast
+ ultimately show ?thesis
+ using object_ptr_kinds_eq_h h2
+ apply(auto simp add: CD.parent_child_rel_def split: option.splits)[1]
+ apply(case_tac "parent = a")
+ apply (metis (no_types, lifting) \<open>type_wf h3\<close> children_eq2_h2 children_eq_h2 known_ptrs
+ local.get_child_nodes_ok local.known_ptrs_known_ptr local.remove_child_children_subset
+ object_ptr_kinds_h2_eq3 returns_result_select_result subset_code(1) type_wf)
+ apply (metis (no_types, lifting) known_ptrs local.get_child_nodes_ok local.known_ptrs_known_ptr
+ returns_result_select_result select_result_I2 type_wf)
+ done
+ qed
+
+ have "a_host_shadow_root_rel h2 = a_host_shadow_root_rel h"
+ using h2
+ proof (induct parent_opt)
+ case None
+ then show ?case
+ by simp
+ next
+ case (Some parent)
+ then
+ have h2: "h \<turnstile> remove_child parent child \<rightarrow>\<^sub>h h2"
+ by auto
+ have "\<And>ptr shadow_root. h \<turnstile> get_shadow_root ptr \<rightarrow>\<^sub>r shadow_root = h2 \<turnstile> get_shadow_root ptr \<rightarrow>\<^sub>r shadow_root"
+ using get_shadow_root_reads remove_child_writes h2
+ apply(rule reads_writes_preserved)
+ apply(auto simp add: remove_child_locs_def)[1]
+ by (auto simp add: set_disconnected_nodes_get_shadow_root set_child_nodes_get_shadow_root)
+ then show ?case
+ apply(auto simp add: a_host_shadow_root_rel_def)[1]
+ apply (metis (mono_tags, lifting) Collect_cong \<open>type_wf h2\<close> case_prodE case_prodI
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_host_shadow_root_rel_def local.get_shadow_root_ok
+ local.a_host_shadow_root_rel_shadow_root returns_result_select_result)
+ by (metis (no_types, lifting) Collect_cong case_prodE case_prodI local.get_shadow_root_ok
+ local.a_host_shadow_root_rel_def local.a_host_shadow_root_rel_shadow_root returns_result_select_result type_wf)
+ qed
+
+ have "a_ptr_disconnected_node_rel h3 = a_ptr_disconnected_node_rel h2 - {(cast old_document, cast child)}"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h2 disconnected_nodes_eq2_h2)[1]
+ using disconnected_nodes_eq2_h2 disc_nodes_old_document_h2 disc_nodes_old_document_h3
+ using \<open>distinct disc_nodes_old_document_h2\<close>
+ apply (metis (no_types, lifting) \<open>child \<notin> set (remove1 child disc_nodes_old_document_h2)\<close>
+ case_prodI in_set_remove1 mem_Collect_eq pair_imageI select_result_I2)
+ using \<open>child \<notin> set (remove1 child disc_nodes_old_document_h2)\<close> disc_nodes_old_document_h3
+ apply auto[1]
+ by (metis (no_types, lifting) case_prodI disc_nodes_old_document_h2 disc_nodes_old_document_h3
+ disconnected_nodes_eq2_h2 in_set_remove1 mem_Collect_eq pair_imageI select_result_I2)
+
+ have "a_ptr_disconnected_node_rel h3 \<subseteq> a_ptr_disconnected_node_rel h"
+ using h2 parent_opt
+ proof (induct parent_opt)
+ case None
+ then show ?case
+ by(auto simp add: \<open>a_ptr_disconnected_node_rel h3 = a_ptr_disconnected_node_rel h2 - {(cast old_document, cast child)}\<close>)
+ next
+ case (Some parent)
+ then
+ have h2: "h \<turnstile> remove_child parent child \<rightarrow>\<^sub>h h2"
+ by auto
+ then
+ obtain children_h h'2 disconnected_nodes_h where
+ children_h: "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children_h" and
+ child_in_children_h: "child \<in> set children_h" and
+ disconnected_nodes_h: "h \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disconnected_nodes_h" and
+ h'2: "h \<turnstile> set_disconnected_nodes old_document (child # disconnected_nodes_h) \<rightarrow>\<^sub>h h'2" and
+ h': "h'2 \<turnstile> set_child_nodes parent (remove1 child children_h) \<rightarrow>\<^sub>h h2"
+ using old_document
+ apply(auto simp add: remove_child_def elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_child_nodes_pure]
+ pure_returns_heap_eq[rotated, OF get_disconnected_nodes_pure] split: if_splits)[1]
+ using select_result_I2 by fastforce
+
+ have "|h3 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ by(auto simp add: document_ptr_kinds_def)
+ have disconnected_nodes_eq_h: "\<And>ptr disc_nodes. old_document \<noteq> ptr \<Longrightarrow>
+h \<turnstile> get_disconnected_nodes ptr \<rightarrow>\<^sub>r disc_nodes = h2 \<turnstile> get_disconnected_nodes ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads remove_child_writes h2
+ apply(rule reads_writes_preserved)
+ apply(auto simp add: remove_child_locs_def)[1]
+ using old_document
+ by (auto simp add:set_child_nodes_get_disconnected_nodes set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then
+ have foo: "\<And>ptr disc_nodes. old_document \<noteq> ptr \<Longrightarrow>
+h \<turnstile> get_disconnected_nodes ptr \<rightarrow>\<^sub>r disc_nodes = h3 \<turnstile> get_disconnected_nodes ptr \<rightarrow>\<^sub>r disc_nodes"
+ using disconnected_nodes_eq_h2 by simp
+ then
+ have foo2: "\<And>ptr. old_document \<noteq> ptr \<Longrightarrow> |h \<turnstile> get_disconnected_nodes ptr|\<^sub>r =
+|h3 \<turnstile> get_disconnected_nodes ptr|\<^sub>r"
+ by (meson select_result_eq)
+ have "h'2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r child # disconnected_nodes_h"
+ using h'2
+ using local.set_disconnected_nodes_get_disconnected_nodes by blast
+
+ have "h2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r child # disconnected_nodes_h"
+ using get_disconnected_nodes_reads set_child_nodes_writes h'
+ \<open>h'2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r child # disconnected_nodes_h\<close>
+ apply(rule reads_writes_separate_forwards)
+ using local.set_child_nodes_get_disconnected_nodes by blast
+ then have "h3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disconnected_nodes_h"
+ using h3
+ using disc_nodes_old_document_h2 disc_nodes_old_document_h3 returns_result_eq
+ by fastforce
+ have "a_ptr_disconnected_node_rel h3 = a_ptr_disconnected_node_rel h"
+ using \<open>|h3 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h \<turnstile> document_ptr_kinds_M|\<^sub>r\<close>
+ apply(auto simp add: a_ptr_disconnected_node_rel_def )[1]
+ apply(case_tac "old_document = aa")
+ using disconnected_nodes_h \<open>h3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disconnected_nodes_h\<close>
+ using foo2
+ apply(auto)[1]
+ using disconnected_nodes_h \<open>h3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disconnected_nodes_h\<close>
+ using foo2
+ apply(auto)[1]
+ apply(case_tac "old_document = aa")
+ using disconnected_nodes_h \<open>h3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disconnected_nodes_h\<close>
+ using foo2
+ apply(auto)[1]
+ using disconnected_nodes_h \<open>h3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disconnected_nodes_h\<close>
+ using foo2
+ apply(auto)[1]
+ done
+ then show ?thesis
+ by auto
+ qed
+
+ have "acyclic (parent_child_rel h2 \<union> a_host_shadow_root_rel h2 \<union> a_ptr_disconnected_node_rel h2)"
+ using local.heap_is_wellformed_def wellformed_h2 by blast
+ then have "acyclic (parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3)"
+ using \<open>a_ptr_disconnected_node_rel h3 = a_ptr_disconnected_node_rel h2 - {(cast old_document, cast child)}\<close>
+ by(auto simp add: \<open>parent_child_rel h3 = parent_child_rel h2\<close> \<open>a_host_shadow_root_rel h3 = a_host_shadow_root_rel h2\<close> elim!: acyclic_subset)
+ moreover
+ have "a_ptr_disconnected_node_rel h' = insert (cast document_ptr, cast child) (a_ptr_disconnected_node_rel h3)"
+ using disconnected_nodes_eq2_h3[symmetric] disc_nodes_document_ptr_h3 disc_nodes_document_ptr_h' document_ptr_in_heap[unfolded document_ptr_kinds_eq_h2]
+ apply(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h3[symmetric])[1]
+ apply(case_tac "document_ptr = aa")
+ apply(auto)[1]
+ apply(auto)[1]
+ apply(case_tac "document_ptr = aa")
+ apply(auto)[1]
+ apply(auto)[1]
+ done
+ moreover have "(cast child, cast document_ptr) \<notin> (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ using \<open>h \<turnstile> get_ancestors_di (cast document_ptr) \<rightarrow>\<^sub>r ancestors\<close>
+ \<open>cast child \<notin> set ancestors\<close> get_ancestors_di_parent_child_a_host_shadow_root_rel
+ using assms(1) known_ptrs type_wf by blast
+ moreover have "(cast child, cast document_ptr) \<notin> (parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3)\<^sup>*"
+ proof -
+ have "(parent_child_rel h3 \<union> local.a_host_shadow_root_rel h3 \<union> local.a_ptr_disconnected_node_rel h3) \<subseteq> (parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> local.a_ptr_disconnected_node_rel h)"
+ apply(simp add: \<open>parent_child_rel h3 = parent_child_rel h2\<close> \<open>a_host_shadow_root_rel h3 = a_host_shadow_root_rel h2\<close> \<open>a_host_shadow_root_rel h2 = a_host_shadow_root_rel h\<close>)
+ using \<open>local.a_ptr_disconnected_node_rel h3 \<subseteq> local.a_ptr_disconnected_node_rel h\<close> \<open>parent_child_rel h2 \<subseteq> parent_child_rel h\<close>
+ by blast
+ then show ?thesis
+ using calculation(3) rtrancl_mono by blast
+ qed
+ ultimately have "acyclic (parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h')"
+ by(auto simp add: \<open>parent_child_rel h' = parent_child_rel h3\<close> \<open>a_host_shadow_root_rel h' = a_host_shadow_root_rel h3\<close>)
+
+ show "heap_is_wellformed h'"
+ using \<open>heap_is_wellformed h2\<close>
+ using \<open>heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M h'\<close>
+ using \<open>acyclic (parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h')\<close>
+ apply(auto simp add: heap_is_wellformed_def CD.heap_is_wellformed_def CD.acyclic_heap_def
+ a_all_ptrs_in_heap_def a_distinct_lists_def a_shadow_root_valid_def)[1]
+ by(auto simp add: object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 element_ptr_kinds_eq_h2
+ element_ptr_kinds_eq_h3 shadow_root_ptr_kinds_eq_h2 shadow_root_ptr_kinds_eq_h3 shadow_root_eq_h2
+ shadow_root_eq_h3 shadow_root_eq2_h2 shadow_root_eq2_h3 tag_name_eq_h2 tag_name_eq_h3 tag_name_eq2_h2
+ tag_name_eq2_h3)
+ qed
+qed
+
+
+lemma adopt_node_node_in_disconnected_nodes:
+ assumes wellformed: "heap_is_wellformed h"
+ and adopt_node: "h \<turnstile> adopt_node owner_document node_ptr \<rightarrow>\<^sub>h h'"
+ and "h' \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "node_ptr \<in> set disc_nodes"
+proof -
+ obtain old_document parent_opt h2 where
+ old_document: "h \<turnstile> get_owner_document (cast node_ptr) \<rightarrow>\<^sub>r old_document" and
+ parent_opt: "h \<turnstile> get_parent node_ptr \<rightarrow>\<^sub>r parent_opt" and
+ h2: "h \<turnstile> (case parent_opt of Some parent \<Rightarrow> remove_child parent node_ptr | None \<Rightarrow> return ()) \<rightarrow>\<^sub>h h2" and
+ h': "h2 \<turnstile> (if owner_document \<noteq> old_document then do {
+ old_disc_nodes \<leftarrow> get_disconnected_nodes old_document;
+ set_disconnected_nodes old_document (remove1 node_ptr old_disc_nodes);
+ disc_nodes \<leftarrow> get_disconnected_nodes owner_document;
+ set_disconnected_nodes owner_document (node_ptr # disc_nodes)
+ } else do {
+ return ()
+ }) \<rightarrow>\<^sub>h h'"
+ using assms(2)[unfolded adopt_node_def CD.adopt_node_def]
+ by(auto elim!: bind_returns_heap_E dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_parent_pure] pure_returns_heap_eq[rotated, OF get_ancestors_di_pure]
+ split: option.splits if_splits)
+
+ show ?thesis
+ proof (cases "owner_document = old_document")
+ case True
+ then show ?thesis
+ proof (insert parent_opt h2, induct parent_opt)
+ case None
+ then have "h = h'"
+ using h2 h' by(auto)
+ then show ?case
+ using in_disconnected_nodes_no_parent assms None old_document by blast
+ next
+ case (Some parent)
+ then show ?case
+ using remove_child_in_disconnected_nodes known_ptrs True h' assms(3) old_document
+ by auto
+ qed
+ next
+ case False
+ then show ?thesis
+ using assms(3) h' list.set_intros(1) select_result_I2
+ set_disconnected_nodes_get_disconnected_nodes
+ apply(auto elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated])[1]
+ proof -
+ fix x and h'a and xb
+ assume a1: "h' \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes"
+ assume a2: "\<And>h document_ptr disc_nodes h'. h \<turnstile> set_disconnected_nodes document_ptr disc_nodes \<rightarrow>\<^sub>h h' \<Longrightarrow>
+h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes"
+ assume "h'a \<turnstile> set_disconnected_nodes owner_document (node_ptr # xb) \<rightarrow>\<^sub>h h'"
+ then have "node_ptr # xb = disc_nodes"
+ using a2 a1 by (meson returns_result_eq)
+ then show ?thesis
+ by (meson list.set_intros(1))
+ qed
+ qed
+qed
+end
+
+interpretation i_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M: l_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document get_parent get_parent_locs remove_child remove_child_locs get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes get_child_nodes_locs known_ptrs set_child_nodes
+ set_child_nodes_locs remove heap_is_wellformed parent_child_rel
+ by(auto simp add: l_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare i_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.l_adopt_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+interpretation i_adopt_node_wf?: l_adopt_node_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_owner_document get_parent get_parent_locs remove_child remove_child_locs get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs get_ancestors_di
+ get_ancestors_di_locs adopt_node adopt_node_locs adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf
+ get_child_nodes get_child_nodes_locs known_ptrs set_child_nodes set_child_nodes_locs get_host
+ get_host_locs get_disconnected_document get_disconnected_document_locs remove heap_is_wellformed
+ parent_child_rel
+ by(auto simp add: l_adopt_node_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_adopt_node_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+interpretation i_adopt_node_wf2?: l_adopt_node_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ set_child_nodes set_child_nodes_locs get_shadow_root get_shadow_root_locs set_disconnected_nodes
+ set_disconnected_nodes_locs get_tag_name get_tag_name_locs get_owner_document get_parent get_parent_locs
+ remove_child remove_child_locs remove known_ptrs heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_host get_host_locs get_disconnected_document get_disconnected_document_locs get_root_node
+ get_root_node_locs get_ancestors_di get_ancestors_di_locs adopt_node adopt_node_locs adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ by(auto simp add: l_adopt_node_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_adopt_node_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+lemma adopt_node_wf_is_l_adopt_node_wf [instances]:
+ "l_adopt_node_wf type_wf known_ptr heap_is_wellformed parent_child_rel get_child_nodes
+get_disconnected_nodes known_ptrs adopt_node"
+ apply(auto simp add: l_adopt_node_wf_def l_adopt_node_wf_axioms_def instances)[1]
+ using adopt_node_preserves_wellformedness apply blast
+ using adopt_node_removes_child apply blast
+ using adopt_node_node_in_disconnected_nodes apply blast
+ using adopt_node_removes_first_child apply blast
+ using adopt_node_document_in_heap apply blast
+ done
+
+
+subsubsection \<open>insert\_before\<close>
+
+locale l_insert_before_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes +
+ l_get_disconnected_nodes +
+ l_set_child_nodes_get_shadow_root +
+ l_set_disconnected_nodes_get_shadow_root +
+ l_set_child_nodes_get_tag_name +
+ l_set_disconnected_nodes_get_tag_name +
+ l_set_disconnected_nodes_get_disconnected_nodes +
+ l_set_child_nodes_get_disconnected_nodes +
+ l_set_disconnected_nodes_get_disconnected_nodes_wf +
+ (* l_set_disconnected_nodes_get_ancestors_si + *)
+ l_insert_before\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M _ _ _ _ _ _ get_ancestors_di get_ancestors_di_locs +
+ (* l_get_root_node_si_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M + *)
+ l_get_owner_document +
+ l_adopt_node\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_adopt_node_wf +
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_adopt_node_get_shadow_root +
+ l_get_ancestors_di_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_remove_child_wf2
+begin
+lemma insert_before_child_preserves:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> insert_before ptr node child \<rightarrow>\<^sub>h h'"
+ shows "type_wf h'" and "known_ptrs h'" and "heap_is_wellformed h'"
+proof -
+ obtain ancestors reference_child owner_document h2 h3 disconnected_nodes_h2 where
+ ancestors: "h \<turnstile> get_ancestors_di ptr \<rightarrow>\<^sub>r ancestors" and
+ node_not_in_ancestors: "cast node \<notin> set ancestors" and
+ reference_child: "h \<turnstile> (if Some node = child then a_next_sibling node else return child) \<rightarrow>\<^sub>r reference_child" and
+ owner_document: "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document" and
+ h2: "h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h2" and
+ disconnected_nodes_h2: "h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disconnected_nodes_h2" and
+ h3: "h2 \<turnstile> set_disconnected_nodes owner_document (remove1 node disconnected_nodes_h2) \<rightarrow>\<^sub>h h3" and
+ h': "h3 \<turnstile> a_insert_node ptr node reference_child \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ by(auto simp add: insert_before_def a_ensure_pre_insertion_validity_def
+ elim!: bind_returns_heap_E bind_returns_result_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_ancestors_pure, rotated]
+ bind_returns_heap_E2[rotated, OF next_sibling_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_owner_document_pure, rotated]
+ split: if_splits option.splits)
+
+ obtain old_document parent_opt h'2 (* ancestors *) where
+ (* "h \<turnstile> get_ancestors_di (cast owner_document) \<rightarrow>\<^sub>r ancestors" and
+ "cast child \<notin> set ancestors" and *)
+ old_document: "h \<turnstile> get_owner_document (cast node) \<rightarrow>\<^sub>r old_document" and
+ parent_opt: "h \<turnstile> get_parent node \<rightarrow>\<^sub>r parent_opt" and
+ h'2: "h \<turnstile> (case parent_opt of Some parent \<Rightarrow> remove_child parent node | None \<Rightarrow> return ()) \<rightarrow>\<^sub>h h'2" and
+ h2': "h'2 \<turnstile> (if owner_document \<noteq> old_document then do {
+ old_disc_nodes \<leftarrow> get_disconnected_nodes old_document;
+ set_disconnected_nodes old_document (remove1 node old_disc_nodes);
+ disc_nodes \<leftarrow> get_disconnected_nodes owner_document;
+ set_disconnected_nodes owner_document (node # disc_nodes)
+ } else do {
+ return ()
+ }) \<rightarrow>\<^sub>h h2"
+ using h2
+ apply(auto simp add: adopt_node_def[unfolded CD.adopt_node_def] elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_ancestors_di_pure])[1]
+ apply(split if_splits)
+ by(auto simp add: elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure] pure_returns_heap_eq[rotated, OF get_parent_pure])
+
+ have "type_wf h2"
+ using \<open>type_wf h\<close>
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF adopt_node_writes h2]
+ using adopt_node_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h3]
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then show "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF insert_node_writes h']
+ using set_child_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have "object_ptr_kinds h = object_ptr_kinds h2"
+ using adopt_node_writes h2
+ apply(rule writes_small_big)
+ using adopt_node_pointers_preserved
+ by(auto simp add: reflp_def transp_def)
+ moreover have "\<dots> = object_ptr_kinds h3"
+ using set_disconnected_nodes_writes h3
+ apply(rule writes_small_big)
+ using set_disconnected_nodes_pointers_preserved
+ by(auto simp add: reflp_def transp_def)
+ moreover have "\<dots> = object_ptr_kinds h'"
+ using insert_node_writes h'
+ apply(rule writes_small_big)
+ using set_child_nodes_pointers_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ ultimately
+ show "known_ptrs h'"
+ using \<open>known_ptrs h\<close> known_ptrs_preserved
+ by blast
+
+ have "known_ptrs h2"
+ using \<open>known_ptrs h\<close> known_ptrs_preserved \<open>object_ptr_kinds h = object_ptr_kinds h2\<close>
+ by blast
+ then
+ have "known_ptrs h3"
+ using known_ptrs_preserved \<open>object_ptr_kinds h2 = object_ptr_kinds h3\<close>
+ by blast
+
+ have "known_ptr ptr"
+ by (meson get_owner_document_ptr_in_heap is_OK_returns_result_I \<open>known_ptrs h\<close>
+ l_known_ptrs.known_ptrs_known_ptr l_known_ptrs_axioms owner_document)
+
+ have object_ptr_kinds_M_eq3_h: "object_ptr_kinds h = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'", OF adopt_node_writes h2])
+ using adopt_node_pointers_preserved
+ apply blast
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h: "\<And>ptrs. h \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs )
+ then have object_ptr_kinds_M_eq2_h: "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq2_h: "|h \<turnstile> node_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+
+ have wellformed_h2: "heap_is_wellformed h2"
+ using adopt_node_preserves_wellformedness[OF \<open>heap_is_wellformed h\<close> h2] \<open>known_ptrs h\<close> \<open>type_wf h\<close>
+ .
+
+ have object_ptr_kinds_M_eq3_h2: "object_ptr_kinds h2 = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h3])
+ unfolding a_remove_child_locs_def
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h2: "\<And>ptrs. h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_M_eq2_h2: "|h2 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq2_h2: "|h2 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ have document_ptr_kinds_eq2_h2: "|h2 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h3 \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_M_eq2_h2 document_ptr_kinds_M_eq by auto
+
+ have object_ptr_kinds_M_eq3_h': "object_ptr_kinds h3 = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'", OF insert_node_writes h'])
+ unfolding a_remove_child_locs_def
+ using set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h3: "\<And>ptrs. h3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h' \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_M_eq2_h3: "|h3 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have node_ptr_kinds_eq2_h3: "|h3 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ have document_ptr_kinds_eq2_h3: "|h3 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h' \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_M_eq2_h3 document_ptr_kinds_M_eq by auto
+
+
+ have shadow_root_eq_h2: "\<And>ptr' shadow_root. h \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root =
+h2 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root"
+ using get_shadow_root_reads adopt_node_writes h2
+ apply(rule reads_writes_preserved)
+ using local.adopt_node_get_shadow_root by blast
+
+ have disconnected_nodes_eq_h2: "\<And>doc_ptr disc_nodes. owner_document \<noteq> doc_ptr \<Longrightarrow>
+h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by (auto simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h2: "\<And>doc_ptr. doc_ptr \<noteq> owner_document \<Longrightarrow>
+|h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_h3: "h3 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r remove1 node disconnected_nodes_h2"
+ using h3 set_disconnected_nodes_get_disconnected_nodes
+ by blast
+
+ have disconnected_nodes_eq_h3:
+ "\<And>doc_ptr disc_nodes. h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads insert_node_writes h'
+ apply(rule reads_writes_preserved)
+ using set_child_nodes_get_disconnected_nodes by fast
+ then have disconnected_nodes_eq2_h3:
+ "\<And>doc_ptr. |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by (auto simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h3:
+ "\<And>ptr' children. ptr \<noteq> ptr' \<Longrightarrow> h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads insert_node_writes h'
+ apply(rule reads_writes_preserved)
+ by (auto simp add: set_child_nodes_get_child_nodes_different_pointers)
+ then have children_eq2_h3: "\<And>ptr'. ptr \<noteq> ptr' \<Longrightarrow> |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ obtain children_h3 where children_h3: "h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children_h3"
+ using h' a_insert_node_def by auto
+ have children_h': "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r insert_before_list node reference_child children_h3"
+ using h' \<open>type_wf h3\<close> \<open>known_ptr ptr\<close>
+ by(auto simp add: a_insert_node_def elim!: bind_returns_heap_E2
+ dest!: set_child_nodes_get_child_nodes returns_result_eq[OF children_h3])
+
+
+ have shadow_root_eq_h: "\<And>ptr' shadow_root_ptr_opt. h \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt =
+h2 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt"
+ using get_shadow_root_reads adopt_node_writes h2
+ apply(rule reads_writes_preserved)
+ by(auto simp add: adopt_node_locs_def CD.adopt_node_locs_def CD.remove_child_locs_def
+ set_child_nodes_get_shadow_root set_disconnected_nodes_get_shadow_root)
+ then
+ have shadow_root_eq2_h: "\<And>ptr'. |h \<turnstile> get_shadow_root ptr'|\<^sub>r = |h2 \<turnstile> get_shadow_root ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have shadow_root_eq_h2: "\<And>ptr' shadow_root_ptr_opt. h2 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt =
+h3 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt"
+ using get_shadow_root_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: adopt_node_locs_def remove_child_locs_def set_child_nodes_get_shadow_root
+ set_disconnected_nodes_get_shadow_root)
+ then
+ have shadow_root_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_shadow_root ptr'|\<^sub>r = |h3 \<turnstile> get_shadow_root ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have shadow_root_eq_h3: "\<And>ptr' shadow_root_ptr_opt. h3 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt =
+h' \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r shadow_root_ptr_opt"
+ using get_shadow_root_reads insert_node_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: adopt_node_locs_def remove_child_locs_def set_child_nodes_get_shadow_root
+ set_disconnected_nodes_get_shadow_root)
+ then
+ have shadow_root_eq2_h3: "\<And>ptr'. |h3 \<turnstile> get_shadow_root ptr'|\<^sub>r = |h' \<turnstile> get_shadow_root ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have tag_name_eq_h2: "\<And>ptr' tag. h2 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r tag = h3 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r tag"
+ using get_tag_name_reads set_disconnected_nodes_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: adopt_node_locs_def remove_child_locs_def set_child_nodes_get_tag_name
+ set_disconnected_nodes_get_tag_name)
+ then
+ have tag_name_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_tag_name ptr'|\<^sub>r = |h3 \<turnstile> get_tag_name ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have tag_name_eq_h3: "\<And>ptr' tag. h3 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r tag = h' \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r tag"
+ using get_tag_name_reads insert_node_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: adopt_node_locs_def remove_child_locs_def set_child_nodes_get_tag_name
+ set_disconnected_nodes_get_tag_name)
+ then
+ have tag_name_eq2_h3: "\<And>ptr'. |h3 \<turnstile> get_tag_name ptr'|\<^sub>r = |h' \<turnstile> get_tag_name ptr'|\<^sub>r"
+ by (meson select_result_eq)
+
+ have object_ptr_kinds_eq_hx: "object_ptr_kinds h = object_ptr_kinds h'2"
+ using h'2 apply(simp split: option.splits)
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'", OF CD.remove_child_writes])
+ using CD.remove_child_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ have document_ptr_kinds_eq_hx: "document_ptr_kinds h = document_ptr_kinds h'2"
+ using object_ptr_kinds_eq_hx
+ by(auto simp add: document_ptr_kinds_def document_ptr_kinds_def)
+ have shadow_root_ptr_kinds_eq_hx: "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'2"
+ using object_ptr_kinds_eq_hx
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ have element_ptr_kinds_eq_hx: "element_ptr_kinds h = element_ptr_kinds h'2"
+ using object_ptr_kinds_eq_hx
+ by(auto simp add: element_ptr_kinds_def node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h: "object_ptr_kinds h = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'", OF adopt_node_writes h2])
+ unfolding adopt_node_locs_def CD.adopt_node_locs_def CD.remove_child_locs_def
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def split: if_splits)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h = document_ptr_kinds h2"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def document_ptr_kinds_def)
+ have shadow_root_ptr_kinds_eq_h: "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h2"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h = element_ptr_kinds h2"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: element_ptr_kinds_def node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h2 = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'", OF set_disconnected_nodes_writes h3])
+ unfolding adopt_node_locs_def remove_child_locs_def
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def split: if_splits)
+ have document_ptr_kinds_eq_h2: "document_ptr_kinds h2 = document_ptr_kinds h3"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: document_ptr_kinds_def document_ptr_kinds_def)
+ have shadow_root_ptr_kinds_eq_h2: "shadow_root_ptr_kinds h2 = shadow_root_ptr_kinds h3"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ have element_ptr_kinds_eq_h2: "element_ptr_kinds h2 = element_ptr_kinds h3"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: element_ptr_kinds_def node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h3 = object_ptr_kinds h'"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'", OF insert_node_writes h'])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def split: if_splits)
+ have document_ptr_kinds_eq_h3: "document_ptr_kinds h3 = document_ptr_kinds h'"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: document_ptr_kinds_def document_ptr_kinds_def)
+ have shadow_root_ptr_kinds_eq_h3: "shadow_root_ptr_kinds h3 = shadow_root_ptr_kinds h'"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ have element_ptr_kinds_eq_h3: "element_ptr_kinds h3 = element_ptr_kinds h'"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: element_ptr_kinds_def node_ptr_kinds_def)
+
+
+ have wellformed_h'2: "heap_is_wellformed h'2"
+ using h'2 remove_child_heap_is_wellformed_preserved assms
+ by (metis (no_types, lifting) assms(1) option.case_eq_if pure_returns_heap_eq return_pure)
+
+ have "known_ptrs h'2"
+ using \<open>known_ptrs h\<close> known_ptrs_preserved \<open>object_ptr_kinds h = object_ptr_kinds h'2\<close>
+ by blast
+
+ have "type_wf h'2"
+ using \<open>type_wf h\<close> h'2
+ apply(auto split: option.splits)[1]
+ apply(drule writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF CD.remove_child_writes])
+ using CD.remove_child_types_preserved
+ by(auto simp add: reflp_def transp_def )
+
+
+ have ptr_in_heap: "ptr |\<in>| object_ptr_kinds h3"
+ using children_h3 get_child_nodes_ptr_in_heap by blast
+ have node_in_heap: "node |\<in>| node_ptr_kinds h"
+ using h2 adopt_node_child_in_heap by fast
+ have child_not_in_any_children: "\<And>p children. h2 \<turnstile> get_child_nodes p \<rightarrow>\<^sub>r children \<Longrightarrow> node \<notin> set children"
+ using \<open>heap_is_wellformed h\<close> h2 adopt_node_removes_child \<open>type_wf h\<close> \<open>known_ptrs h\<close> by auto
+ have "node \<in> set disconnected_nodes_h2"
+ using disconnected_nodes_h2 h2 adopt_node_node_in_disconnected_nodes assms(1) \<open>type_wf h\<close> \<open>known_ptrs h\<close> by blast
+ have node_not_in_disconnected_nodes: "\<And>d. d |\<in>| document_ptr_kinds h3 \<Longrightarrow> node \<notin> set |h3 \<turnstile> get_disconnected_nodes d|\<^sub>r"
+ proof -
+ fix d
+ assume "d |\<in>| document_ptr_kinds h3"
+ show "node \<notin> set |h3 \<turnstile> get_disconnected_nodes d|\<^sub>r"
+ proof (cases "d = owner_document")
+ case True
+ then show ?thesis
+ using disconnected_nodes_h2 wellformed_h2 h3 remove_from_disconnected_nodes_removes wellformed_h2
+ \<open>d |\<in>| document_ptr_kinds h3\<close> disconnected_nodes_h3
+ by fastforce
+ next
+ case False
+ then have "set |h2 \<turnstile> get_disconnected_nodes d|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes owner_document|\<^sub>r = {}"
+ using distinct_concat_map_E(1) wellformed_h2
+ by (metis (no_types, lifting) \<open>d |\<in>| document_ptr_kinds h3\<close> \<open>type_wf h2\<close> disconnected_nodes_h2
+ document_ptr_kinds_M_def document_ptr_kinds_eq2_h2 l_ptr_kinds_M.ptr_kinds_ptr_kinds_M
+ local.get_disconnected_nodes_ok local.heap_is_wellformed_one_disc_parent returns_result_select_result
+ select_result_I2)
+ then show ?thesis
+ using disconnected_nodes_eq2_h2[OF False] \<open>node \<in> set disconnected_nodes_h2\<close> disconnected_nodes_h2 by fastforce
+ qed
+ qed
+
+ have "cast node \<noteq> ptr"
+ using ancestors node_not_in_ancestors get_ancestors_ptr
+ by fast
+
+ have "a_host_shadow_root_rel h = a_host_shadow_root_rel h2"
+ by(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h shadow_root_eq2_h)
+ have "a_host_shadow_root_rel h2 = a_host_shadow_root_rel h3"
+ by(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h2 shadow_root_eq2_h2)
+ have "a_host_shadow_root_rel h3 = a_host_shadow_root_rel h'"
+ by(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h3 shadow_root_eq2_h3)
+
+ have "parent_child_rel h2 \<subseteq> parent_child_rel h"
+ proof -
+ have "parent_child_rel h'2 \<subseteq> parent_child_rel h"
+ using h'2 parent_opt
+ proof (induct parent_opt)
+ case None
+ then show ?case
+ by simp
+ next
+ case (Some parent)
+ then
+ have h'2: "h \<turnstile> remove_child parent node \<rightarrow>\<^sub>h h'2"
+ by auto
+ then
+ have "parent |\<in>| object_ptr_kinds h"
+ using CD.remove_child_ptr_in_heap
+ by blast
+ have child_nodes_eq_h: "\<And>ptr children. parent \<noteq> ptr \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children =
+h'2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads CD.remove_child_writes h'2
+ apply(rule reads_writes_preserved)
+ apply(auto simp add: CD.remove_child_locs_def)[1]
+ by (simp add: set_child_nodes_get_child_nodes_different_pointers)
+ moreover obtain children where children: "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children"
+ using Some local.get_parent_child_dual by blast
+ moreover obtain children_h'2 where children_h'2: "h'2 \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children_h'2"
+ using object_ptr_kinds_eq_hx calculation(2) \<open>parent |\<in>| object_ptr_kinds h\<close> get_child_nodes_ok
+ by (metis \<open>type_wf h'2\<close> assms(3) is_OK_returns_result_E local.known_ptrs_known_ptr)
+ ultimately show ?thesis
+ using object_ptr_kinds_eq_h h2
+ apply(auto simp add: CD.parent_child_rel_def object_ptr_kinds_eq_hx split: option.splits)[1]
+ apply(case_tac "parent = a")
+ using CD.remove_child_children_subset
+ apply (metis (no_types, lifting) assms(2) assms(3) contra_subsetD h'2 select_result_I2)
+ by (metis select_result_eq)
+ qed
+ moreover have "parent_child_rel h2 = parent_child_rel h'2"
+ proof(cases "owner_document = old_document")
+ case True
+ then show ?thesis
+ using h2' by simp
+ next
+ case False
+ then obtain h'3 old_disc_nodes disc_nodes_document_ptr_h'3 where
+ docs_neq: "owner_document \<noteq> old_document" and
+ old_disc_nodes: "h'2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r old_disc_nodes" and
+ h'3: "h'2 \<turnstile> set_disconnected_nodes old_document (remove1 node old_disc_nodes) \<rightarrow>\<^sub>h h'3" and
+ disc_nodes_document_ptr_h3: "h'3 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes_document_ptr_h'3" and
+ h2': "h'3 \<turnstile> set_disconnected_nodes owner_document (node # disc_nodes_document_ptr_h'3) \<rightarrow>\<^sub>h h2"
+ using h2'
+ by(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+
+ have object_ptr_kinds_h'2_eq3: "object_ptr_kinds h'2 = object_ptr_kinds h'3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h'3])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h'2: "\<And>ptrs. h'2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h'3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq_h'2: "|h'2 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h'3 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+ then have node_ptr_kinds_eq_h'2: "|h'2 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h'3 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ then have node_ptr_kinds_eq3_h'2: "node_ptr_kinds h'2 = node_ptr_kinds h'3"
+ by auto
+ have document_ptr_kinds_eq2_h'2: "|h'2 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h'3 \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq_h'2 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3_h'2: "document_ptr_kinds h'2 = document_ptr_kinds h'3"
+ using object_ptr_kinds_eq_h'2 document_ptr_kinds_M_eq by auto
+ have children_eq_h'2: "\<And>ptr children. h'2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children = h'3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h'3
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h'2: "\<And>ptr. |h'2 \<turnstile> get_child_nodes ptr|\<^sub>r = |h'3 \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have object_ptr_kinds_h'3_eq3: "object_ptr_kinds h'3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h2. object_ptr_kinds h = object_ptr_kinds h2",
+ OF set_disconnected_nodes_writes h2'])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h'3: "\<And>ptrs. h'3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq_h'3: "|h'3 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+ then have node_ptr_kinds_eq_h'3: "|h'3 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ then have node_ptr_kinds_eq3_h'3: "node_ptr_kinds h'3 = node_ptr_kinds h2"
+ by auto
+ have document_ptr_kinds_eq2_h'3: "|h'3 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq_h'3 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3_h'3: "document_ptr_kinds h'3 = document_ptr_kinds h2"
+ using object_ptr_kinds_eq_h'3 document_ptr_kinds_M_eq by auto
+ have children_eq_h'3: "\<And>ptr children. h'3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children =
+h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children"
+ using get_child_nodes_reads set_disconnected_nodes_writes h2'
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h'3: "\<And>ptr. |h'3 \<turnstile> get_child_nodes ptr|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using select_result_eq by force
+
+ show ?thesis
+ by(auto simp add: CD.parent_child_rel_def object_ptr_kinds_h'2_eq3 object_ptr_kinds_h'3_eq3
+ children_eq2_h'3 children_eq2_h'2)
+ qed
+ ultimately
+ show ?thesis
+ by simp
+ qed
+
+ have "parent_child_rel h2 = parent_child_rel h3"
+ by(auto simp add: CD.parent_child_rel_def object_ptr_kinds_M_eq3_h2 children_eq2_h2)
+ have "parent_child_rel h' = insert (ptr, cast node) ((parent_child_rel h3))"
+ using children_h3 children_h' ptr_in_heap
+ apply(auto simp add: CD.parent_child_rel_def object_ptr_kinds_M_eq3_h' children_eq2_h3
+ insert_before_list_node_in_set)[1]
+ apply (metis (no_types, lifting) children_eq2_h3 insert_before_list_in_set select_result_I2)
+ by (metis (no_types, lifting) children_eq2_h3 imageI insert_before_list_in_set select_result_I2)
+
+ have "a_ptr_disconnected_node_rel h3 \<subseteq> a_ptr_disconnected_node_rel h"
+ proof -
+ have "a_ptr_disconnected_node_rel h3 = a_ptr_disconnected_node_rel h2 - {(cast owner_document, cast node)}"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h2)[1]
+ apply(case_tac "aa = owner_document")
+ using disconnected_nodes_h2 disconnected_nodes_h3 notin_set_remove1 apply fastforce
+ using disconnected_nodes_eq2_h2 apply auto[1]
+ using node_not_in_disconnected_nodes apply blast
+ apply(case_tac "aa = owner_document")
+ using disconnected_nodes_h2 disconnected_nodes_h3 notin_set_remove1 apply fastforce
+ using disconnected_nodes_eq2_h2 apply auto[1]
+ apply(case_tac "aa = owner_document")
+ using disconnected_nodes_h2 disconnected_nodes_h3 notin_set_remove1 apply fastforce
+ using disconnected_nodes_eq2_h2 apply auto[1]
+ done
+ then have "a_ptr_disconnected_node_rel h'2 \<subseteq> a_ptr_disconnected_node_rel h \<union> {(cast old_document, cast node)}"
+ using h'2 parent_opt
+ proof (induct parent_opt)
+ case None
+ then show ?case
+ by auto
+ next
+ case (Some parent)
+ then
+ have h'2: "h \<turnstile> remove_child parent node \<rightarrow>\<^sub>h h'2"
+ by auto
+ then
+ have "parent |\<in>| object_ptr_kinds h"
+ using CD.remove_child_ptr_in_heap
+ by blast
+ obtain children_h h''2 disconnected_nodes_h where
+ owner_document: "h \<turnstile> get_owner_document (cast node) \<rightarrow>\<^sub>r old_document" and
+ children_h: "h \<turnstile> get_child_nodes parent \<rightarrow>\<^sub>r children_h" and
+ child_in_children_h: "node \<in> set children_h" and
+ disconnected_nodes_h: "h \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r disconnected_nodes_h" and
+ h''2: "h \<turnstile> set_disconnected_nodes old_document (node # disconnected_nodes_h) \<rightarrow>\<^sub>h h''2" and
+ h'2: "h''2 \<turnstile> set_child_nodes parent (remove1 node children_h) \<rightarrow>\<^sub>h h'2"
+ using h'2 old_document
+ apply(auto simp add: CD.remove_child_def elim!: bind_returns_heap_E
+ dest!: pure_returns_heap_eq[rotated, OF get_owner_document_pure]
+ pure_returns_heap_eq[rotated, OF get_child_nodes_pure] split: if_splits)[1]
+ using pure_returns_heap_eq returns_result_eq by fastforce
+
+ have disconnected_nodes_eq: "\<And>ptr' disc_nodes. ptr' \<noteq> old_document \<Longrightarrow>
+h \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes = h''2 \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using local.get_disconnected_nodes_reads set_disconnected_nodes_writes h''2
+ apply(rule reads_writes_preserved)
+ by (metis local.set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then
+ have disconnected_nodes_eq2: "\<And>ptr'. ptr' \<noteq> old_document \<Longrightarrow>
+|h \<turnstile> get_disconnected_nodes ptr'|\<^sub>r = |h''2 \<turnstile> get_disconnected_nodes ptr'|\<^sub>r"
+ by (meson select_result_eq)
+ have "h''2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r node # disconnected_nodes_h"
+ using h''2 local.set_disconnected_nodes_get_disconnected_nodes
+ by blast
+
+ have disconnected_nodes_eq_h2:
+ "\<And>ptr' disc_nodes. h''2 \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes = h'2 \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using local.get_disconnected_nodes_reads set_child_nodes_writes h'2
+ apply(rule reads_writes_preserved)
+ by (metis local.set_child_nodes_get_disconnected_nodes)
+ then
+ have disconnected_nodes_eq2_h2:
+ "\<And>ptr'. |h''2 \<turnstile> get_disconnected_nodes ptr'|\<^sub>r = |h'2 \<turnstile> get_disconnected_nodes ptr'|\<^sub>r"
+ by (meson select_result_eq)
+ show ?case
+ apply(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_hx
+ \<open>\<And>ptr'. |h''2 \<turnstile> get_disconnected_nodes ptr'|\<^sub>r = |h'2 \<turnstile> get_disconnected_nodes ptr'|\<^sub>r\<close>[symmetric])[1]
+ apply(case_tac "aa = old_document")
+ using disconnected_nodes_h
+ \<open>h''2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r node # disconnected_nodes_h\<close>
+ apply(auto)[1]
+ apply(auto dest!: disconnected_nodes_eq2)[1]
+ apply(case_tac "aa = old_document")
+ using disconnected_nodes_h
+ \<open>h''2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r node # disconnected_nodes_h\<close>
+ apply(auto)[1]
+ apply(auto dest!: disconnected_nodes_eq2)[1]
+ done
+ qed
+ show ?thesis
+ proof(cases "owner_document = old_document")
+ case True
+ then have "a_ptr_disconnected_node_rel h'2 = a_ptr_disconnected_node_rel h2"
+ using h2'
+ by(auto simp add: a_ptr_disconnected_node_rel_def)
+ then
+ show ?thesis
+ using \<open>a_ptr_disconnected_node_rel h3 =
+a_ptr_disconnected_node_rel h2 - {(cast owner_document, cast node)}\<close>
+ using True \<open>local.a_ptr_disconnected_node_rel h'2 \<subseteq> local.a_ptr_disconnected_node_rel h \<union>
+{(cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r old_document, cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node)}\<close> by auto
+ next
+ case False
+ then obtain h'3 old_disc_nodes disc_nodes_document_ptr_h'3 where
+ docs_neq: "owner_document \<noteq> old_document" and
+ old_disc_nodes: "h'2 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r old_disc_nodes" and
+ h'3: "h'2 \<turnstile> set_disconnected_nodes old_document (remove1 node old_disc_nodes) \<rightarrow>\<^sub>h h'3" and
+ disc_nodes_document_ptr_h3: "h'3 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disc_nodes_document_ptr_h'3" and
+ h2': "h'3 \<turnstile> set_disconnected_nodes owner_document (node # disc_nodes_document_ptr_h'3) \<rightarrow>\<^sub>h h2"
+ using h2'
+ by(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated] )
+
+ have object_ptr_kinds_h'2_eq3: "object_ptr_kinds h'2 = object_ptr_kinds h'3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h = object_ptr_kinds h'",
+ OF set_disconnected_nodes_writes h'3])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h'2:
+ "\<And>ptrs. h'2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h'3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq_h'2: "|h'2 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h'3 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+ then have node_ptr_kinds_eq_h'2: "|h'2 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h'3 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ then have node_ptr_kinds_eq3_h'2: "node_ptr_kinds h'2 = node_ptr_kinds h'3"
+ by auto
+ have document_ptr_kinds_eq2_h'2: "|h'2 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h'3 \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq_h'2 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3_h'2: "document_ptr_kinds h'2 = document_ptr_kinds h'3"
+ using object_ptr_kinds_eq_h'2 document_ptr_kinds_M_eq by auto
+
+ have disconnected_nodes_eq: "\<And>ptr' disc_nodes. ptr' \<noteq> old_document \<Longrightarrow>
+h'2 \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes = h'3 \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using local.get_disconnected_nodes_reads set_disconnected_nodes_writes h'3
+ apply(rule reads_writes_preserved)
+ by (metis local.set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then
+ have disconnected_nodes_eq2: "\<And>ptr'. ptr' \<noteq> old_document \<Longrightarrow>
+|h'2 \<turnstile> get_disconnected_nodes ptr'|\<^sub>r = |h'3 \<turnstile> get_disconnected_nodes ptr'|\<^sub>r"
+ by (meson select_result_eq)
+ have "h'3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r (remove1 node old_disc_nodes)"
+ using h'3 local.set_disconnected_nodes_get_disconnected_nodes
+ by blast
+
+ have object_ptr_kinds_h'3_eq3: "object_ptr_kinds h'3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h2. object_ptr_kinds h = object_ptr_kinds h2",
+ OF set_disconnected_nodes_writes h2'])
+ using set_disconnected_nodes_pointers_preserved set_child_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have object_ptr_kinds_M_eq_h'3: "\<And>ptrs. h'3 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs = h2 \<turnstile> object_ptr_kinds_M \<rightarrow>\<^sub>r ptrs"
+ by(simp add: object_ptr_kinds_M_defs)
+ then have object_ptr_kinds_eq_h'3: "|h'3 \<turnstile> object_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by(simp)
+ then have node_ptr_kinds_eq_h'3: "|h'3 \<turnstile> node_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_ptr_kinds_M_eq by blast
+ then have node_ptr_kinds_eq3_h'3: "node_ptr_kinds h'3 = node_ptr_kinds h2"
+ by auto
+ have document_ptr_kinds_eq2_h'3: "|h'3 \<turnstile> document_ptr_kinds_M|\<^sub>r = |h2 \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using object_ptr_kinds_eq_h'3 document_ptr_kinds_M_eq by auto
+ then have document_ptr_kinds_eq3_h'3: "document_ptr_kinds h'3 = document_ptr_kinds h2"
+ using object_ptr_kinds_eq_h'3 document_ptr_kinds_M_eq by auto
+ have disc_nodes_eq_h'3:
+ "\<And>ptr disc_nodes. h'3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r disc_nodes = h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_child_nodes_reads set_disconnected_nodes_writes h2'
+ apply(rule reads_writes_preserved)
+ by (simp add: set_disconnected_nodes_get_child_nodes)
+ then have disc_nodes_eq2_h'3: "\<And>ptr. |h'3 \<turnstile> get_child_nodes ptr|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have disconnected_nodes_eq: "\<And>ptr' disc_nodes. ptr' \<noteq> owner_document \<Longrightarrow>
+h'3 \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes = h2 \<turnstile> get_disconnected_nodes ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using local.get_disconnected_nodes_reads set_disconnected_nodes_writes h2'
+ apply(rule reads_writes_preserved)
+ by (metis local.set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then
+ have disconnected_nodes_eq2': "\<And>ptr'. ptr' \<noteq> owner_document \<Longrightarrow>
+|h'3 \<turnstile> get_disconnected_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes ptr'|\<^sub>r"
+ by (meson select_result_eq)
+ have "h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r (node # disc_nodes_document_ptr_h'3)"
+ using h2' local.set_disconnected_nodes_get_disconnected_nodes
+ by blast
+
+ have "a_ptr_disconnected_node_rel h'3 = a_ptr_disconnected_node_rel h'2 - {(cast old_document, cast node)}"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq2_h'2[simplified])[1]
+ apply(case_tac "aa = old_document")
+ using \<open>h'3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r (remove1 node old_disc_nodes)\<close>
+ notin_set_remove1 old_disc_nodes
+ apply fastforce
+ apply(auto dest!: disconnected_nodes_eq2)[1]
+ using \<open>h'3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r remove1 node old_disc_nodes\<close> h'3
+ local.remove_from_disconnected_nodes_removes old_disc_nodes wellformed_h'2
+ apply auto[1]
+ defer
+ apply(case_tac "aa = old_document")
+ using \<open>h'3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r (remove1 node old_disc_nodes)\<close>
+ notin_set_remove1 old_disc_nodes
+ apply fastforce
+ apply(auto dest!: disconnected_nodes_eq2)[1]
+ apply(case_tac "aa = old_document")
+ using \<open>h'3 \<turnstile> get_disconnected_nodes old_document \<rightarrow>\<^sub>r (remove1 node old_disc_nodes)\<close>
+ notin_set_remove1 old_disc_nodes
+ apply fastforce
+ apply(auto dest!: disconnected_nodes_eq2)[1]
+ done
+ moreover
+ have "a_ptr_disconnected_node_rel h2 = a_ptr_disconnected_node_rel h'3 \<union>
+{(cast owner_document, cast node)}"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq2_h'3[simplified])[1]
+ apply(case_tac "aa = owner_document")
+ apply(simp)
+ apply(auto dest!: disconnected_nodes_eq2')[1]
+ apply(case_tac "aa = owner_document")
+ using \<open>h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r node # disc_nodes_document_ptr_h'3\<close>
+ disc_nodes_document_ptr_h3 apply auto[1]
+ apply(auto dest!: disconnected_nodes_eq2')[1]
+ using \<open>node \<in> set disconnected_nodes_h2\<close> disconnected_nodes_h2 local.a_ptr_disconnected_node_rel_def
+ local.a_ptr_disconnected_node_rel_disconnected_node apply blast
+ defer
+ apply(case_tac "aa = owner_document")
+ using \<open>h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r node # disc_nodes_document_ptr_h'3\<close>
+ disc_nodes_document_ptr_h3 apply auto[1]
+ apply(auto dest!: disconnected_nodes_eq2')[1]
+ done
+ ultimately show ?thesis
+ using \<open>a_ptr_disconnected_node_rel h3 =
+a_ptr_disconnected_node_rel h2 - {(cast owner_document, cast node)}\<close>
+ using \<open>a_ptr_disconnected_node_rel h'2 \<subseteq>
+a_ptr_disconnected_node_rel h \<union> {(cast old_document, cast node)}\<close>
+ by blast
+ qed
+ qed
+
+ have "(cast node, ptr) \<notin> (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)\<^sup>*"
+ using h2
+ apply(auto simp add: adopt_node_def elim!: bind_returns_heap_E2 split: if_splits)[1]
+ using ancestors assms(1) assms(2) assms(3) local.get_ancestors_di_parent_child_a_host_shadow_root_rel node_not_in_ancestors
+ by blast
+ then
+ have "(cast node, ptr) \<notin> (parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3)\<^sup>*"
+ apply(simp add: \<open>a_host_shadow_root_rel h = a_host_shadow_root_rel h2\<close> \<open>a_host_shadow_root_rel h2 = a_host_shadow_root_rel h3\<close>)
+ apply(simp add: \<open>parent_child_rel h2 = parent_child_rel h3\<close>[symmetric])
+ using \<open>parent_child_rel h2 \<subseteq> parent_child_rel h\<close> \<open>a_ptr_disconnected_node_rel h3 \<subseteq> a_ptr_disconnected_node_rel h\<close>
+ by (smt Un_assoc in_rtrancl_UnI sup.orderE sup_left_commute)
+
+ have "CD.a_acyclic_heap h'"
+ proof -
+ have "acyclic (parent_child_rel h2)"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def CD.acyclic_heap_def)
+ then have "acyclic (parent_child_rel h3)"
+ by(auto simp add: CD.parent_child_rel_def object_ptr_kinds_M_eq3_h2 children_eq2_h2)
+ moreover have "cast node \<notin> {x. (x, ptr) \<in> (parent_child_rel h3)\<^sup>*}"
+ by (meson \<open>(cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r node, ptr) \<notin> (parent_child_rel h3 \<union> local.a_host_shadow_root_rel h3 \<union>
+local.a_ptr_disconnected_node_rel h3)\<^sup>*\<close> in_rtrancl_UnI mem_Collect_eq)
+ ultimately show ?thesis
+ using \<open>parent_child_rel h' = insert (ptr, cast node) ((parent_child_rel h3))\<close>
+ by(auto simp add: CD.acyclic_heap_def)
+ qed
+
+
+ moreover have "CD.a_all_ptrs_in_heap h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ have "CD.a_all_ptrs_in_heap h'"
+ proof -
+ have "CD.a_all_ptrs_in_heap h3"
+ using \<open>CD.a_all_ptrs_in_heap h2\<close>
+ apply(auto simp add: CD.a_all_ptrs_in_heap_def object_ptr_kinds_M_eq2_h2 node_ptr_kinds_eq2_h2
+ children_eq_h2)[1]
+ apply (metis \<open>known_ptrs h3\<close> \<open>type_wf h3\<close> children_eq_h2
+ l_heap_is_wellformed.heap_is_wellformed_children_in_heap local.get_child_nodes_ok
+ local.known_ptrs_known_ptr local.l_heap_is_wellformed_axioms node_ptr_kinds_commutes
+ object_ptr_kinds_eq_h2 returns_result_select_result wellformed_h2)
+ by (metis (mono_tags, hide_lams) disconnected_nodes_eq2_h2 disconnected_nodes_h2
+ disconnected_nodes_h3 document_ptr_kinds_eq_h2 finite_set_in node_ptr_kinds_commutes
+ object_ptr_kinds_eq_h2 select_result_I2 set_remove1_subset subsetD)
+ have "set children_h3 \<subseteq> set |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using children_h3 \<open>CD.a_all_ptrs_in_heap h3\<close>
+ apply(auto simp add: CD.a_all_ptrs_in_heap_def node_ptr_kinds_eq2_h3)[1]
+ using children_eq_h2 local.heap_is_wellformed_children_in_heap node_ptr_kinds_eq2_h2
+ node_ptr_kinds_eq2_h3 wellformed_h2 by auto
+ then have "set (insert_before_list node reference_child children_h3) \<subseteq> set |h' \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ using node_in_heap
+ apply(auto simp add: node_ptr_kinds_eq2_h node_ptr_kinds_eq2_h2 node_ptr_kinds_eq2_h3)[1]
+ by (metis (no_types, hide_lams) contra_subsetD finite_set_in insert_before_list_in_set
+ node_ptr_kinds_commutes object_ptr_kinds_M_eq3_h object_ptr_kinds_M_eq3_h' object_ptr_kinds_M_eq3_h2)
+ then show ?thesis
+ using \<open>CD.a_all_ptrs_in_heap h3\<close>
+ apply(auto simp add: object_ptr_kinds_M_eq3_h' CD.a_all_ptrs_in_heap_def node_ptr_kinds_def
+ node_ptr_kinds_eq2_h3 disconnected_nodes_eq_h3)[1]
+ apply (metis (no_types, lifting) children_eq2_h3 children_h' finite_set_in select_result_I2 subsetD)
+ by (metis (no_types, lifting) disconnected_nodes_eq2_h3 document_ptr_kinds_eq_h3 in_mono notin_fset)
+ qed
+
+
+ moreover have "CD.a_distinct_lists h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def )
+ then have "CD.a_distinct_lists h3"
+ proof(auto simp add: CD.a_distinct_lists_def object_ptr_kinds_M_eq2_h2 document_ptr_kinds_eq2_h2
+ children_eq2_h2 intro!: distinct_concat_map_I)
+ fix x
+ assume 1: "x |\<in>| document_ptr_kinds h3"
+ and 2: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+(sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ show "distinct |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using distinct_concat_map_E(2)[OF 2] select_result_I2[OF disconnected_nodes_h3]
+ disconnected_nodes_eq2_h2 select_result_I2[OF disconnected_nodes_h2] 1
+ by (metis (full_types) distinct_remove1 finite_fset fmember.rep_eq set_sorted_list_of_set)
+ next
+ fix x y xa
+ assume 1: "distinct (concat (map (\<lambda>document_ptr. |h2 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+(sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and 2: "x |\<in>| document_ptr_kinds h3"
+ and 3: "y |\<in>| document_ptr_kinds h3"
+ and 4: "x \<noteq> y"
+ and 5: "xa \<in> set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ and 6: "xa \<in> set |h3 \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ show False
+ proof (cases "x = owner_document")
+ case True
+ then have "y \<noteq> owner_document"
+ using 4 by simp
+ show ?thesis
+ using distinct_concat_map_E(1)[OF 1]
+ using 2 3 4 5 6 select_result_I2[OF disconnected_nodes_h3] select_result_I2[OF disconnected_nodes_h2]
+ apply(auto simp add: True disconnected_nodes_eq2_h2[OF \<open>y \<noteq> owner_document\<close>])[1]
+ by (metis (no_types, hide_lams) disconnected_nodes_eq2_h2 disjoint_iff_not_equal notin_set_remove1)
+ next
+ case False
+ then show ?thesis
+ proof (cases "y = owner_document")
+ case True
+ then show ?thesis
+ using distinct_concat_map_E(1)[OF 1]
+ using 2 3 4 5 6 select_result_I2[OF disconnected_nodes_h3] select_result_I2[OF disconnected_nodes_h2]
+ apply(auto simp add: True disconnected_nodes_eq2_h2[OF \<open>x \<noteq> owner_document\<close>])[1]
+ by (metis (no_types, hide_lams) disconnected_nodes_eq2_h2 disjoint_iff_not_equal notin_set_remove1)
+ next
+ case False
+ then show ?thesis
+ using distinct_concat_map_E(1)[OF 1, simplified, OF 2 3 4] 5 6
+ using disconnected_nodes_eq2_h2 disconnected_nodes_h2 disconnected_nodes_h3
+ disjoint_iff_not_equal finite_fset fmember.rep_eq notin_set_remove1 select_result_I2
+ set_sorted_list_of_set
+ by (metis (no_types, lifting))
+ qed
+ qed
+ next
+ fix x xa xb
+ assume 1: "(\<Union>x\<in>fset (object_ptr_kinds h3). set |h3 \<turnstile> get_child_nodes x|\<^sub>r) \<inter>
+(\<Union>x\<in>fset (document_ptr_kinds h3). set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 2: "xa |\<in>| object_ptr_kinds h3"
+ and 3: "x \<in> set |h3 \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 4: "xb |\<in>| document_ptr_kinds h3"
+ and 5: "x \<in> set |h3 \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ have 6: "set |h3 \<turnstile> get_child_nodes xa|\<^sub>r \<inter> set |h2 \<turnstile> get_disconnected_nodes xb|\<^sub>r = {}"
+ using 1 2 4
+ by (metis \<open>type_wf h2\<close> children_eq2_h2 document_ptr_kinds_commutes \<open>known_ptrs h\<close>
+ local.get_child_nodes_ok local.get_disconnected_nodes_ok local.heap_is_wellformed_children_disc_nodes_different
+ local.known_ptrs_known_ptr object_ptr_kinds_M_eq3_h object_ptr_kinds_M_eq3_h2 returns_result_select_result wellformed_h2)
+ show False
+ proof (cases "xb = owner_document")
+ case True
+ then show ?thesis
+ using select_result_I2[OF disconnected_nodes_h3,folded select_result_I2[OF disconnected_nodes_h2]]
+ by (metis (no_types, lifting) "3" "5" "6" disjoint_iff_not_equal notin_set_remove1)
+ next
+ case False
+ show ?thesis
+ using 2 3 4 5 6 unfolding disconnected_nodes_eq2_h2[OF False] by auto
+ qed
+ qed
+ then have "CD.a_distinct_lists h'"
+ proof(auto simp add: CD.a_distinct_lists_def document_ptr_kinds_eq2_h3 object_ptr_kinds_M_eq2_h3
+ disconnected_nodes_eq2_h3 intro!: distinct_concat_map_I)
+ fix x
+ assume 1: "distinct (concat (map (\<lambda>ptr. |h3 \<turnstile> get_child_nodes ptr|\<^sub>r) (sorted_list_of_set (fset (object_ptr_kinds h')))))" and
+ 2: "x |\<in>| object_ptr_kinds h'"
+ have 3: "\<And>p. p |\<in>| object_ptr_kinds h' \<Longrightarrow> distinct |h3 \<turnstile> get_child_nodes p|\<^sub>r"
+ using 1 by (auto elim: distinct_concat_map_E)
+ show "distinct |h' \<turnstile> get_child_nodes x|\<^sub>r"
+ proof(cases "ptr = x")
+ case True
+ show ?thesis
+ using 3[OF 2] children_h3 children_h'
+ by(auto simp add: True insert_before_list_distinct dest: child_not_in_any_children[unfolded children_eq_h2])
+ next
+ case False
+ show ?thesis
+ using children_eq2_h3[OF False] 3[OF 2] by auto
+ qed
+ next
+ fix x y xa
+ assume 1: "distinct (concat (map (\<lambda>ptr. |h3 \<turnstile> get_child_nodes ptr|\<^sub>r) (sorted_list_of_set (fset (object_ptr_kinds h')))))"
+ and 2: "x |\<in>| object_ptr_kinds h'"
+ and 3: "y |\<in>| object_ptr_kinds h'"
+ and 4: "x \<noteq> y"
+ and 5: "xa \<in> set |h' \<turnstile> get_child_nodes x|\<^sub>r"
+ and 6: "xa \<in> set |h' \<turnstile> get_child_nodes y|\<^sub>r"
+ have 7:"set |h3 \<turnstile> get_child_nodes x|\<^sub>r \<inter> set |h3 \<turnstile> get_child_nodes y|\<^sub>r = {}"
+ using distinct_concat_map_E(1)[OF 1] 2 3 4 by auto
+ show False
+ proof (cases "ptr = x")
+ case True
+ then have "ptr \<noteq> y"
+ using 4 by simp
+ then show ?thesis
+ using children_h3 children_h' child_not_in_any_children[unfolded children_eq_h2] 5 6
+ apply(auto simp add: True children_eq2_h3[OF \<open>ptr \<noteq> y\<close>])[1]
+ by (metis (no_types, hide_lams) "3" "7" \<open>type_wf h3\<close> children_eq2_h3 disjoint_iff_not_equal
+ get_child_nodes_ok insert_before_list_in_set \<open>known_ptrs h\<close> local.known_ptrs_known_ptr
+ object_ptr_kinds_M_eq3_h object_ptr_kinds_M_eq3_h' object_ptr_kinds_M_eq3_h2
+ returns_result_select_result select_result_I2)
+ next
+ case False
+ then show ?thesis
+ proof (cases "ptr = y")
+ case True
+ then show ?thesis
+ using children_h3 children_h' child_not_in_any_children[unfolded children_eq_h2] 5 6
+ apply(auto simp add: True children_eq2_h3[OF \<open>ptr \<noteq> x\<close>])[1]
+ by (metis (no_types, hide_lams) "2" "4" "7" IntI \<open>known_ptrs h3\<close> \<open>type_wf h'\<close>
+ children_eq_h3 empty_iff insert_before_list_in_set local.get_child_nodes_ok local.known_ptrs_known_ptr
+ object_ptr_kinds_M_eq3_h' returns_result_select_result select_result_I2)
+ next
+ case False
+ then show ?thesis
+ using children_eq2_h3[OF \<open>ptr \<noteq> x\<close>] children_eq2_h3[OF \<open>ptr \<noteq> y\<close>] 5 6 7 by auto
+ qed
+ qed
+ next
+ fix x xa xb
+ assume 1: " (\<Union>x\<in>fset (object_ptr_kinds h'). set |h3 \<turnstile> get_child_nodes x|\<^sub>r) \<inter> (\<Union>x\<in>fset (document_ptr_kinds h'). set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r) = {} "
+ and 2: "xa |\<in>| object_ptr_kinds h'"
+ and 3: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 4: "xb |\<in>| document_ptr_kinds h'"
+ and 5: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ have 6: "set |h3 \<turnstile> get_child_nodes xa|\<^sub>r \<inter> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r = {}"
+ using 1 2 3 4 5
+ proof -
+ have "\<forall>h d. \<not> type_wf h \<or> d |\<notin>| document_ptr_kinds h \<or> h \<turnstile> ok get_disconnected_nodes d"
+ using local.get_disconnected_nodes_ok by satx
+ then have "h' \<turnstile> ok get_disconnected_nodes xb"
+ using "4" \<open>type_wf h'\<close> by fastforce
+ then have f1: "h3 \<turnstile> get_disconnected_nodes xb \<rightarrow>\<^sub>r |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ by (simp add: disconnected_nodes_eq_h3)
+ have "xa |\<in>| object_ptr_kinds h3"
+ using "2" object_ptr_kinds_M_eq3_h' by blast
+ then show ?thesis
+ using f1 \<open>local.CD.a_distinct_lists h3\<close> CD.distinct_lists_no_parent by fastforce
+ qed
+ show False
+ proof (cases "ptr = xa")
+ case True
+ show ?thesis
+ using 6 node_not_in_disconnected_nodes 3 4 5 select_result_I2[OF children_h']
+ select_result_I2[OF children_h3] True disconnected_nodes_eq2_h3
+ by (metis (no_types, lifting) "2" DocumentMonad.ptr_kinds_ptr_kinds_M \<open>CD.a_distinct_lists h3\<close>
+ \<open>type_wf h'\<close> disconnected_nodes_eq_h3 CD.distinct_lists_no_parent document_ptr_kinds_eq2_h3
+ get_disconnected_nodes_ok insert_before_list_in_set object_ptr_kinds_M_eq3_h' returns_result_select_result)
+
+ next
+ case False
+ then show ?thesis
+ using 1 2 3 4 5 children_eq2_h3[OF False] by fastforce
+ qed
+ qed
+
+ moreover have "CD.a_owner_document_valid h2"
+ using wellformed_h2 by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_owner_document_valid h'"
+ apply(auto simp add: CD.a_owner_document_valid_def object_ptr_kinds_M_eq2_h2 object_ptr_kinds_M_eq2_h3
+ node_ptr_kinds_eq2_h2 node_ptr_kinds_eq2_h3 document_ptr_kinds_eq2_h2 document_ptr_kinds_eq2_h3 children_eq2_h2 )[1]
+ apply(auto simp add: document_ptr_kinds_eq2_h2[simplified] document_ptr_kinds_eq2_h3[simplified]
+ object_ptr_kinds_M_eq2_h2[simplified] object_ptr_kinds_M_eq2_h3[simplified] node_ptr_kinds_eq2_h2[simplified]
+ node_ptr_kinds_eq2_h3[simplified])[1]
+ apply(auto simp add: disconnected_nodes_eq2_h3[symmetric])[1]
+ by (smt Core_DOM_Functions.i_insert_before.insert_before_list_in_set children_eq2_h3 children_h'
+ children_h3 disconnected_nodes_eq2_h2 disconnected_nodes_h2 disconnected_nodes_h3 finite_set_in in_set_remove1
+ object_ptr_kinds_eq_h3 ptr_in_heap select_result_I2)
+
+ ultimately have "heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M h'"
+ by (simp add: CD.heap_is_wellformed_def)
+
+ have "a_ptr_disconnected_node_rel h3 = a_ptr_disconnected_node_rel h2 - {(cast owner_document, cast node)}"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h2 disconnected_nodes_eq2_h2)[1]
+ apply(case_tac "aa = owner_document")
+ apply (metis (no_types, lifting) case_prodI disconnected_nodes_h2 disconnected_nodes_h3
+ in_set_remove1 mem_Collect_eq node_not_in_disconnected_nodes pair_imageI select_result_I2)
+ using disconnected_nodes_eq2_h2 apply auto[1]
+ using node_not_in_disconnected_nodes apply blast
+ by (metis (no_types, lifting) case_prodI disconnected_nodes_eq2_h2 disconnected_nodes_h2
+ disconnected_nodes_h3 in_set_remove1 mem_Collect_eq pair_imageI select_result_I2)
+ have "a_ptr_disconnected_node_rel h3 = a_ptr_disconnected_node_rel h'"
+ by(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h3 disconnected_nodes_eq2_h3)
+
+ have "acyclic (parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3)"
+ using \<open>heap_is_wellformed h2\<close>
+ by(auto simp add: \<open>a_ptr_disconnected_node_rel h3 = a_ptr_disconnected_node_rel h2 - {(cast owner_document, cast node)}\<close>
+ heap_is_wellformed_def \<open>parent_child_rel h2 = parent_child_rel h3\<close> \<open>a_host_shadow_root_rel h2 = a_host_shadow_root_rel h3\<close> elim!: acyclic_subset)
+ then
+ have "acyclic (parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> local.a_ptr_disconnected_node_rel h')"
+ using \<open>(cast node, ptr) \<notin> (parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3)\<^sup>*\<close>
+ by(auto simp add: \<open>a_ptr_disconnected_node_rel h3 = a_ptr_disconnected_node_rel h'\<close> \<open>a_host_shadow_root_rel h3 =
+a_host_shadow_root_rel h'\<close> \<open>parent_child_rel h' = insert (ptr, cast node) ((parent_child_rel h3))\<close>)
+ then
+ show "heap_is_wellformed h'"
+ using \<open>heap_is_wellformed h2\<close>
+ using \<open>heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M h'\<close>
+ apply(auto simp add: heap_is_wellformed_def CD.heap_is_wellformed_def CD.acyclic_heap_def
+ a_all_ptrs_in_heap_def a_distinct_lists_def a_shadow_root_valid_def)[1]
+ by(auto simp add: object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 element_ptr_kinds_eq_h2
+ element_ptr_kinds_eq_h3 shadow_root_ptr_kinds_eq_h2 shadow_root_ptr_kinds_eq_h3 shadow_root_eq_h2
+ shadow_root_eq_h3 shadow_root_eq2_h2 shadow_root_eq2_h3 tag_name_eq_h2 tag_name_eq_h3 tag_name_eq2_h2
+ tag_name_eq2_h3)
+
+qed
+end
+
+interpretation i_insert_before_wf?: l_insert_before_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_parent get_parent_locs get_child_nodes
+ get_child_nodes_locs set_child_nodes set_child_nodes_locs get_ancestors_di get_ancestors_di_locs adopt_node
+ adopt_node_locs set_disconnected_nodes set_disconnected_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ get_owner_document insert_before insert_before_locs append_child type_wf known_ptr known_ptrs heap_is_wellformed
+ parent_child_rel
+ by(simp add: l_insert_before_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_insert_before_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma insert_before_wf_is_l_insert_before_wf [instances]: "l_insert_before_wf Shadow_DOM.heap_is_wellformed
+ShadowRootClass.type_wf ShadowRootClass.known_ptr ShadowRootClass.known_ptrs
+ Shadow_DOM.insert_before Shadow_DOM.get_child_nodes"
+ apply(auto simp add: l_insert_before_wf_def l_insert_before_wf_axioms_def instances)[1]
+ using insert_before_removes_child apply fast
+ done
+
+lemma l_set_disconnected_nodes_get_disconnected_nodes_wf [instances]: "l_set_disconnected_nodes_get_disconnected_nodes_wf ShadowRootClass.type_wf
+ShadowRootClass.known_ptr Shadow_DOM.heap_is_wellformed Shadow_DOM.parent_child_rel Shadow_DOM.get_child_nodes
+ get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs"
+ apply(auto simp add: l_set_disconnected_nodes_get_disconnected_nodes_wf_def l_set_disconnected_nodes_get_disconnected_nodes_wf_axioms_def instances)[1]
+ by (metis Diff_iff Shadow_DOM.i_heap_is_wellformed.heap_is_wellformed_disconnected_nodes_distinct Shadow_DOM.i_remove_child.set_disconnected_nodes_get_disconnected_nodes insert_iff returns_result_eq set_remove1_eq)
+
+interpretation i_insert_before_wf2?: l_insert_before_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ set_child_nodes set_child_nodes_locs get_shadow_root get_shadow_root_locs set_disconnected_nodes
+ set_disconnected_nodes_locs get_tag_name get_tag_name_locs heap_is_wellformed parent_child_rel get_parent
+ get_parent_locs adopt_node adopt_node_locs get_owner_document insert_before insert_before_locs append_child
+ known_ptrs remove_child remove_child_locs get_ancestors_di get_ancestors_di_locs adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document get_disconnected_document_locs
+ remove heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ by(auto simp add: l_insert_before_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_insert_before_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+lemma insert_before_wf2_is_l_insert_before_wf2 [instances]:
+ "l_insert_before_wf2 ShadowRootClass.type_wf ShadowRootClass.known_ptr ShadowRootClass.known_ptrs Shadow_DOM.insert_before
+ Shadow_DOM.heap_is_wellformed"
+ apply(auto simp add: l_insert_before_wf2_def l_insert_before_wf2_axioms_def instances)[1]
+ using insert_before_child_preserves apply(fast, fast, fast)
+ done
+
+
+subsubsection \<open>append\_child\<close>
+
+locale l_append_child_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_insert_before_wf2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_append_child\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma append_child_heap_is_wellformed_preserved:
+ assumes wellformed: "heap_is_wellformed h"
+ and append_child: "h \<turnstile> append_child ptr node \<rightarrow>\<^sub>h h'"
+ and known_ptrs: "known_ptrs h"
+ and type_wf: "type_wf h"
+ shows "heap_is_wellformed h'" and "type_wf h'" and "known_ptrs h'"
+ using assms
+ by(auto simp add: append_child_def intro: insert_before_child_preserves)
+
+lemma append_child_children:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs"
+ assumes "h \<turnstile> append_child ptr node \<rightarrow>\<^sub>h h'"
+ assumes "node \<notin> set xs"
+ shows "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs @ [node]"
+proof -
+
+ obtain ancestors owner_document h2 h3 disconnected_nodes_h2 where
+ ancestors: "h \<turnstile> get_ancestors_di ptr \<rightarrow>\<^sub>r ancestors" and
+ node_not_in_ancestors: "cast node \<notin> set ancestors" and
+ owner_document: "h \<turnstile> get_owner_document ptr \<rightarrow>\<^sub>r owner_document" and
+ h2: "h \<turnstile> adopt_node owner_document node \<rightarrow>\<^sub>h h2" and
+ disconnected_nodes_h2: "h2 \<turnstile> get_disconnected_nodes owner_document \<rightarrow>\<^sub>r disconnected_nodes_h2" and
+ h3: "h2 \<turnstile> set_disconnected_nodes owner_document (remove1 node disconnected_nodes_h2) \<rightarrow>\<^sub>h h3" and
+ h': "h3 \<turnstile> a_insert_node ptr node None \<rightarrow>\<^sub>h h'"
+ using assms(5)
+ by(auto simp add: append_child_def insert_before_def a_ensure_pre_insertion_validity_def
+ elim!: bind_returns_heap_E bind_returns_result_E
+ bind_returns_heap_E2[rotated, OF get_parent_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_disconnected_nodes_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_ancestors_pure, rotated]
+ bind_returns_heap_E2[rotated, OF next_sibling_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_owner_document_pure, rotated]
+ split: if_splits option.splits)
+
+ have "\<And>parent. |h \<turnstile> get_parent node|\<^sub>r = Some parent \<Longrightarrow> parent \<noteq> ptr"
+ using assms(1) assms(4) assms(6)
+ by (metis (no_types, lifting) assms(2) assms(3) h2 is_OK_returns_heap_I is_OK_returns_result_E
+ local.adopt_node_child_in_heap local.get_parent_child_dual local.get_parent_ok
+ select_result_I2)
+ have "h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs"
+ using get_child_nodes_reads adopt_node_writes h2 assms(4)
+ apply(rule reads_writes_separate_forwards)
+ using \<open>\<And>parent. |h \<turnstile> get_parent node|\<^sub>r = Some parent \<Longrightarrow> parent \<noteq> ptr\<close>
+ apply(auto simp add: adopt_node_locs_def CD.adopt_node_locs_def CD.remove_child_locs_def)[1]
+ by (meson local.set_child_nodes_get_child_nodes_different_pointers)
+
+ have "h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs"
+ using get_child_nodes_reads set_disconnected_nodes_writes h3 \<open>h2 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs\<close>
+ apply(rule reads_writes_separate_forwards)
+ by(auto)
+
+ have "ptr |\<in>| object_ptr_kinds h"
+ by (meson ancestors is_OK_returns_result_I local.get_ancestors_ptr_in_heap)
+ then
+ have "known_ptr ptr"
+ using assms(3)
+ using local.known_ptrs_known_ptr by blast
+
+ have "type_wf h2"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF adopt_node_writes h2]
+ using adopt_node_types_preserved \<open>type_wf h\<close>
+ by(auto simp add: adopt_node_locs_def remove_child_locs_def reflp_def transp_def split: if_splits)
+ then
+ have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h3]
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ show "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs@[node]"
+ using h'
+ apply(auto simp add: a_insert_node_def
+ dest!: bind_returns_heap_E3[rotated, OF \<open>h3 \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs\<close>
+ get_child_nodes_pure, rotated])[1]
+ using \<open>type_wf h3\<close> set_child_nodes_get_child_nodes \<open>known_ptr ptr\<close>
+ by metis
+qed
+
+lemma append_child_for_all_on_children:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs"
+ assumes "h \<turnstile> forall_M (append_child ptr) nodes \<rightarrow>\<^sub>h h'"
+ assumes "set nodes \<inter> set xs = {}"
+ assumes "distinct nodes"
+ shows "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs@nodes"
+ using assms
+ apply(induct nodes arbitrary: h xs)
+ apply(simp)
+proof(auto elim!: bind_returns_heap_E)[1]fix a nodes h xs h'a
+ assume 0: "(\<And>h xs. heap_is_wellformed h \<Longrightarrow> type_wf h \<Longrightarrow> known_ptrs h
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs \<Longrightarrow> h \<turnstile> forall_M (append_child ptr) nodes \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> set nodes \<inter> set xs = {} \<Longrightarrow> h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs @ nodes)"
+ and 1: "heap_is_wellformed h"
+ and 2: "type_wf h"
+ and 3: "known_ptrs h"
+ and 4: "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs"
+ and 5: "h \<turnstile> append_child ptr a \<rightarrow>\<^sub>r ()"
+ and 6: "h \<turnstile> append_child ptr a \<rightarrow>\<^sub>h h'a"
+ and 7: "h'a \<turnstile> forall_M (append_child ptr) nodes \<rightarrow>\<^sub>h h'"
+ and 8: "a \<notin> set xs"
+ and 9: "set nodes \<inter> set xs = {}"
+ and 10: "a \<notin> set nodes"
+ and 11: "distinct nodes"
+ then have "h'a \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs @ [a]"
+ using append_child_children 6
+ using "1" "2" "3" "4" "8" by blast
+
+ moreover have "heap_is_wellformed h'a" and "type_wf h'a" and "known_ptrs h'a"
+ using insert_before_child_preserves 1 2 3 6 append_child_def
+ by metis+
+ moreover have "set nodes \<inter> set (xs @ [a]) = {}"
+ using 9 10
+ by auto
+ ultimately show "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r xs @ a # nodes"
+ using 0 7
+ by fastforce
+qed
+
+
+lemma append_child_for_all_on_no_children:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r []"
+ assumes "h \<turnstile> forall_M (append_child ptr) nodes \<rightarrow>\<^sub>h h'"
+ assumes "distinct nodes"
+ shows "h' \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r nodes"
+ using assms append_child_for_all_on_children
+ by force
+end
+
+interpretation i_append_child_wf?: l_append_child_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs set_child_nodes set_child_nodes_locs get_shadow_root get_shadow_root_locs
+ set_disconnected_nodes set_disconnected_nodes_locs get_tag_name get_tag_name_locs heap_is_wellformed
+ parent_child_rel get_parent get_parent_locs adopt_node adopt_node_locs get_owner_document insert_before
+ insert_before_locs append_child known_ptrs remove_child remove_child_locs get_ancestors_di
+ get_ancestors_di_locs adopt_node\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M adopt_node_locs\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document
+ get_disconnected_document_locs remove heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ by(auto simp add: l_append_child_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_append_child_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma append_child_wf_is_l_append_child_wf [instances]:
+ "l_append_child_wf type_wf known_ptr known_ptrs append_child heap_is_wellformed"
+ apply(auto simp add: l_append_child_wf_def l_append_child_wf_axioms_def instances)[1]
+ using append_child_heap_is_wellformed_preserved by fast+
+
+
+subsubsection \<open>to\_tree\_order\<close>
+
+interpretation i_to_tree_order_wf?: l_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf get_child_nodes
+ get_child_nodes_locs to_tree_order known_ptrs get_parent get_parent_locs heap_is_wellformed
+ parent_child_rel get_disconnected_nodes get_disconnected_nodes_locs
+ apply(auto simp add: l_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)[1]
+ done
+declare l_to_tree_order_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma to_tree_order_wf_is_l_to_tree_order_wf [instances]:
+ "l_to_tree_order_wf heap_is_wellformed parent_child_rel type_wf known_ptr known_ptrs
+to_tree_order get_parent get_child_nodes"
+ apply(auto simp add: l_to_tree_order_wf_def l_to_tree_order_wf_axioms_def instances)[1]
+ using to_tree_order_ok apply fast
+ using to_tree_order_ptrs_in_heap apply fast
+ using to_tree_order_parent_child_rel apply(fast, fast)
+ using to_tree_order_child2 apply blast
+ using to_tree_order_node_ptrs apply fast
+ using to_tree_order_child apply fast
+ using to_tree_order_ptr_in_result apply fast
+ using to_tree_order_parent apply fast
+ using to_tree_order_subset apply fast
+ done
+
+
+paragraph \<open>get\_root\_node\<close>
+
+interpretation i_to_tree_order_wf_get_root_node_wf?: l_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr type_wf known_ptrs heap_is_wellformed parent_child_rel get_child_nodes get_child_nodes_locs
+ get_disconnected_nodes get_disconnected_nodes_locs get_parent get_parent_locs get_ancestors
+ get_ancestors_locs get_root_node get_root_node_locs to_tree_order
+ by(auto simp add: l_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_to_tree_order_wf_get_root_node_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+lemma to_tree_order_wf_get_root_node_wf_is_l_to_tree_order_wf_get_root_node_wf [instances]:
+ "l_to_tree_order_wf_get_root_node_wf ShadowRootClass.type_wf ShadowRootClass.known_ptr
+ShadowRootClass.known_ptrs to_tree_order Shadow_DOM.get_root_node
+ Shadow_DOM.heap_is_wellformed"
+ apply(auto simp add: l_to_tree_order_wf_get_root_node_wf_def
+ l_to_tree_order_wf_get_root_node_wf_axioms_def instances)[1]
+ using to_tree_order_get_root_node apply fast
+ using to_tree_order_same_root apply fast
+ done
+
+
+subsubsection \<open>to\_tree\_order\_si\<close>
+
+locale l_to_tree_order_si_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_child_nodes +
+ l_get_parent_get_host_get_disconnected_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_to_tree_order_si\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+lemma to_tree_order_si_ok:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ and "ptr |\<in>| object_ptr_kinds h"
+ shows "h \<turnstile> ok (to_tree_order_si ptr)"
+proof(insert assms(1) assms(4), induct rule: heap_wellformed_induct_si)
+ case (step parent)
+ have "known_ptr parent"
+ using assms(2) local.known_ptrs_known_ptr step.prems
+ by blast
+ then show ?case
+ using step
+ using assms(1) assms(2) assms(3)
+ using local.heap_is_wellformed_children_in_heap local.get_shadow_root_shadow_root_ptr_in_heap
+ by(auto simp add: to_tree_order_si_def[of parent] intro: get_child_nodes_ok get_shadow_root_ok
+ intro!: bind_is_OK_pure_I map_M_pure_I bind_pure_I map_M_ok_I split: option.splits)
+qed
+end
+interpretation i_to_tree_order_si_wf?: l_to_tree_order_si_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ type_wf known_ptr get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document get_disconnected_document_locs known_ptrs get_parent get_parent_locs to_tree_order_si
+ by(auto simp add: l_to_tree_order_si_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_to_tree_order_si_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_assigned\_nodes\<close>
+
+lemma forall_M_small_big: "h \<turnstile> forall_M f xs \<rightarrow>\<^sub>h h' \<Longrightarrow> P h \<Longrightarrow>
+(\<And>h h' x. x \<in> set xs \<Longrightarrow> h \<turnstile> f x \<rightarrow>\<^sub>h h' \<Longrightarrow> P h \<Longrightarrow> P h') \<Longrightarrow> P h'"
+ by(induct xs arbitrary: h) (auto elim!: bind_returns_heap_E)
+
+locale l_assigned_nodes_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_assigned_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_heap_is_wellformed +
+ l_remove_child_wf2 +
+ l_append_child_wf +
+ l_remove_shadow_root_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+begin
+
+lemma assigned_nodes_distinct:
+ assumes "heap_is_wellformed h"
+ assumes "h \<turnstile> assigned_nodes slot \<rightarrow>\<^sub>r nodes"
+ shows "distinct nodes"
+proof -
+ have "\<And>ptr children. h \<turnstile> get_child_nodes ptr \<rightarrow>\<^sub>r children \<Longrightarrow> distinct children"
+ using assms(1) local.heap_is_wellformed_children_distinct by blast
+ then show ?thesis
+ using assms
+ apply(auto simp add: assigned_nodes_def elim!: bind_returns_result_E2 split: if_splits)[1]
+ by (simp add: filter_M_distinct)
+qed
+
+
+lemma flatten_dom_preserves:
+ assumes "heap_is_wellformed h" and "known_ptrs h" and "type_wf h"
+ assumes "h \<turnstile> flatten_dom \<rightarrow>\<^sub>h h'"
+ shows "heap_is_wellformed h'" and "known_ptrs h'" and "type_wf h'"
+proof -
+ obtain tups h2 element_ptrs shadow_root_ptrs where
+ "h \<turnstile> element_ptr_kinds_M \<rightarrow>\<^sub>r element_ptrs" and
+ tups: "h \<turnstile> map_filter_M2 (\<lambda>element_ptr. do {
+ tag \<leftarrow> get_tag_name element_ptr;
+ assigned_nodes \<leftarrow> assigned_nodes element_ptr;
+ (if tag = ''slot'' \<and> assigned_nodes \<noteq> []
+then return (Some (element_ptr, assigned_nodes)) else return None)}) element_ptrs \<rightarrow>\<^sub>r tups"
+ (is "h \<turnstile> map_filter_M2 ?f element_ptrs \<rightarrow>\<^sub>r tups") and
+ h2: "h \<turnstile> forall_M (\<lambda>(slot, assigned_nodes). do {
+ get_child_nodes (cast slot) \<bind> forall_M remove;
+ forall_M (append_child (cast slot)) assigned_nodes
+ }) tups \<rightarrow>\<^sub>h h2" and
+ "h2 \<turnstile> shadow_root_ptr_kinds_M \<rightarrow>\<^sub>r shadow_root_ptrs" and
+ h': "h2 \<turnstile> forall_M (\<lambda>shadow_root_ptr. do {
+ host \<leftarrow> get_host shadow_root_ptr;
+ get_child_nodes (cast host) \<bind> forall_M remove;
+ get_child_nodes (cast shadow_root_ptr) \<bind> forall_M (append_child (cast host));
+ remove_shadow_root host
+ }) shadow_root_ptrs \<rightarrow>\<^sub>h h'"
+ using \<open>h \<turnstile> flatten_dom \<rightarrow>\<^sub>h h'\<close>
+ apply(auto simp add: flatten_dom_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF ElementMonad.ptr_kinds_M_pure, rotated]
+ bind_returns_heap_E2[rotated, OF ShadowRootMonad.ptr_kinds_M_pure, rotated])[1]
+ apply(drule pure_returns_heap_eq)
+ by(auto intro!: map_filter_M2_pure bind_pure_I)
+ have "heap_is_wellformed h2 \<and> known_ptrs h2 \<and> type_wf h2"
+ using h2 \<open>heap_is_wellformed h\<close> \<open>known_ptrs h\<close> \<open>type_wf h\<close>
+ by(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ elim!: forall_M_small_big[where P = "\<lambda>h. heap_is_wellformed h \<and> known_ptrs h \<and> type_wf h", simplified]
+ intro: remove_preserves_known_ptrs remove_heap_is_wellformed_preserved remove_preserves_type_wf
+ append_child_preserves_known_ptrs append_child_heap_is_wellformed_preserved append_child_preserves_type_wf)
+ then
+ show "heap_is_wellformed h'" and "known_ptrs h'" and "type_wf h'"
+ using h'
+ by(auto elim!: bind_returns_heap_E bind_returns_heap_E2[rotated, OF get_host_pure, rotated] bind_returns_heap_E2[rotated, OF get_child_nodes_pure, rotated]
+ dest!: forall_M_small_big[where P = "\<lambda>h. heap_is_wellformed h \<and> known_ptrs h \<and> type_wf h", simplified]
+ intro: remove_preserves_known_ptrs remove_heap_is_wellformed_preserved remove_preserves_type_wf
+ append_child_preserves_known_ptrs append_child_heap_is_wellformed_preserved append_child_preserves_type_wf
+ remove_shadow_root_preserves
+ )
+qed
+end
+
+interpretation i_assigned_nodes_wf?: l_assigned_nodes_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ known_ptr assigned_nodes assigned_nodes_flatten flatten_dom get_child_nodes get_child_nodes_locs
+ get_tag_name get_tag_name_locs get_root_node get_root_node_locs get_host get_host_locs find_slot
+ assigned_slot remove insert_before insert_before_locs append_child remove_shadow_root
+ remove_shadow_root_locs type_wf get_shadow_root get_shadow_root_locs set_shadow_root
+ set_shadow_root_locs get_parent get_parent_locs to_tree_order heap_is_wellformed parent_child_rel
+ get_disconnected_nodes get_disconnected_nodes_locs known_ptrs remove_child remove_child_locs
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_document get_disconnected_document_locs
+ by(auto simp add: l_assigned_nodes_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_assigned_nodes_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>get\_shadow\_root\_safe\<close>
+
+locale l_get_shadow_root_safe_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs
+ known_ptr type_wf heap_is_wellformed parent_child_rel heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs +
+ l_type_wf type_wf +
+ l_get_shadow_root_safe\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf get_shadow_root_safe get_shadow_root_safe_locs get_shadow_root
+ get_shadow_root_locs get_mode get_mode_locs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root_safe :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_safe_locs :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_child_nodes :: "(_::linorder) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+begin
+
+
+end
+
+
+subsubsection \<open>create\_element\<close>
+
+locale l_create_element_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_disconnected_nodes type_wf get_disconnected_nodes get_disconnected_nodes_locs +
+ l_set_tag_name type_wf set_tag_name set_tag_name_locs +
+ l_create_element_defs create_element +
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs
+ get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs known_ptr type_wf
+ heap_is_wellformed parent_child_rel
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document
+ get_disconnected_document_locs +
+ l_new_element_get_disconnected_nodes get_disconnected_nodes get_disconnected_nodes_locs +
+ l_set_tag_name_get_disconnected_nodes type_wf set_tag_name set_tag_name_locs
+ get_disconnected_nodes get_disconnected_nodes_locs +
+ l_create_element\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+ set_disconnected_nodes_locs set_tag_name set_tag_name_locs type_wf
+ create_element known_ptr type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M +
+ l_new_element_get_child_nodes type_wf known_ptr get_child_nodes get_child_nodes_locs +
+ l_set_tag_name_get_child_nodes type_wf set_tag_name set_tag_name_locs known_ptr
+ get_child_nodes get_child_nodes_locs +
+ l_set_tag_name_get_tag_name type_wf get_tag_name get_tag_name_locs set_tag_name set_tag_name_locs +
+ l_new_element_get_tag_name type_wf get_tag_name get_tag_name_locs +
+ l_set_disconnected_nodes_get_child_nodes set_disconnected_nodes set_disconnected_nodes_locs
+ get_child_nodes get_child_nodes_locs +
+ l_set_disconnected_nodes_get_shadow_root set_disconnected_nodes set_disconnected_nodes_locs
+ get_shadow_root get_shadow_root_locs +
+ l_set_disconnected_nodes_get_tag_name type_wf set_disconnected_nodes set_disconnected_nodes_locs
+ get_tag_name get_tag_name_locs +
+ l_set_disconnected_nodes type_wf set_disconnected_nodes set_disconnected_nodes_locs +
+ l_set_disconnected_nodes_get_disconnected_nodes type_wf get_disconnected_nodes
+ get_disconnected_nodes_locs set_disconnected_nodes set_disconnected_nodes_locs +
+ l_new_element_get_shadow_root type_wf get_shadow_root get_shadow_root_locs +
+ l_set_tag_name_get_shadow_root type_wf set_tag_name set_tag_name_locs get_shadow_root get_shadow_root_locs +
+ l_new_element type_wf +
+ l_known_ptrs known_ptr known_ptrs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and set_tag_name :: "(_) element_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and create_element :: "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_document :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_disconnected_document_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+begin
+lemma create_element_preserves_wellformedness:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>h h'"
+ and "type_wf h"
+ and "known_ptrs h"
+ shows "heap_is_wellformed h'" and "type_wf h'" and "known_ptrs h'"
+proof -
+ obtain new_element_ptr h2 h3 disc_nodes_h3 where
+ new_element_ptr: "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr" and
+ h2: "h \<turnstile> new_element \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile> set_tag_name new_element_ptr tag \<rightarrow>\<^sub>h h3" and
+ disc_nodes_h3: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_element_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ by(auto simp add: create_element_def
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF CD.get_disconnected_nodes_pure, rotated] )
+ then have "h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr"
+ apply(auto simp add: create_element_def intro!: bind_returns_result_I)[1]
+ apply (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ apply (metis is_OK_returns_heap_E is_OK_returns_result_I CD.get_disconnected_nodes_pure
+ pure_returns_heap_eq)
+ by (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+
+ have "new_element_ptr \<notin> set |h \<turnstile> element_ptr_kinds_M|\<^sub>r"
+ using new_element_ptr ElementMonad.ptr_kinds_ptr_kinds_M h2
+ using new_element_ptr_not_in_heap by blast
+ then have "cast new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have "cast new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+
+ have object_ptr_kinds_eq_h: "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ using new_element_new_ptr h2 new_element_ptr by blast
+ then have node_ptr_kinds_eq_h: "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h |\<union>| {|new_element_ptr|}"
+ apply(simp add: element_ptr_kinds_def)
+ by force
+ have character_data_ptr_kinds_eq_h: "character_data_ptr_kinds h2 = character_data_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def character_data_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_tag_name_writes h3])
+ using set_tag_name_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+ then have element_ptr_kinds_eq_h2: "element_ptr_kinds h3 = element_ptr_kinds h2"
+ by(simp add: element_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+ then have element_ptr_kinds_eq_h3: "element_ptr_kinds h' = element_ptr_kinds h3"
+ by(simp add: element_ptr_kinds_def)
+
+ have "known_ptr (cast new_element_ptr)"
+ using \<open>h \<turnstile> create_element document_ptr tag \<rightarrow>\<^sub>r new_element_ptr\<close> local.create_element_known_ptr
+ by blast
+ then
+ have "known_ptrs h2"
+ using known_ptrs_new_ptr object_ptr_kinds_eq_h \<open>known_ptrs h\<close> h2
+ by blast
+ then
+ have "known_ptrs h3"
+ using known_ptrs_preserved object_ptr_kinds_eq_h2 by blast
+ then
+ show "known_ptrs h'"
+ using known_ptrs_preserved object_ptr_kinds_eq_h3 by blast
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ CD.get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_element_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads h2 get_child_nodes_new_element[rotated, OF new_element_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h: "\<And>ptr'. ptr' \<noteq> cast new_element_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have "h2 \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []"
+ using new_element_ptr h2 new_element_ptr_in_heap[OF h2 new_element_ptr]
+ new_element_is_element_ptr[OF new_element_ptr] new_element_no_child_nodes
+ by blast
+ have tag_name_eq_h:
+ "\<And>ptr' disc_nodes. ptr' \<noteq> new_element_ptr
+ \<Longrightarrow> h \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using get_tag_name_reads h2 get_tag_name_new_element[rotated, OF new_element_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by(blast)+
+ then have tag_name_eq2_h: "\<And>ptr'. ptr' \<noteq> new_element_ptr
+ \<Longrightarrow> |h \<turnstile> get_tag_name ptr'|\<^sub>r = |h2 \<turnstile> get_tag_name ptr'|\<^sub>r"
+ using select_result_eq by force
+ have "h2 \<turnstile> get_tag_name new_element_ptr \<rightarrow>\<^sub>r ''''"
+ using new_element_ptr h2 new_element_ptr_in_heap[OF h2 new_element_ptr]
+ new_element_is_element_ptr[OF new_element_ptr] new_element_empty_tag_name
+ by blast
+
+
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using CD.get_disconnected_nodes_reads h2 get_disconnected_nodes_new_element[OF new_element_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have disconnected_nodes_eq2_h:
+ "\<And>doc_ptr. |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads set_tag_name_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_tag_name_get_child_nodes)
+ then have children_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using CD.get_disconnected_nodes_reads set_tag_name_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_tag_name_get_disconnected_nodes)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have tag_name_eq_h2:
+ "\<And>ptr' disc_nodes. ptr' \<noteq> new_element_ptr
+ \<Longrightarrow> h2 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes"
+ apply(rule reads_writes_preserved[OF get_tag_name_reads set_tag_name_writes h3])
+ by (metis local.set_tag_name_get_tag_name_different_pointers)
+ then have tag_name_eq2_h2: "\<And>ptr'. ptr' \<noteq> new_element_ptr
+ \<Longrightarrow> |h2 \<turnstile> get_tag_name ptr'|\<^sub>r = |h3 \<turnstile> get_tag_name ptr'|\<^sub>r"
+ using select_result_eq by force
+ have "h2 \<turnstile> get_tag_name new_element_ptr \<rightarrow>\<^sub>r ''''"
+ using new_element_ptr h2 new_element_ptr_in_heap[OF h2 new_element_ptr]
+ new_element_is_element_ptr[OF new_element_ptr] new_element_empty_tag_name
+ by blast
+
+ have "type_wf h2"
+ using \<open>type_wf h\<close> new_element_types_preserved h2 by blast
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_tag_name_writes h3]
+ using set_tag_name_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then show "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_eq_h3:
+ "\<And>ptr' children. h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h3: "\<And>ptr'. |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h3:
+ "\<And>doc_ptr disc_nodes. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using CD.get_disconnected_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h3:
+ "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have tag_name_eq_h2:
+ "\<And>ptr' disc_nodes. ptr' \<noteq> new_element_ptr
+ \<Longrightarrow> h2 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes"
+ apply(rule reads_writes_preserved[OF get_tag_name_reads set_tag_name_writes h3])
+ by (metis local.set_tag_name_get_tag_name_different_pointers)
+ then have tag_name_eq2_h2: "\<And>ptr'. ptr' \<noteq> new_element_ptr
+ \<Longrightarrow> |h2 \<turnstile> get_tag_name ptr'|\<^sub>r = |h3 \<turnstile> get_tag_name ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have disc_nodes_document_ptr_h2: "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h2 disc_nodes_h3 by auto
+ then have disc_nodes_document_ptr_h: "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h by auto
+ then have "cast new_element_ptr \<notin> set disc_nodes_h3"
+ using \<open>heap_is_wellformed h\<close>
+ using \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ a_all_ptrs_in_heap_def heap_is_wellformed_def
+ using NodeMonad.ptr_kinds_ptr_kinds_M local.heap_is_wellformed_disc_nodes_in_heap by blast
+
+ have tag_name_eq_h3:
+ "\<And>ptr' disc_nodes. h3 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes"
+ apply(rule reads_writes_preserved[OF get_tag_name_reads set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_get_tag_name
+ by blast
+ then have tag_name_eq2_h3: "\<And>ptr'. |h3 \<turnstile> get_tag_name ptr'|\<^sub>r = |h' \<turnstile> get_tag_name ptr'|\<^sub>r"
+ using select_result_eq by force
+
+
+ have "acyclic (parent_child_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def CD.acyclic_heap_def)
+ also have "parent_child_rel h = parent_child_rel h2"
+ proof(auto simp add: CD.parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h2"
+ by (simp add: object_ptr_kinds_eq_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq_h \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting)
+ \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2_h empty_iff empty_set image_eqI select_result_I2)
+ qed
+ also have "\<dots> = parent_child_rel h3"
+ by(auto simp add: CD.parent_child_rel_def object_ptr_kinds_eq_h2 children_eq2_h2)
+ also have "\<dots> = parent_child_rel h'"
+ by(auto simp add: CD.parent_child_rel_def object_ptr_kinds_eq_h3 children_eq2_h3)
+ finally have "CD.a_acyclic_heap h'"
+ by (simp add: CD.acyclic_heap_def)
+
+ have "CD.a_all_ptrs_in_heap h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_all_ptrs_in_heap h2"
+ apply(auto simp add: CD.a_all_ptrs_in_heap_def)[1]
+ apply (metis \<open>known_ptrs h2\<close> \<open>parent_child_rel h = parent_child_rel h2\<close> \<open>type_wf h2\<close> assms(1)
+ assms(3) funion_iff CD.get_child_nodes_ok local.known_ptrs_known_ptr
+ local.parent_child_rel_child_in_heap CD.parent_child_rel_child_nodes2 node_ptr_kinds_commutes
+ node_ptr_kinds_eq_h returns_result_select_result)
+ by (metis (no_types, lifting) CD.get_child_nodes_ok CD.get_child_nodes_ptr_in_heap
+ \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close> assms(3) assms(4) children_eq_h
+ disconnected_nodes_eq2_h document_ptr_kinds_eq_h finite_set_in is_OK_returns_result_I
+ local.known_ptrs_known_ptr node_ptr_kinds_commutes returns_result_select_result subsetD)
+ then have "CD.a_all_ptrs_in_heap h3"
+ by (simp add: children_eq2_h2 disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ CD.a_all_ptrs_in_heap_def node_ptr_kinds_eq_h2 object_ptr_kinds_eq_h2)
+ then have "CD.a_all_ptrs_in_heap h'"
+ by (smt children_eq2_h3 disc_nodes_h3 disconnected_nodes_eq2_h3 document_ptr_kinds_eq_h3
+ element_ptr_kinds_commutes h' h2 local.CD.a_all_ptrs_in_heap_def
+ local.set_disconnected_nodes_get_disconnected_nodes new_element_ptr new_element_ptr_in_heap
+ node_ptr_kinds_eq_h2 node_ptr_kinds_eq_h3 notin_fset object_ptr_kinds_eq_h3 select_result_I2
+ set_ConsD subset_code(1))
+
+ have "\<And>p. p |\<in>| object_ptr_kinds h \<Longrightarrow> cast new_element_ptr \<notin> set |h \<turnstile> get_child_nodes p|\<^sub>r"
+ using \<open>heap_is_wellformed h\<close> \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ heap_is_wellformed_children_in_heap
+ by (meson NodeMonad.ptr_kinds_ptr_kinds_M CD.a_all_ptrs_in_heap_def assms(3) assms(4) fset_mp
+ fset_of_list_elem CD.get_child_nodes_ok known_ptrs_known_ptr returns_result_select_result)
+ then have "\<And>p. p |\<in>| object_ptr_kinds h2 \<Longrightarrow> cast new_element_ptr \<notin> set |h2 \<turnstile> get_child_nodes p|\<^sub>r"
+ using children_eq2_h
+ apply(auto simp add: object_ptr_kinds_eq_h)[1]
+ using \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr) \<rightarrow>\<^sub>r []\<close> apply auto[1]
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>)
+ then have "\<And>p. p |\<in>| object_ptr_kinds h3 \<Longrightarrow> cast new_element_ptr \<notin> set |h3 \<turnstile> get_child_nodes p|\<^sub>r"
+ using object_ptr_kinds_eq_h2 children_eq2_h2 by auto
+ then have new_element_ptr_not_in_any_children:
+ "\<And>p. p |\<in>| object_ptr_kinds h' \<Longrightarrow> cast new_element_ptr \<notin> set |h' \<turnstile> get_child_nodes p|\<^sub>r"
+ using object_ptr_kinds_eq_h3 children_eq2_h3 by auto
+
+ have "CD.a_distinct_lists h"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: CD.heap_is_wellformed_def heap_is_wellformed_def)
+ then have "CD.a_distinct_lists h2"
+ using \<open>h2 \<turnstile> get_child_nodes (cast new_element_ptr) \<rightarrow>\<^sub>r []\<close>
+ apply(auto simp add: CD.a_distinct_lists_def object_ptr_kinds_eq_h document_ptr_kinds_eq_h
+ disconnected_nodes_eq2_h intro!: distinct_concat_map_I)[1]
+ apply (metis distinct_sorted_list_of_set finite_fset sorted_list_of_set_insert)
+ apply(case_tac "x=cast new_element_ptr")
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply (metis IntI assms(1) assms(3) assms(4) empty_iff CD.get_child_nodes_ok
+ local.heap_is_wellformed_one_parent local.known_ptrs_known_ptr returns_result_select_result)
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ by (metis \<open> CD.a_distinct_lists h\<close> \<open>type_wf h2\<close> disconnected_nodes_eq_h document_ptr_kinds_eq_h
+ CD.distinct_lists_no_parent get_disconnected_nodes_ok returns_result_select_result)
+
+ then have " CD.a_distinct_lists h3"
+ by(auto simp add: CD.a_distinct_lists_def disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ children_eq2_h2 object_ptr_kinds_eq_h2)
+ then have " CD.a_distinct_lists h'"
+ proof(auto simp add: CD.a_distinct_lists_def disconnected_nodes_eq2_h3 children_eq2_h3
+ object_ptr_kinds_eq_h3 document_ptr_kinds_eq_h3
+ intro!: distinct_concat_map_I)[1]
+ fix x
+ assume "distinct (concat (map (\<lambda>document_ptr. |h3 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and "x |\<in>| document_ptr_kinds h3"
+ then show "distinct |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using document_ptr_kinds_eq_h3 disconnected_nodes_eq_h3 h' set_disconnected_nodes_get_disconnected_nodes
+ by (metis (no_types, lifting) \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set disc_nodes_h3\<close>
+ \<open> CD.a_distinct_lists h3\<close> \<open>type_wf h'\<close> disc_nodes_h3 distinct.simps(2)
+ CD.distinct_lists_disconnected_nodes get_disconnected_nodes_ok returns_result_eq
+ returns_result_select_result)
+ next
+ fix x y xa
+ assume "distinct (concat (map (\<lambda>document_ptr. |h3 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and "x |\<in>| document_ptr_kinds h3"
+ and "y |\<in>| document_ptr_kinds h3"
+ and "x \<noteq> y"
+ and "xa \<in> set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ and "xa \<in> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ moreover have "set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h3 \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ using calculation by(auto dest: distinct_concat_map_E(1))
+ ultimately show "False"
+ apply(-)
+ apply(cases "x = document_ptr")
+ apply(smt NodeMonad.ptr_kinds_ptr_kinds_M \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close> \<open>CD.a_all_ptrs_in_heap h\<close>
+ disc_nodes_h3 disconnected_nodes_eq2_h disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ disjoint_iff_not_equal document_ptr_kinds_eq_h document_ptr_kinds_eq_h2 finite_set_in h'
+ set_disconnected_nodes_get_disconnected_nodes
+ CD.a_all_ptrs_in_heap_def
+ select_result_I2 set_ConsD subsetD)
+ by (smt NodeMonad.ptr_kinds_ptr_kinds_M \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close> \<open>CD.a_all_ptrs_in_heap h\<close>
+ disc_nodes_document_ptr_h2 disconnected_nodes_eq2_h disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ disjoint_iff_not_equal document_ptr_kinds_eq_h document_ptr_kinds_eq_h2 finite_set_in h'
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ CD.a_all_ptrs_in_heap_def local.l_set_disconnected_nodes_get_disconnected_nodes_axioms
+ select_result_I2 set_ConsD subsetD)
+ next
+ fix x xa xb
+ assume 2: "(\<Union>x\<in>fset (object_ptr_kinds h3). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h3). set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 3: "xa |\<in>| object_ptr_kinds h3"
+ and 4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 5: "xb |\<in>| document_ptr_kinds h3"
+ and 6: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ show "False"
+ using disc_nodes_document_ptr_h disconnected_nodes_eq2_h3
+ apply -
+ apply(cases "xb = document_ptr")
+ apply (metis (no_types, hide_lams) "3" "4" "6"
+ \<open>\<And>p. p |\<in>| object_ptr_kinds h3
+ \<Longrightarrow> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h3 \<turnstile> get_child_nodes p|\<^sub>r\<close>
+ \<open> CD.a_distinct_lists h3\<close> children_eq2_h3 disc_nodes_h3 CD.distinct_lists_no_parent h'
+ select_result_I2 set_ConsD set_disconnected_nodes_get_disconnected_nodes)
+ by (metis "3" "4" "5" "6" \<open> CD.a_distinct_lists h3\<close> \<open>type_wf h3\<close> children_eq2_h3
+ CD.distinct_lists_no_parent get_disconnected_nodes_ok returns_result_select_result)
+ qed
+
+ have "CD.a_owner_document_valid h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_owner_document_valid h'"
+ using disc_nodes_h3 \<open>document_ptr |\<in>| document_ptr_kinds h\<close>
+ apply(auto simp add: CD.a_owner_document_valid_def)[1]
+ apply(auto simp add: object_ptr_kinds_eq_h object_ptr_kinds_eq_h3 )[1]
+ apply(auto simp add: object_ptr_kinds_eq_h2)[1]
+ apply(auto simp add: document_ptr_kinds_eq_h document_ptr_kinds_eq_h3 )[1]
+ apply(auto simp add: document_ptr_kinds_eq_h2)[1]
+ apply(auto simp add: node_ptr_kinds_eq_h node_ptr_kinds_eq_h3 )[1]
+ apply(auto simp add: node_ptr_kinds_eq_h2 node_ptr_kinds_eq_h )[1]
+ apply(auto simp add: children_eq2_h2[symmetric] children_eq2_h3[symmetric]
+ disconnected_nodes_eq2_h disconnected_nodes_eq2_h2
+ disconnected_nodes_eq2_h3)[1]
+ apply (metis (no_types, lifting) document_ptr_kinds_eq_h h' list.set_intros(1)
+ local.set_disconnected_nodes_get_disconnected_nodes select_result_I2)
+ apply(simp add: object_ptr_kinds_eq_h)
+ by(metis (no_types, lifting) NodeMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close> children_eq2_h children_eq2_h2
+ children_eq2_h3 disconnected_nodes_eq2_h disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ document_ptr_kinds_eq_h finite_set_in h'
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ list.set_intros(2) local.l_set_disconnected_nodes_get_disconnected_nodes_axioms node_ptr_kinds_commutes
+ select_result_I2)
+
+ have "CD.a_heap_is_wellformed h'"
+ using \<open>CD.a_acyclic_heap h'\<close> \<open>CD.a_all_ptrs_in_heap h'\<close> \<open>CD.a_distinct_lists h'\<close> \<open>CD.a_owner_document_valid h'\<close>
+ by(simp add: CD.a_heap_is_wellformed_def)
+
+
+
+
+
+ have shadow_root_ptr_kinds_eq_h: "shadow_root_ptr_kinds h2 = shadow_root_ptr_kinds h"
+ using document_ptr_kinds_eq_h
+ by(auto simp add: shadow_root_ptr_kinds_def)
+ have shadow_root_ptr_kinds_eq_h2: "shadow_root_ptr_kinds h3 = shadow_root_ptr_kinds h2"
+ using document_ptr_kinds_eq_h2
+ by(auto simp add: shadow_root_ptr_kinds_def)
+ have shadow_root_ptr_kinds_eq_h3: "shadow_root_ptr_kinds h' = shadow_root_ptr_kinds h3"
+ using document_ptr_kinds_eq_h3
+ by(auto simp add: shadow_root_ptr_kinds_def)
+
+
+
+ have shadow_root_eq_h: "\<And>element_ptr shadow_root_opt. element_ptr \<noteq> new_element_ptr
+ \<Longrightarrow> h \<turnstile> get_shadow_root element_ptr \<rightarrow>\<^sub>r shadow_root_opt = h2 \<turnstile> get_shadow_root element_ptr \<rightarrow>\<^sub>r shadow_root_opt"
+ proof -
+ fix element_ptr shadow_root_opt
+ assume "element_ptr \<noteq> new_element_ptr "
+ have "\<forall>P \<in> get_shadow_root_locs element_ptr. P h h2"
+ using get_shadow_root_new_element new_element_ptr h2
+ using \<open>element_ptr \<noteq> new_element_ptr\<close> by blast
+ then
+ have "preserved (get_shadow_root element_ptr) h h2"
+ using get_shadow_root_new_element[rotated, OF new_element_ptr h2]
+ using get_shadow_root_reads
+ by(simp add: reads_def)
+ then show "h \<turnstile> get_shadow_root element_ptr \<rightarrow>\<^sub>r shadow_root_opt = h2 \<turnstile> get_shadow_root element_ptr \<rightarrow>\<^sub>r shadow_root_opt"
+ by (simp add: preserved_def)
+ qed
+ have shadow_root_none: "h2 \<turnstile> get_shadow_root (new_element_ptr) \<rightarrow>\<^sub>r None"
+ using new_element_ptr h2 new_element_ptr_in_heap[OF h2 new_element_ptr]
+ new_element_is_element_ptr[OF new_element_ptr] new_element_no_shadow_root
+ by blast
+
+ have shadow_root_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children"
+ using get_shadow_root_reads set_tag_name_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_tag_name_get_shadow_root)
+ have shadow_root_eq_h3:
+ "\<And>ptr' children. h3 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children"
+ using get_shadow_root_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ using set_disconnected_nodes_get_shadow_root
+ by(auto simp add: set_disconnected_nodes_get_shadow_root)
+
+
+ have "a_all_ptrs_in_heap h"
+ by (simp add: assms(1) local.a_all_ptrs_in_heap_def local.get_shadow_root_shadow_root_ptr_in_heap)
+ then have "a_all_ptrs_in_heap h2"
+ apply(auto simp add: a_all_ptrs_in_heap_def shadow_root_ptr_kinds_eq_h)[1]
+ using returns_result_eq shadow_root_eq_h shadow_root_none by fastforce
+ then have "a_all_ptrs_in_heap h3"
+ apply(auto simp add: a_all_ptrs_in_heap_def shadow_root_ptr_kinds_eq_h2)[1]
+ using shadow_root_eq_h2 by blast
+ then have "a_all_ptrs_in_heap h'"
+ apply(auto simp add: a_all_ptrs_in_heap_def shadow_root_ptr_kinds_eq_h3)[1]
+ by (simp add: shadow_root_eq_h3)
+
+ have "a_distinct_lists h"
+ using assms(1)
+ by (simp add: heap_is_wellformed_def)
+ then have "a_distinct_lists h2"
+ apply(auto simp add: a_distinct_lists_def element_ptr_kinds_eq_h)[1]
+ apply(auto simp add: distinct_insort intro!: distinct_concat_map_I split: option.splits)[1]
+ apply(case_tac "x = new_element_ptr")
+ using shadow_root_none apply auto[1]
+ using shadow_root_eq_h
+ by (smt Diff_empty Diff_insert0 ElementMonad.ptr_kinds_M_ptr_kinds
+ ElementMonad.ptr_kinds_ptr_kinds_M assms(1) assms(3) finite_set_in h2 insort_split
+ local.get_shadow_root_ok local.shadow_root_same_host new_element_ptr new_element_ptr_not_in_heap
+ option.distinct(1) returns_result_select_result select_result_I2 shadow_root_none)
+ then have "a_distinct_lists h3"
+ by(auto simp add: a_distinct_lists_def element_ptr_kinds_eq_h2 select_result_eq[OF shadow_root_eq_h2])
+ then have "a_distinct_lists h'"
+ by(auto simp add: a_distinct_lists_def element_ptr_kinds_eq_h3 select_result_eq[OF shadow_root_eq_h3])
+
+
+ have "a_shadow_root_valid h"
+ using assms(1)
+ by (simp add: heap_is_wellformed_def)
+ then have "a_shadow_root_valid h2"
+ proof (unfold a_shadow_root_valid_def; safe)
+ fix shadow_root_ptr
+ assume "\<forall>shadow_root_ptr\<in>fset (shadow_root_ptr_kinds h). \<exists>host\<in>fset (element_ptr_kinds h).
+|h \<turnstile> get_tag_name host|\<^sub>r \<in> safe_shadow_root_element_types \<and> |h \<turnstile> get_shadow_root host|\<^sub>r = Some shadow_root_ptr"
+ assume "shadow_root_ptr \<in> fset (shadow_root_ptr_kinds h2)"
+
+ obtain previous_host where
+ "previous_host \<in> fset (element_ptr_kinds h)" and
+ "|h \<turnstile> get_tag_name previous_host|\<^sub>r \<in> safe_shadow_root_element_types" and
+ "|h \<turnstile> get_shadow_root previous_host|\<^sub>r = Some shadow_root_ptr"
+ by (metis \<open>local.a_shadow_root_valid h\<close> \<open>shadow_root_ptr \<in> fset (shadow_root_ptr_kinds h2)\<close>
+ local.a_shadow_root_valid_def shadow_root_ptr_kinds_eq_h)
+ moreover have "previous_host \<noteq> new_element_ptr"
+ using calculation(1) h2 new_element_ptr new_element_ptr_not_in_heap by auto
+ ultimately have "|h2 \<turnstile> get_tag_name previous_host|\<^sub>r \<in> safe_shadow_root_element_types" and
+ "|h2 \<turnstile> get_shadow_root previous_host|\<^sub>r = Some shadow_root_ptr"
+ using shadow_root_eq_h
+ apply (simp add: tag_name_eq2_h)
+ by (metis \<open>previous_host \<noteq> new_element_ptr\<close> \<open>|h \<turnstile> get_shadow_root previous_host|\<^sub>r = Some shadow_root_ptr\<close>
+ select_result_eq shadow_root_eq_h)
+ then
+ show "\<exists>host\<in>fset (element_ptr_kinds h2). |h2 \<turnstile> get_tag_name host|\<^sub>r \<in> safe_shadow_root_element_types \<and>
+|h2 \<turnstile> get_shadow_root host|\<^sub>r = Some shadow_root_ptr"
+ by (meson \<open>previous_host \<in> fset (element_ptr_kinds h)\<close> \<open>previous_host \<noteq> new_element_ptr\<close> assms(3)
+ local.get_shadow_root_ok local.get_shadow_root_ptr_in_heap notin_fset returns_result_select_result shadow_root_eq_h)
+ qed
+ then have "a_shadow_root_valid h3"
+ proof (unfold a_shadow_root_valid_def; safe)
+ fix shadow_root_ptr
+ assume "\<forall>shadow_root_ptr\<in>fset (shadow_root_ptr_kinds h2). \<exists>host\<in>fset (element_ptr_kinds h2).
+|h2 \<turnstile> get_tag_name host|\<^sub>r \<in> safe_shadow_root_element_types \<and> |h2 \<turnstile> get_shadow_root host|\<^sub>r = Some shadow_root_ptr"
+ assume "shadow_root_ptr \<in> fset (shadow_root_ptr_kinds h3)"
+
+ obtain previous_host where
+ "previous_host \<in> fset (element_ptr_kinds h2)" and
+ "|h2 \<turnstile> get_tag_name previous_host|\<^sub>r \<in> safe_shadow_root_element_types" and
+ "|h2 \<turnstile> get_shadow_root previous_host|\<^sub>r = Some shadow_root_ptr"
+ by (metis \<open>local.a_shadow_root_valid h2\<close> \<open>shadow_root_ptr \<in> fset (shadow_root_ptr_kinds h3)\<close>
+ local.a_shadow_root_valid_def shadow_root_ptr_kinds_eq_h2)
+ moreover have "previous_host \<noteq> new_element_ptr"
+ using calculation(1) h3 new_element_ptr new_element_ptr_not_in_heap
+ using calculation(3) shadow_root_none by auto
+ ultimately have "|h2 \<turnstile> get_tag_name previous_host|\<^sub>r \<in> safe_shadow_root_element_types" and
+ "|h2 \<turnstile> get_shadow_root previous_host|\<^sub>r = Some shadow_root_ptr"
+ using shadow_root_eq_h2
+ apply (simp add: tag_name_eq2_h2)
+ by (metis \<open>previous_host \<noteq> new_element_ptr\<close> \<open>|h2 \<turnstile> get_shadow_root previous_host|\<^sub>r = Some shadow_root_ptr\<close>
+ select_result_eq shadow_root_eq_h)
+ then
+ show "\<exists>host\<in>fset (element_ptr_kinds h3). |h3 \<turnstile> get_tag_name host|\<^sub>r \<in> safe_shadow_root_element_types \<and>
+|h3 \<turnstile> get_shadow_root host|\<^sub>r = Some shadow_root_ptr"
+ by (smt \<open>previous_host \<in> fset (element_ptr_kinds h2)\<close> \<open>previous_host \<noteq> new_element_ptr\<close> \<open>type_wf h2\<close>
+ \<open>type_wf h3\<close> element_ptr_kinds_eq_h2 finite_set_in local.get_shadow_root_ok returns_result_eq
+ returns_result_select_result shadow_root_eq_h2 tag_name_eq2_h2)
+ qed
+ then have "a_shadow_root_valid h'"
+ apply(auto simp add: a_shadow_root_valid_def element_ptr_kinds_eq_h3 shadow_root_eq_h3
+ shadow_root_ptr_kinds_eq_h3 tag_name_eq2_h3)[1]
+ by (smt \<open>type_wf h3\<close> finite_set_in local.get_shadow_root_ok returns_result_select_result
+ select_result_I2 shadow_root_eq_h3)
+
+
+
+ have "a_host_shadow_root_rel h = a_host_shadow_root_rel h2"
+ apply(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h shadow_root_eq_h)[1]
+ apply (smt assms(3) case_prod_conv h2 image_iff local.get_shadow_root_ok mem_Collect_eq new_element_ptr
+ new_element_ptr_not_in_heap returns_result_select_result select_result_I2 shadow_root_eq_h)
+ using shadow_root_none apply auto[1]
+ apply (metis (no_types, lifting) Collect_cong assms(3) case_prodE case_prodI h2 host_shadow_root_rel_def
+ i_get_parent_get_host_get_disconnected_document_wf.a_host_shadow_root_rel_shadow_root
+ local.a_host_shadow_root_rel_def local.get_shadow_root_impl local.get_shadow_root_ok new_element_ptr
+ new_element_ptr_not_in_heap returns_result_select_result select_result_I2 shadow_root_eq_h)
+ done
+ have "a_host_shadow_root_rel h2 = a_host_shadow_root_rel h3"
+ apply(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h2 shadow_root_eq_h2)[1]
+ apply (smt Collect_cong \<open>type_wf h2\<close> case_prodE case_prodI element_ptr_kinds_eq_h2 host_shadow_root_rel_def
+ i_get_root_node_si_wf.a_host_shadow_root_rel_shadow_root local.a_host_shadow_root_rel_def local.get_shadow_root_impl
+ local.get_shadow_root_ok returns_result_select_result shadow_root_eq_h2)
+ by (metis (no_types, lifting) Collect_cong \<open>type_wf h3\<close> case_prodI2 case_prod_conv element_ptr_kinds_eq_h2
+ host_shadow_root_rel_def i_get_root_node_si_wf.a_host_shadow_root_rel_shadow_root local.a_host_shadow_root_rel_def
+ local.get_shadow_root_impl local.get_shadow_root_ok returns_result_select_result shadow_root_eq_h2)
+ have "a_host_shadow_root_rel h3 = a_host_shadow_root_rel h'"
+ apply(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h2 shadow_root_eq_h2)[1]
+ apply (smt Collect_cong Shadow_DOM.a_host_shadow_root_rel_def \<open>type_wf h3\<close> case_prodD case_prodI2
+ element_ptr_kinds_eq_h2 i_get_root_node_si_wf.a_host_shadow_root_rel_shadow_root local.get_shadow_root_impl
+ local.get_shadow_root_ok returns_result_select_result shadow_root_eq_h3)
+ apply (smt Collect_cong \<open>type_wf h'\<close> case_prodE case_prodI element_ptr_kinds_eq_h2 host_shadow_root_rel_def
+ i_get_root_node_si_wf.a_host_shadow_root_rel_shadow_root l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_defs.a_host_shadow_root_rel_def
+ local.get_shadow_root_impl local.get_shadow_root_ok returns_result_select_result shadow_root_eq_h3)
+ done
+
+
+ have "a_ptr_disconnected_node_rel h = a_ptr_disconnected_node_rel h2"
+ by(simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h disconnected_nodes_eq2_h)
+ have "a_ptr_disconnected_node_rel h2 = a_ptr_disconnected_node_rel h3"
+ by(simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h2 disconnected_nodes_eq2_h2)
+
+ have "h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast new_element_ptr # disc_nodes_h3"
+ using h' local.set_disconnected_nodes_get_disconnected_nodes by auto
+ have " document_ptr |\<in>| document_ptr_kinds h3"
+ by (simp add: \<open>document_ptr |\<in>| document_ptr_kinds h\<close> document_ptr_kinds_eq_h document_ptr_kinds_eq_h2)
+ have "cast new_element_ptr \<in> set |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ using \<open>h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr # disc_nodes_h3\<close>
+ by auto
+
+ have "a_ptr_disconnected_node_rel h' = {(cast document_ptr, cast new_element_ptr)} \<union> a_ptr_disconnected_node_rel h3"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h3 disconnected_nodes_eq2_h3)[1]
+ apply(case_tac "aa = document_ptr")
+ using disc_nodes_h3 h' \<open>h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast new_element_ptr # disc_nodes_h3\<close>
+ apply(auto)[1]
+ using disconnected_nodes_eq2_h3 apply auto[1]
+ using \<open>h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast new_element_ptr # disc_nodes_h3\<close>
+ using \<open>cast new_element_ptr \<in> set |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r\<close>
+ using \<open>document_ptr |\<in>| document_ptr_kinds h3\<close> apply auto[1]
+ apply(case_tac "document_ptr = aa")
+ using \<open>h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr # disc_nodes_h3\<close> disc_nodes_h3
+ apply auto[1]
+ using disconnected_nodes_eq_h3[THEN select_result_eq, simplified] by auto
+
+ have "acyclic (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def)
+ have "parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h =
+parent_child_rel h2 \<union> a_host_shadow_root_rel h2 \<union> a_ptr_disconnected_node_rel h2"
+ using \<open>local.a_host_shadow_root_rel h = local.a_host_shadow_root_rel h2\<close>
+ \<open>local.a_ptr_disconnected_node_rel h = local.a_ptr_disconnected_node_rel h2\<close> \<open>parent_child_rel h = parent_child_rel h2\<close>
+ by auto
+ have "parent_child_rel h2 \<union> a_host_shadow_root_rel h2 \<union> a_ptr_disconnected_node_rel h2 =
+parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3"
+ using \<open>local.a_host_shadow_root_rel h2 = local.a_host_shadow_root_rel h3\<close>
+ \<open>local.a_ptr_disconnected_node_rel h2 = local.a_ptr_disconnected_node_rel h3\<close> \<open>parent_child_rel h2 = parent_child_rel h3\<close>
+ by auto
+ have "parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h' =
+{(cast document_ptr, cast new_element_ptr)} \<union> parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3"
+ by (simp add: \<open>local.a_host_shadow_root_rel h3 = local.a_host_shadow_root_rel h'\<close>
+ \<open>local.a_ptr_disconnected_node_rel h' = {(cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr, cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr)} \<union>
+local.a_ptr_disconnected_node_rel h3\<close> \<open>parent_child_rel h3 = parent_child_rel h'\<close>)
+
+ have "\<And>a b. (a, b) \<in> parent_child_rel h3 \<Longrightarrow> a \<noteq> cast new_element_ptr"
+ using CD.parent_child_rel_parent_in_heap \<open>parent_child_rel h = parent_child_rel h2\<close>
+ \<open>parent_child_rel h2 = parent_child_rel h3\<close> element_ptr_kinds_commutes h2 new_element_ptr
+ new_element_ptr_not_in_heap node_ptr_kinds_commutes
+ by blast
+ moreover
+ have "\<And>a b. (a, b) \<in> a_host_shadow_root_rel h3 \<Longrightarrow> a \<noteq> cast new_element_ptr"
+ using shadow_root_eq_h2 shadow_root_none
+ by(auto simp add: a_host_shadow_root_rel_def)
+ moreover
+ have "\<And>a b. (a, b) \<in> a_ptr_disconnected_node_rel h3 \<Longrightarrow> a \<noteq> cast new_element_ptr"
+ by(auto simp add: a_ptr_disconnected_node_rel_def)
+ moreover
+ have "cast new_element_ptr \<notin> {x. (x, cast document_ptr) \<in>
+(parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3)\<^sup>*}"
+ by (smt Un_iff \<open>\<And>b a. (a, b) \<in> local.a_host_shadow_root_rel h3 \<Longrightarrow>
+a \<noteq> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr\<close> \<open>\<And>b a. (a, b) \<in> local.a_ptr_disconnected_node_rel h3 \<Longrightarrow>
+a \<noteq> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr\<close> \<open>\<And>b a. (a, b) \<in> parent_child_rel h3 \<Longrightarrow>
+a \<noteq> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_element_ptr\<close> cast_document_ptr_not_node_ptr(1) converse_rtranclE mem_Collect_eq)
+ moreover
+ have "acyclic (parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3)"
+ using \<open>acyclic (parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> local.a_ptr_disconnected_node_rel h)\<close>
+ \<open>parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> local.a_ptr_disconnected_node_rel h =
+parent_child_rel h2 \<union> local.a_host_shadow_root_rel h2 \<union> local.a_ptr_disconnected_node_rel h2\<close>
+ \<open>parent_child_rel h2 \<union> local.a_host_shadow_root_rel h2 \<union> local.a_ptr_disconnected_node_rel h2 =
+parent_child_rel h3 \<union> local.a_host_shadow_root_rel h3 \<union> local.a_ptr_disconnected_node_rel h3\<close>
+ by auto
+ ultimately have "acyclic (parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h')"
+ by(simp add: \<open>parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h' =
+{(cast document_ptr, cast new_element_ptr)} \<union> parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3\<close>)
+
+
+ show " heap_is_wellformed h' "
+ using \<open>acyclic (parent_child_rel h' \<union> local.a_host_shadow_root_rel h' \<union> local.a_ptr_disconnected_node_rel h')\<close>
+ by(simp add: heap_is_wellformed_def CD.heap_is_wellformed_impl \<open>local.CD.a_heap_is_wellformed h'\<close>
+ \<open>local.a_all_ptrs_in_heap h'\<close> \<open>local.a_distinct_lists h'\<close> \<open>local.a_shadow_root_valid h'\<close>)
+qed
+end
+
+interpretation i_create_element_wf?: l_create_element_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr known_ptrs type_wf
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs heap_is_wellformed
+ parent_child_rel set_tag_name set_tag_name_locs set_disconnected_nodes
+ set_disconnected_nodes_locs create_element get_shadow_root get_shadow_root_locs get_tag_name
+ get_tag_name_locs heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document
+ get_disconnected_document_locs DocumentClass.known_ptr DocumentClass.type_wf
+ by(auto simp add: l_create_element_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_create_element_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+
+subsubsection \<open>create\_character\_data\<close>
+
+locale l_create_character_data_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_disconnected_nodes type_wf get_disconnected_nodes get_disconnected_nodes_locs +
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs known_ptr type_wf
+ heap_is_wellformed parent_child_rel
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document
+ get_disconnected_document_locs +
+ l_create_character_data\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs
+ set_disconnected_nodes set_disconnected_nodes_locs set_val set_val_locs create_character_data known_ptr
+ type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ + l_new_character_data_get_disconnected_nodes
+ get_disconnected_nodes get_disconnected_nodes_locs
+
++ l_set_val_get_disconnected_nodes
+type_wf set_val set_val_locs get_disconnected_nodes get_disconnected_nodes_locs
++ l_new_character_data_get_child_nodes
+type_wf known_ptr get_child_nodes get_child_nodes_locs
++ l_set_val_get_child_nodes
+type_wf set_val set_val_locs known_ptr get_child_nodes get_child_nodes_locs
++ l_set_disconnected_nodes_get_child_nodes
+set_disconnected_nodes set_disconnected_nodes_locs get_child_nodes get_child_nodes_locs
++ l_set_disconnected_nodes
+type_wf set_disconnected_nodes set_disconnected_nodes_locs
++ l_set_disconnected_nodes_get_disconnected_nodes
+type_wf get_disconnected_nodes get_disconnected_nodes_locs set_disconnected_nodes
+set_disconnected_nodes_locs
++ l_set_val_get_shadow_root type_wf set_val set_val_locs get_shadow_root get_shadow_root_locs
++ l_set_disconnected_nodes_get_shadow_root set_disconnected_nodes set_disconnected_nodes_locs
+get_shadow_root get_shadow_root_locs
++ l_new_character_data_get_tag_name
+get_tag_name get_tag_name_locs
++ l_set_val_get_tag_name type_wf set_val set_val_locs get_tag_name get_tag_name_locs
++ l_get_tag_name type_wf get_tag_name get_tag_name_locs
++ l_set_disconnected_nodes_get_tag_name type_wf set_disconnected_nodes set_disconnected_nodes_locs
+get_tag_name get_tag_name_locs
++ l_new_character_data
+type_wf
++ l_known_ptrs
+known_ptr known_ptrs
+for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and set_tag_name :: "(_) element_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and create_element :: "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_document :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_disconnected_document_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_val :: "(_) character_data_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_val_locs :: "(_) character_data_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and create_character_data ::
+ "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) character_data_ptr) prog"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+begin
+lemma create_character_data_preserves_wellformedness:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>h h'"
+ and "type_wf h"
+ and "known_ptrs h"
+ shows "heap_is_wellformed h'" and "type_wf h'" and "known_ptrs h'"
+proof -
+ obtain new_character_data_ptr h2 h3 disc_nodes_h3 where
+ new_character_data_ptr: "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr" and
+ h2: "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h2" and
+ h3: "h2 \<turnstile> set_val new_character_data_ptr text \<rightarrow>\<^sub>h h3" and
+ disc_nodes_h3: "h3 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3" and
+ h': "h3 \<turnstile> set_disconnected_nodes document_ptr (cast new_character_data_ptr # disc_nodes_h3) \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ by(auto simp add: CD.create_character_data_def
+ elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF CD.get_disconnected_nodes_pure, rotated] )
+ then have "h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr"
+ apply(auto simp add: CD.create_character_data_def intro!: bind_returns_result_I)[1]
+ apply (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+ apply (metis is_OK_returns_heap_E is_OK_returns_result_I local.CD.get_disconnected_nodes_pure
+ pure_returns_heap_eq)
+ by (metis is_OK_returns_heap_I is_OK_returns_result_E old.unit.exhaust)
+
+
+ have "new_character_data_ptr \<notin> set |h \<turnstile> character_data_ptr_kinds_M|\<^sub>r"
+ using new_character_data_ptr CharacterDataMonad.ptr_kinds_ptr_kinds_M h2
+ using new_character_data_ptr_not_in_heap by blast
+ then have "cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have "cast new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+
+
+
+ have object_ptr_kinds_eq_h:
+ "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using new_character_data_new_ptr h2 new_character_data_ptr by blast
+ then have node_ptr_kinds_eq_h:
+ "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have character_data_ptr_kinds_eq_h:
+ "character_data_ptr_kinds h2 = character_data_ptr_kinds h |\<union>| {|new_character_data_ptr|}"
+ apply(simp add: character_data_ptr_kinds_def)
+ by force
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF CD.set_val_writes h3])
+ using CD.set_val_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+ have "known_ptr (cast new_character_data_ptr)"
+ using \<open>h \<turnstile> create_character_data document_ptr text \<rightarrow>\<^sub>r new_character_data_ptr\<close>
+ local.create_character_data_known_ptr by blast
+ then
+ have "known_ptrs h2"
+ using known_ptrs_new_ptr object_ptr_kinds_eq_h \<open>known_ptrs h\<close> h2
+ by blast
+ then
+ have "known_ptrs h3"
+ using known_ptrs_preserved object_ptr_kinds_eq_h2 by blast
+ then
+ show "known_ptrs h'"
+ using known_ptrs_preserved object_ptr_kinds_eq_h3 by blast
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ CD.get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads h2 get_child_nodes_new_character_data[rotated, OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h:
+ "\<And>ptr'. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have object_ptr_kinds_eq_h:
+ "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using new_character_data_new_ptr h2 new_character_data_ptr by blast
+ then have node_ptr_kinds_eq_h:
+ "node_ptr_kinds h2 = node_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have character_data_ptr_kinds_eq_h:
+ "character_data_ptr_kinds h2 = character_data_ptr_kinds h |\<union>| {|new_character_data_ptr|}"
+ apply(simp add: character_data_ptr_kinds_def)
+ by force
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: document_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF CD.set_val_writes h3])
+ using CD.set_val_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+ then have character_data_ptr_kinds_eq_h2: "character_data_ptr_kinds h3 = character_data_ptr_kinds h2"
+ by(simp add: character_data_ptr_kinds_def)
+ have element_ptr_kinds_eq_h2: "element_ptr_kinds h3 = element_ptr_kinds h2"
+ using node_ptr_kinds_eq_h2
+ by(simp add: element_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_disconnected_nodes_writes h'])
+ using set_disconnected_nodes_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+ then have character_data_ptr_kinds_eq_h3: "character_data_ptr_kinds h' = character_data_ptr_kinds h3"
+ by(simp add: character_data_ptr_kinds_def)
+ have element_ptr_kinds_eq_h3: "element_ptr_kinds h' = element_ptr_kinds h3"
+ using node_ptr_kinds_eq_h3
+ by(simp add: element_ptr_kinds_def)
+
+
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ using disc_nodes_h3 document_ptr_kinds_eq_h object_ptr_kinds_eq_h2
+ CD.get_disconnected_nodes_ptr_in_heap \<open>type_wf h\<close> document_ptr_kinds_def
+ by (metis is_OK_returns_result_I)
+
+ have children_eq_h: "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads h2 get_child_nodes_new_character_data[rotated, OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h: "\<And>ptr'. ptr' \<noteq> cast new_character_data_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []"
+ using new_character_data_ptr h2 new_character_data_ptr_in_heap[OF h2 new_character_data_ptr]
+ new_character_data_is_character_data_ptr[OF new_character_data_ptr]
+ new_character_data_no_child_nodes
+ by blast
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using CD.get_disconnected_nodes_reads h2
+ get_disconnected_nodes_new_character_data[OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have disconnected_nodes_eq2_h:
+ "\<And>doc_ptr. |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have tag_name_eq_h:
+ "\<And>ptr' disc_nodes. h \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using get_tag_name_reads h2
+ get_tag_name_new_character_data[OF new_character_data_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have tag_name_eq2_h: "\<And>ptr'. |h \<turnstile> get_tag_name ptr'|\<^sub>r = |h2 \<turnstile> get_tag_name ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads CD.set_val_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_val_get_child_nodes)
+ then have children_eq2_h2:
+ "\<And>ptr'. |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using CD.get_disconnected_nodes_reads CD.set_val_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_val_get_disconnected_nodes)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have tag_name_eq_h2:
+ "\<And>ptr' disc_nodes. h2 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using get_tag_name_reads CD.set_val_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_val_get_tag_name)
+ then have tag_name_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_tag_name ptr'|\<^sub>r = |h3 \<turnstile> get_tag_name ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "type_wf h2"
+ using \<open>type_wf h\<close> new_character_data_types_preserved h2 by blast
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF CD.set_val_writes h3]
+ using set_val_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then show "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_disconnected_nodes_writes h']
+ using set_disconnected_nodes_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_eq_h3:
+ "\<And>ptr' children. h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_child_nodes)
+ then have children_eq2_h3:
+ " \<And>ptr'. |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h3: "\<And>doc_ptr disc_nodes. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using CD.get_disconnected_nodes_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_disconnected_nodes_different_pointers)
+ then have disconnected_nodes_eq2_h3: "\<And>doc_ptr. document_ptr \<noteq> doc_ptr
+ \<Longrightarrow> |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have tag_name_eq_h3:
+ "\<And>ptr' disc_nodes. h3 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using get_tag_name_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_disconnected_nodes_get_tag_name)
+ then have tag_name_eq2_h3: "\<And>ptr'. |h3 \<turnstile> get_tag_name ptr'|\<^sub>r = |h' \<turnstile> get_tag_name ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have disc_nodes_document_ptr_h2: "h2 \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h2 disc_nodes_h3 by auto
+ then have disc_nodes_document_ptr_h: "h \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r disc_nodes_h3"
+ using disconnected_nodes_eq_h by auto
+ then have "cast new_character_data_ptr \<notin> set disc_nodes_h3"
+ using \<open>heap_is_wellformed h\<close> using \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ a_all_ptrs_in_heap_def heap_is_wellformed_def
+ using NodeMonad.ptr_kinds_ptr_kinds_M local.heap_is_wellformed_disc_nodes_in_heap by blast
+
+ have "acyclic (parent_child_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def CD.acyclic_heap_def)
+ also have "parent_child_rel h = parent_child_rel h2"
+ proof(auto simp add: CD.parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h2"
+ by (simp add: object_ptr_kinds_eq_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq_h \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting) \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2_h empty_iff empty_set image_eqI select_result_I2)
+ qed
+ also have "\<dots> = parent_child_rel h3"
+ by(auto simp add: CD.parent_child_rel_def object_ptr_kinds_eq_h2 children_eq2_h2)
+ also have "\<dots> = parent_child_rel h'"
+ by(auto simp add: CD.parent_child_rel_def object_ptr_kinds_eq_h3 children_eq2_h3)
+ finally have "CD.a_acyclic_heap h'"
+ by (simp add: CD.acyclic_heap_def)
+
+ have "CD.a_all_ptrs_in_heap h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_all_ptrs_in_heap h2"
+ apply(auto simp add: CD.a_all_ptrs_in_heap_def)[1]
+ using node_ptr_kinds_eq_h \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ apply (metis (no_types, lifting) NodeMonad.ptr_kinds_ptr_kinds_M \<open>parent_child_rel h = parent_child_rel h2\<close>
+ children_eq2_h finite_set_in finsert_iff funion_finsert_right CD.parent_child_rel_child
+ CD.parent_child_rel_parent_in_heap node_ptr_kinds_commutes object_ptr_kinds_eq_h
+ select_result_I2 subsetD sup_bot.right_neutral)
+ by (metis (no_types, lifting) CD.get_child_nodes_ok CD.get_child_nodes_ptr_in_heap
+ \<open>h2 \<turnstile> get_child_nodes (cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr) \<rightarrow>\<^sub>r []\<close> assms(3) assms(4)
+ children_eq_h disconnected_nodes_eq2_h document_ptr_kinds_eq_h finite_set_in is_OK_returns_result_I
+ local.known_ptrs_known_ptr node_ptr_kinds_commutes returns_result_select_result subset_code(1))
+ then have "CD.a_all_ptrs_in_heap h3"
+ by (simp add: children_eq2_h2 disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ CD.a_all_ptrs_in_heap_def node_ptr_kinds_eq_h2 object_ptr_kinds_eq_h2)
+ then have "CD.a_all_ptrs_in_heap h'"
+ by (smt character_data_ptr_kinds_commutes character_data_ptr_kinds_eq_h2 children_eq2_h3
+ disc_nodes_h3 disconnected_nodes_eq2_h3 document_ptr_kinds_eq_h3 h' h2 local.CD.a_all_ptrs_in_heap_def
+ local.set_disconnected_nodes_get_disconnected_nodes new_character_data_ptr new_character_data_ptr_in_heap
+ node_ptr_kinds_eq_h3 notin_fset object_ptr_kinds_eq_h3 select_result_I2 set_ConsD subset_code(1))
+
+ have "\<And>p. p |\<in>| object_ptr_kinds h \<Longrightarrow> cast new_character_data_ptr \<notin> set |h \<turnstile> get_child_nodes p|\<^sub>r"
+ using \<open>heap_is_wellformed h\<close> \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+ heap_is_wellformed_children_in_heap
+ by (meson NodeMonad.ptr_kinds_ptr_kinds_M CD.a_all_ptrs_in_heap_def assms(3) assms(4) fset_mp
+ fset_of_list_elem CD.get_child_nodes_ok known_ptrs_known_ptr returns_result_select_result)
+ then have "\<And>p. p |\<in>| object_ptr_kinds h2 \<Longrightarrow> cast new_character_data_ptr \<notin> set |h2 \<turnstile> get_child_nodes p|\<^sub>r"
+ using children_eq2_h
+ apply(auto simp add: object_ptr_kinds_eq_h)[1]
+ using \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close> apply auto[1]
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M \<open>cast new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>)
+ then have "\<And>p. p |\<in>| object_ptr_kinds h3 \<Longrightarrow> cast new_character_data_ptr \<notin> set |h3 \<turnstile> get_child_nodes p|\<^sub>r"
+ using object_ptr_kinds_eq_h2 children_eq2_h2 by auto
+ then have new_character_data_ptr_not_in_any_children:
+ "\<And>p. p |\<in>| object_ptr_kinds h' \<Longrightarrow> cast new_character_data_ptr \<notin> set |h' \<turnstile> get_child_nodes p|\<^sub>r"
+ using object_ptr_kinds_eq_h3 children_eq2_h3 by auto
+
+ have "CD.a_distinct_lists h"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_distinct_lists h2"
+ using \<open>h2 \<turnstile> get_child_nodes (cast new_character_data_ptr) \<rightarrow>\<^sub>r []\<close>
+ apply(auto simp add: CD.a_distinct_lists_def object_ptr_kinds_eq_h document_ptr_kinds_eq_h
+ disconnected_nodes_eq2_h intro!: distinct_concat_map_I)[1]
+ apply (metis distinct_sorted_list_of_set finite_fset sorted_list_of_set_insert)
+ apply(case_tac "x=cast new_character_data_ptr")
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ apply (metis IntI assms(1) assms(3) assms(4) empty_iff CD.get_child_nodes_ok
+ local.heap_is_wellformed_one_parent local.known_ptrs_known_ptr
+ returns_result_select_result)
+ apply(auto simp add: children_eq2_h[symmetric] insort_split dest: distinct_concat_map_E(2))[1]
+ thm children_eq2_h
+
+ using \<open>CD.a_distinct_lists h\<close> \<open>type_wf h2\<close> disconnected_nodes_eq_h document_ptr_kinds_eq_h
+ CD.distinct_lists_no_parent get_disconnected_nodes_ok returns_result_select_result
+ by metis
+ then have "CD.a_distinct_lists h3"
+ by(auto simp add: CD.a_distinct_lists_def disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ children_eq2_h2 object_ptr_kinds_eq_h2)[1]
+ then have "CD.a_distinct_lists h'"
+ proof(auto simp add: CD.a_distinct_lists_def disconnected_nodes_eq2_h3 children_eq2_h3
+ object_ptr_kinds_eq_h3 document_ptr_kinds_eq_h3 intro!: distinct_concat_map_I)[1]
+ fix x
+ assume "distinct (concat (map (\<lambda>document_ptr. |h3 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and "x |\<in>| document_ptr_kinds h3"
+ then show "distinct |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using document_ptr_kinds_eq_h3 disconnected_nodes_eq_h3 h' set_disconnected_nodes_get_disconnected_nodes
+ by (metis (no_types, hide_lams) \<open>cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr \<notin> set disc_nodes_h3\<close>
+ \<open>type_wf h2\<close> assms(1) disc_nodes_document_ptr_h disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ disconnected_nodes_eq_h distinct.simps(2) document_ptr_kinds_eq_h2 local.get_disconnected_nodes_ok
+ local.heap_is_wellformed_disconnected_nodes_distinct returns_result_select_result select_result_I2)
+ next
+ fix x y xa
+ assume "distinct (concat (map (\<lambda>document_ptr. |h3 \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h3)))))"
+ and "x |\<in>| document_ptr_kinds h3"
+ and "y |\<in>| document_ptr_kinds h3"
+ and "x \<noteq> y"
+ and "xa \<in> set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ and "xa \<in> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ moreover have "set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r \<inter> set |h3 \<turnstile> get_disconnected_nodes y|\<^sub>r = {}"
+ using calculation by(auto dest: distinct_concat_map_E(1))
+ ultimately show "False"
+ using NodeMonad.ptr_kinds_ptr_kinds_M \<open>cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr \<notin> set |h \<turnstile> node_ptr_kinds_M|\<^sub>r\<close>
+
+ by (smt local.CD.a_all_ptrs_in_heap_def \<open>CD.a_all_ptrs_in_heap h\<close> disc_nodes_document_ptr_h2
+ disconnected_nodes_eq2_h
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3 disjoint_iff_not_equal
+ document_ptr_kinds_eq_h document_ptr_kinds_eq_h2 finite_set_in h'
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ local.a_all_ptrs_in_heap_def local.l_set_disconnected_nodes_get_disconnected_nodes_axioms
+ select_result_I2 set_ConsD subsetD)
+ next
+ fix x xa xb
+ assume 2: "(\<Union>x\<in>fset (object_ptr_kinds h3). set |h' \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h3). set |h3 \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 3: "xa |\<in>| object_ptr_kinds h3"
+ and 4: "x \<in> set |h' \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 5: "xb |\<in>| document_ptr_kinds h3"
+ and 6: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ show "False"
+ using disc_nodes_document_ptr_h disconnected_nodes_eq2_h3
+ apply(cases "document_ptr = xb")
+ apply (metis (no_types, lifting) "3" "4" "5" "6" CD.distinct_lists_no_parent
+ \<open>local.CD.a_distinct_lists h2\<close> \<open>type_wf h'\<close> children_eq2_h2 children_eq2_h3 disc_nodes_document_ptr_h2
+ document_ptr_kinds_eq_h3 h' local.get_disconnected_nodes_ok local.set_disconnected_nodes_get_disconnected_nodes
+ new_character_data_ptr_not_in_any_children object_ptr_kinds_eq_h2 object_ptr_kinds_eq_h3 returns_result_eq
+ returns_result_select_result set_ConsD)
+ by (metis "3" "4" "5" "6" CD.distinct_lists_no_parent \<open>local.CD.a_distinct_lists h3\<close> \<open>type_wf h3\<close>
+ children_eq2_h3 local.get_disconnected_nodes_ok returns_result_select_result)
+ qed
+
+ have "CD.a_owner_document_valid h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_owner_document_valid h'"
+ using disc_nodes_h3 \<open>document_ptr |\<in>| document_ptr_kinds h\<close>
+ apply(simp add: CD.a_owner_document_valid_def)
+ apply(simp add: object_ptr_kinds_eq_h object_ptr_kinds_eq_h3 )
+ apply(simp add: object_ptr_kinds_eq_h2)
+ apply(simp add: document_ptr_kinds_eq_h document_ptr_kinds_eq_h3 )
+ apply(simp add: document_ptr_kinds_eq_h2)
+ apply(simp add: node_ptr_kinds_eq_h node_ptr_kinds_eq_h3 )
+ apply(simp add: node_ptr_kinds_eq_h2 node_ptr_kinds_eq_h )
+ apply(auto simp add: children_eq2_h2[symmetric] children_eq2_h3[symmetric] disconnected_nodes_eq2_h
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3)[1]
+ apply (metis (no_types, lifting) document_ptr_kinds_eq_h h' list.set_intros(1)
+ local.set_disconnected_nodes_get_disconnected_nodes select_result_I2)
+ apply(simp add: object_ptr_kinds_eq_h)
+ by (metis (mono_tags, lifting) \<open>cast\<^sub>c\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>_\<^sub>d\<^sub>a\<^sub>t\<^sub>a\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_character_data_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>
+ children_eq2_h disconnected_nodes_eq2_h3 document_ptr_kinds_eq_h finite_set_in h'
+ l_ptr_kinds_M.ptr_kinds_ptr_kinds_M
+ l_set_disconnected_nodes_get_disconnected_nodes.set_disconnected_nodes_get_disconnected_nodes
+ list.set_intros(2) local.l_set_disconnected_nodes_get_disconnected_nodes_axioms
+ object_ptr_kinds_M_def
+ select_result_I2)
+
+
+
+
+
+
+ have shadow_root_ptr_kinds_eq_h: "shadow_root_ptr_kinds h2 = shadow_root_ptr_kinds h"
+ using document_ptr_kinds_eq_h
+ by(auto simp add: shadow_root_ptr_kinds_def)
+ have shadow_root_ptr_kinds_eq_h2: "shadow_root_ptr_kinds h3 = shadow_root_ptr_kinds h2"
+ using document_ptr_kinds_eq_h2
+ by(auto simp add: shadow_root_ptr_kinds_def)
+ have shadow_root_ptr_kinds_eq_h3: "shadow_root_ptr_kinds h' = shadow_root_ptr_kinds h3"
+ using document_ptr_kinds_eq_h3
+ by(auto simp add: shadow_root_ptr_kinds_def)
+
+
+
+ have shadow_root_eq_h: "\<And>character_data_ptr shadow_root_opt.
+h \<turnstile> get_shadow_root character_data_ptr \<rightarrow>\<^sub>r shadow_root_opt =
+h2 \<turnstile> get_shadow_root character_data_ptr \<rightarrow>\<^sub>r shadow_root_opt"
+ using get_shadow_root_reads h2 get_shadow_root_new_character_data[rotated, OF h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ using local.get_shadow_root_locs_impl new_character_data_ptr apply blast
+ using local.get_shadow_root_locs_impl new_character_data_ptr by blast
+
+
+ have shadow_root_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children"
+ using get_shadow_root_reads set_val_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_val_get_shadow_root)
+ have shadow_root_eq_h3:
+ "\<And>ptr' children. h3 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children"
+ using get_shadow_root_reads set_disconnected_nodes_writes h'
+ apply(rule reads_writes_preserved)
+ using set_disconnected_nodes_get_shadow_root
+ by(auto simp add: set_disconnected_nodes_get_shadow_root)
+
+
+ have "a_all_ptrs_in_heap h"
+ by (simp add: assms(1) local.a_all_ptrs_in_heap_def local.get_shadow_root_shadow_root_ptr_in_heap)
+ then have "a_all_ptrs_in_heap h2"
+ apply(auto simp add: a_all_ptrs_in_heap_def shadow_root_ptr_kinds_eq_h)[1]
+ using returns_result_eq shadow_root_eq_h by fastforce
+ then have "a_all_ptrs_in_heap h3"
+ apply(auto simp add: a_all_ptrs_in_heap_def shadow_root_ptr_kinds_eq_h2)[1]
+ using shadow_root_eq_h2 by blast
+ then have "a_all_ptrs_in_heap h'"
+ apply(auto simp add: a_all_ptrs_in_heap_def shadow_root_ptr_kinds_eq_h3)[1]
+ by (simp add: shadow_root_eq_h3)
+
+ have "a_distinct_lists h"
+ using assms(1)
+ by (simp add: heap_is_wellformed_def)
+ then have "a_distinct_lists h2"
+ apply(auto simp add: a_distinct_lists_def character_data_ptr_kinds_eq_h)[1]
+ apply(auto simp add: distinct_insort intro!: distinct_concat_map_I split: option.splits)[1]
+ by (metis \<open>type_wf h2\<close> assms(1) assms(3) local.get_shadow_root_ok local.shadow_root_same_host
+ returns_result_select_result shadow_root_eq_h)
+ then have "a_distinct_lists h3"
+ by(auto simp add: a_distinct_lists_def element_ptr_kinds_eq_h2 select_result_eq[OF shadow_root_eq_h2])
+ then have "a_distinct_lists h'"
+ by(auto simp add: a_distinct_lists_def element_ptr_kinds_eq_h3 select_result_eq[OF shadow_root_eq_h3])
+
+
+ have "a_shadow_root_valid h"
+ using assms(1)
+ by (simp add: heap_is_wellformed_def)
+ then have "a_shadow_root_valid h2"
+ by(auto simp add: a_shadow_root_valid_def shadow_root_ptr_kinds_eq_h element_ptr_kinds_eq_h
+ select_result_eq[OF shadow_root_eq_h] tag_name_eq2_h)
+ then have "a_shadow_root_valid h3"
+ by(auto simp add: a_shadow_root_valid_def shadow_root_ptr_kinds_eq_h2 element_ptr_kinds_eq_h2
+ select_result_eq[OF shadow_root_eq_h2] tag_name_eq2_h2)
+ then have "a_shadow_root_valid h'"
+ by(auto simp add: a_shadow_root_valid_def shadow_root_ptr_kinds_eq_h3 element_ptr_kinds_eq_h3
+ select_result_eq[OF shadow_root_eq_h3] tag_name_eq2_h3)
+
+
+
+ have "a_host_shadow_root_rel h = a_host_shadow_root_rel h2"
+ by(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h select_result_eq[OF shadow_root_eq_h])
+ have "a_host_shadow_root_rel h2 = a_host_shadow_root_rel h3"
+ by(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h2 select_result_eq[OF shadow_root_eq_h2])
+ have "a_host_shadow_root_rel h3 = a_host_shadow_root_rel h'"
+ by(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h3 select_result_eq[OF shadow_root_eq_h3])
+
+ have "a_ptr_disconnected_node_rel h = a_ptr_disconnected_node_rel h2"
+ by(simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h disconnected_nodes_eq2_h)
+ have "a_ptr_disconnected_node_rel h2 = a_ptr_disconnected_node_rel h3"
+ by(simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h2 disconnected_nodes_eq2_h2)
+
+ have "h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast new_character_data_ptr # disc_nodes_h3"
+ using h' local.set_disconnected_nodes_get_disconnected_nodes by auto
+ have " document_ptr |\<in>| document_ptr_kinds h3"
+ by (simp add: \<open>document_ptr |\<in>| document_ptr_kinds h\<close> document_ptr_kinds_eq_h document_ptr_kinds_eq_h2)
+ have "cast new_character_data_ptr \<in> set |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r"
+ using \<open>h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast new_character_data_ptr # disc_nodes_h3\<close> by auto
+
+ have "a_ptr_disconnected_node_rel h' = {(cast document_ptr, cast new_character_data_ptr)} \<union> a_ptr_disconnected_node_rel h3"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h3 disconnected_nodes_eq2_h3)[1]
+ apply(case_tac "aa = document_ptr")
+ using disc_nodes_h3 h' \<open>h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast new_character_data_ptr # disc_nodes_h3\<close>
+ apply(auto)[1]
+ using disconnected_nodes_eq2_h3 apply auto[1]
+ using \<open>h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast new_character_data_ptr # disc_nodes_h3\<close>
+ using \<open>cast new_character_data_ptr \<in> set |h' \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r\<close>
+ using \<open>document_ptr |\<in>| document_ptr_kinds h3\<close> apply auto[1]
+ apply(case_tac "document_ptr = aa")
+ using \<open>h' \<turnstile> get_disconnected_nodes document_ptr \<rightarrow>\<^sub>r cast new_character_data_ptr # disc_nodes_h3\<close> disc_nodes_h3 apply auto[1]
+ using disconnected_nodes_eq_h3[THEN select_result_eq, simplified] by auto
+
+ have "acyclic (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def)
+ have "parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h =
+parent_child_rel h2 \<union> a_host_shadow_root_rel h2 \<union> a_ptr_disconnected_node_rel h2"
+ using \<open>local.a_host_shadow_root_rel h = local.a_host_shadow_root_rel h2\<close>
+ \<open>local.a_ptr_disconnected_node_rel h = local.a_ptr_disconnected_node_rel h2\<close> \<open>parent_child_rel h = parent_child_rel h2\<close> by auto
+ have "parent_child_rel h2 \<union> a_host_shadow_root_rel h2 \<union> a_ptr_disconnected_node_rel h2 =
+parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3"
+ using \<open>local.a_host_shadow_root_rel h2 = local.a_host_shadow_root_rel h3\<close>
+ \<open>local.a_ptr_disconnected_node_rel h2 = local.a_ptr_disconnected_node_rel h3\<close> \<open>parent_child_rel h2 = parent_child_rel h3\<close> by auto
+ have "parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h' =
+{(cast document_ptr, cast new_character_data_ptr)} \<union> parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3"
+ by (simp add: \<open>local.a_host_shadow_root_rel h3 = local.a_host_shadow_root_rel h'\<close>
+ \<open>local.a_ptr_disconnected_node_rel h' = {(cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr, cast new_character_data_ptr)} \<union>
+local.a_ptr_disconnected_node_rel h3\<close> \<open>parent_child_rel h3 = parent_child_rel h'\<close>)
+
+ have "\<And>a b. (a, b) \<in> parent_child_rel h3 \<Longrightarrow> a \<noteq> cast new_character_data_ptr"
+ using CD.parent_child_rel_parent_in_heap \<open>parent_child_rel h = parent_child_rel h2\<close>
+ \<open>parent_child_rel h2 = parent_child_rel h3\<close> character_data_ptr_kinds_commutes h2 new_character_data_ptr
+ new_character_data_ptr_not_in_heap node_ptr_kinds_commutes by blast
+ moreover
+ have "\<And>a b. (a, b) \<in> a_host_shadow_root_rel h3 \<Longrightarrow> a \<noteq> cast new_character_data_ptr"
+ using shadow_root_eq_h2
+ by(auto simp add: a_host_shadow_root_rel_def)
+ moreover
+ have "\<And>a b. (a, b) \<in> a_ptr_disconnected_node_rel h3 \<Longrightarrow> a \<noteq> cast new_character_data_ptr"
+ by(auto simp add: a_ptr_disconnected_node_rel_def)
+ moreover
+ have "cast new_character_data_ptr \<notin> {x. (x, cast document_ptr) \<in>
+(parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3)\<^sup>*}"
+ by (smt Un_iff calculation(1) calculation(2) calculation(3) cast_document_ptr_not_node_ptr(2)
+ converse_rtranclE mem_Collect_eq)
+ moreover
+ have "acyclic (parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3)"
+ using \<open>acyclic (parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> local.a_ptr_disconnected_node_rel h)\<close>
+ \<open>parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> local.a_ptr_disconnected_node_rel h =
+parent_child_rel h2 \<union> local.a_host_shadow_root_rel h2 \<union> local.a_ptr_disconnected_node_rel h2\<close>
+ \<open>parent_child_rel h2 \<union> local.a_host_shadow_root_rel h2 \<union> local.a_ptr_disconnected_node_rel h2 =
+parent_child_rel h3 \<union> local.a_host_shadow_root_rel h3 \<union> local.a_ptr_disconnected_node_rel h3\<close>
+ by auto
+ ultimately have "acyclic (parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h')"
+ by(simp add: \<open>parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h' =
+{(cast document_ptr, cast new_character_data_ptr)} \<union> parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3\<close>)
+
+
+ have "CD.a_heap_is_wellformed h'"
+ apply(simp add: CD.a_heap_is_wellformed_def)
+ by (simp add: \<open>local.CD.a_acyclic_heap h'\<close> \<open>local.CD.a_all_ptrs_in_heap h'\<close>
+ \<open>local.CD.a_distinct_lists h'\<close> \<open>local.CD.a_owner_document_valid h'\<close>)
+
+ show " heap_is_wellformed h' "
+ using \<open>acyclic (parent_child_rel h' \<union> local.a_host_shadow_root_rel h' \<union> local.a_ptr_disconnected_node_rel h')\<close>
+ by(simp add: heap_is_wellformed_def CD.heap_is_wellformed_impl \<open>local.CD.a_heap_is_wellformed h'\<close>
+ \<open>local.a_all_ptrs_in_heap h'\<close> \<open>local.a_distinct_lists h'\<close> \<open>local.a_shadow_root_valid h'\<close>)
+qed
+end
+
+subsubsection \<open>create\_document\<close>
+
+locale l_create_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_child_nodes get_child_nodes_locs get_disconnected_nodes
+ get_disconnected_nodes_locs
+ get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs known_ptr type_wf
+ heap_is_wellformed parent_child_rel
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document get_disconnected_document_locs
+ + l_new_document_get_disconnected_nodes
+ get_disconnected_nodes get_disconnected_nodes_locs
+ + l_create_document\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ create_document
+ + l_new_document_get_child_nodes
+ type_wf known_ptr get_child_nodes get_child_nodes_locs
+ + l_get_tag_name type_wf get_tag_name get_tag_name_locs
+ + l_new_document_get_tag_name get_tag_name get_tag_name_locs
+ + l_get_disconnected_nodes\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M type_wf type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_disconnected_nodes get_disconnected_nodes_locs
+ + l_new_document
+ type_wf
+ + l_known_ptrs
+ known_ptr known_ptrs
+ for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_document :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_disconnected_document_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and set_val :: "(_) character_data_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_val_locs :: "(_) character_data_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and create_document :: "((_) heap, exception, (_) document_ptr) prog"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+begin
+
+lemma create_document_preserves_wellformedness:
+ assumes "heap_is_wellformed h"
+ and "h \<turnstile> create_document \<rightarrow>\<^sub>h h'"
+ and "type_wf h"
+ and "known_ptrs h"
+ shows "heap_is_wellformed h'"
+proof -
+ obtain new_document_ptr where
+ new_document_ptr: "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr" and
+ h': "h \<turnstile> new_document \<rightarrow>\<^sub>h h'"
+ using assms(2)
+ apply(simp add: create_document_def)
+ using new_document_ok by blast
+
+ have "new_document_ptr \<notin> set |h \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ using new_document_ptr DocumentMonad.ptr_kinds_ptr_kinds_M
+ using new_document_ptr_not_in_heap h' by blast
+ then have "cast new_document_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+
+ have "new_document_ptr |\<notin>| document_ptr_kinds h"
+ using new_document_ptr DocumentMonad.ptr_kinds_ptr_kinds_M
+ using new_document_ptr_not_in_heap h' by blast
+ then have "cast new_document_ptr |\<notin>| object_ptr_kinds h"
+ by simp
+
+ have object_ptr_kinds_eq: "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_document_ptr|}"
+ using new_document_new_ptr h' new_document_ptr by blast
+ then have node_ptr_kinds_eq: "node_ptr_kinds h' = node_ptr_kinds h"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have character_data_ptr_kinds_eq_h: "character_data_ptr_kinds h' = character_data_ptr_kinds h"
+ by(simp add: character_data_ptr_kinds_def)
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h' = element_ptr_kinds h"
+ using object_ptr_kinds_eq
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h' = document_ptr_kinds h |\<union>| {|new_document_ptr|}"
+ using object_ptr_kinds_eq
+ apply(auto simp add: document_ptr_kinds_def)[1]
+ by (metis (no_types, lifting) document_ptr_kinds_commutes document_ptr_kinds_def finsertI1 fset.map_comp)
+
+
+ have children_eq:
+ "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_document_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads h' get_child_nodes_new_document[rotated, OF new_document_ptr h']
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2: "\<And>ptr'. ptr' \<noteq> cast new_document_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+
+ have "h' \<turnstile> get_child_nodes (cast new_document_ptr) \<rightarrow>\<^sub>r []"
+ using new_document_ptr h' new_document_ptr_in_heap[OF h' new_document_ptr]
+ new_document_is_document_ptr[OF new_document_ptr] new_document_no_child_nodes
+ by blast
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. doc_ptr \<noteq> new_document_ptr
+ \<Longrightarrow> h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using CD.get_disconnected_nodes_reads h' get_disconnected_nodes_new_document_different_pointers new_document_ptr
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by (metis(full_types) \<open>\<And>thesis. (\<And>new_document_ptr.
+ \<lbrakk>h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr; h \<turnstile> new_document \<rightarrow>\<^sub>h h'\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis\<close>
+ local.get_disconnected_nodes_new_document_different_pointers new_document_ptr)+
+ then have disconnected_nodes_eq2_h: "\<And>doc_ptr. doc_ptr \<noteq> new_document_ptr
+ \<Longrightarrow> |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have "h' \<turnstile> get_disconnected_nodes new_document_ptr \<rightarrow>\<^sub>r []"
+ using h' local.new_document_no_disconnected_nodes new_document_ptr by blast
+
+ have "type_wf h'"
+ using \<open>type_wf h\<close> new_document_types_preserved h' by blast
+
+ have "acyclic (parent_child_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (auto simp add: heap_is_wellformed_def CD.heap_is_wellformed_def CD.acyclic_heap_def)
+ also have "parent_child_rel h = parent_child_rel h'"
+ proof(auto simp add: CD.parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h'"
+ by (simp add: object_ptr_kinds_eq)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h' \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast new_document_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h'"
+ and 1: "x \<in> set |h' \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq \<open>h' \<turnstile> get_child_nodes (cast new_document_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h'"
+ and 1: "x \<in> set |h' \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting) \<open>h' \<turnstile> get_child_nodes (cast new_document_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2 empty_iff empty_set image_eqI select_result_I2)
+ qed
+ finally have "CD.a_acyclic_heap h'"
+ by (simp add: CD.acyclic_heap_def)
+
+ have "CD.a_all_ptrs_in_heap h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def )
+ then have "CD.a_all_ptrs_in_heap h'"
+ apply(auto simp add: CD.a_all_ptrs_in_heap_def)[1]
+ using ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close>
+ \<open>parent_child_rel h = parent_child_rel h'\<close> assms(1) children_eq fset_of_list_elem
+ local.heap_is_wellformed_children_in_heap CD.parent_child_rel_child
+ CD.parent_child_rel_parent_in_heap node_ptr_kinds_eq
+ apply (metis (no_types, lifting) \<open>h' \<turnstile> get_child_nodes (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2 finite_set_in finsert_iff funion_finsert_right object_ptr_kinds_eq
+ select_result_I2 subsetD sup_bot.right_neutral)
+ by (metis (no_types, lifting) \<open>h' \<turnstile> get_disconnected_nodes new_document_ptr \<rightarrow>\<^sub>r []\<close> \<open>type_wf h'\<close>
+ assms(1) disconnected_nodes_eq_h empty_iff empty_set local.get_disconnected_nodes_ok
+ local.heap_is_wellformed_disc_nodes_in_heap node_ptr_kinds_eq returns_result_select_result select_result_I2)
+
+ have "CD.a_distinct_lists h"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_distinct_lists h'"
+ using \<open>h' \<turnstile> get_disconnected_nodes new_document_ptr \<rightarrow>\<^sub>r []\<close>
+ \<open>h' \<turnstile> get_child_nodes (cast new_document_ptr) \<rightarrow>\<^sub>r []\<close>
+
+ apply(auto simp add: children_eq2[symmetric] CD.a_distinct_lists_def insort_split object_ptr_kinds_eq
+ document_ptr_kinds_eq_h disconnected_nodes_eq2_h intro!: distinct_concat_map_I)[1]
+ apply (metis distinct_sorted_list_of_set finite_fset sorted_list_of_set_insert)
+
+ apply(auto simp add: dest: distinct_concat_map_E)[1]
+ apply(auto simp add: dest: distinct_concat_map_E)[1]
+ using \<open>new_document_ptr |\<notin>| document_ptr_kinds h\<close>
+ apply(auto simp add: distinct_insort dest: distinct_concat_map_E)[1]
+ apply (metis assms(1) assms(3) disconnected_nodes_eq2_h get_disconnected_nodes_ok
+ local.heap_is_wellformed_disconnected_nodes_distinct
+ returns_result_select_result)
+ proof -
+ fix x :: "(_) document_ptr" and y :: "(_) document_ptr" and xa :: "(_) node_ptr"
+ assume a1: "x \<noteq> y"
+ assume a2: "x |\<in>| document_ptr_kinds h"
+ assume a3: "x \<noteq> new_document_ptr"
+ assume a4: "y |\<in>| document_ptr_kinds h"
+ assume a5: "y \<noteq> new_document_ptr"
+ assume a6: "distinct (concat (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h)))))"
+ assume a7: "xa \<in> set |h' \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ assume a8: "xa \<in> set |h' \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ have f9: "xa \<in> set |h \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using a7 a3 disconnected_nodes_eq2_h by presburger
+ have f10: "xa \<in> set |h \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ using a8 a5 disconnected_nodes_eq2_h by presburger
+ have f11: "y \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))"
+ using a4 by simp
+ have "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))"
+ using a2 by simp
+ then show False
+ using f11 f10 f9 a6 a1 by (meson disjoint_iff_not_equal distinct_concat_map_E(1))
+ next
+ fix x xa xb
+ assume 0: "h' \<turnstile> get_disconnected_nodes new_document_ptr \<rightarrow>\<^sub>r []"
+ and 1: "h' \<turnstile> get_child_nodes (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr) \<rightarrow>\<^sub>r []"
+ and 2: "distinct (concat (map (\<lambda>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h)))))"
+ and 3: "distinct (concat (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h)))))"
+ and 4: "(\<Union>x\<in>fset (object_ptr_kinds h). set |h \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h). set |h \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 5: "x \<in> set |h \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 6: "x \<in> set |h' \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ and 7: "xa |\<in>| object_ptr_kinds h"
+ and 8: "xa \<noteq> cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr"
+ and 9: "xb |\<in>| document_ptr_kinds h"
+ and 10: "xb \<noteq> new_document_ptr"
+ then show "False"
+
+ by (metis \<open>CD.a_distinct_lists h\<close> assms(3) disconnected_nodes_eq2_h
+ CD.distinct_lists_no_parent get_disconnected_nodes_ok
+ returns_result_select_result)
+ qed
+
+ have "CD.a_owner_document_valid h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_owner_document_valid h'"
+ apply(auto simp add: CD.a_owner_document_valid_def)[1]
+ by (metis \<open>cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_document_ptr |\<notin>| object_ptr_kinds h\<close>
+ children_eq2 disconnected_nodes_eq2_h document_ptr_kinds_commutes finite_set_in funion_iff
+ node_ptr_kinds_eq object_ptr_kinds_eq)
+
+ have shadow_root_eq_h: "\<And>character_data_ptr shadow_root_opt. h \<turnstile> get_shadow_root character_data_ptr \<rightarrow>\<^sub>r shadow_root_opt =
+h' \<turnstile> get_shadow_root character_data_ptr \<rightarrow>\<^sub>r shadow_root_opt"
+ using get_shadow_root_reads assms(2) get_shadow_root_new_document[rotated, OF h']
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ using local.get_shadow_root_locs_impl new_document_ptr apply blast
+ using local.get_shadow_root_locs_impl new_document_ptr by blast
+
+
+ have "a_all_ptrs_in_heap h"
+ by (simp add: assms(1) local.a_all_ptrs_in_heap_def local.get_shadow_root_shadow_root_ptr_in_heap)
+ then have "a_all_ptrs_in_heap h'"
+ apply(auto simp add: a_all_ptrs_in_heap_def shadow_root_ptr_kinds_def document_ptr_kinds_eq_h)[1]
+ using shadow_root_eq_h by fastforce
+
+ have "a_distinct_lists h"
+ using assms(1)
+ by (simp add: heap_is_wellformed_def)
+ then have "a_distinct_lists h'"
+ apply(auto simp add: a_distinct_lists_def character_data_ptr_kinds_eq_h)[1]
+ apply(auto simp add: distinct_insort intro!: distinct_concat_map_I split: option.splits)[1]
+ by (metis \<open>type_wf h'\<close> assms(1) assms(3) local.get_shadow_root_ok local.shadow_root_same_host
+ returns_result_select_result shadow_root_eq_h)
+
+
+ have tag_name_eq_h:
+ "\<And>ptr' disc_nodes. h \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using get_tag_name_reads h'
+ get_tag_name_new_document[OF new_document_ptr h']
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+
+ have "a_shadow_root_valid h"
+ using assms(1)
+ by (simp add: heap_is_wellformed_def)
+ then have "a_shadow_root_valid h'"
+ using new_document_is_document_ptr[OF new_document_ptr]
+ by(auto simp add: a_shadow_root_valid_def element_ptr_kinds_eq_h document_ptr_kinds_eq_h
+ shadow_root_ptr_kinds_def select_result_eq[OF shadow_root_eq_h] select_result_eq[OF tag_name_eq_h]
+ is_shadow_root_ptr_kind\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def is_document_ptr\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def
+ split: option.splits)
+
+
+ have "a_host_shadow_root_rel h = a_host_shadow_root_rel h'"
+ by(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h select_result_eq[OF shadow_root_eq_h])
+
+ have "a_ptr_disconnected_node_rel h = a_ptr_disconnected_node_rel h'"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h disconnected_nodes_eq2_h)[1]
+ using \<open>new_document_ptr |\<notin>| document_ptr_kinds h\<close> disconnected_nodes_eq2_h apply fastforce
+ using new_document_disconnected_nodes[OF h' new_document_ptr]
+ apply(simp add: CD.get_disconnected_nodes_impl CD.a_get_disconnected_nodes_def)
+ using \<open>new_document_ptr |\<notin>| document_ptr_kinds h\<close> disconnected_nodes_eq2_h apply fastforce
+ done
+
+ have "acyclic (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def)
+ moreover
+ have "parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h =
+parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h'"
+ by (simp add: \<open>local.a_host_shadow_root_rel h = local.a_host_shadow_root_rel h'\<close>
+ \<open>local.a_ptr_disconnected_node_rel h = local.a_ptr_disconnected_node_rel h'\<close>
+ \<open>parent_child_rel h = parent_child_rel h'\<close>)
+ ultimately have "acyclic (parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h')"
+ by simp
+
+ have "CD.a_heap_is_wellformed h'"
+ apply(simp add: CD.a_heap_is_wellformed_def)
+ by (simp add: \<open>local.CD.a_acyclic_heap h'\<close> \<open>local.CD.a_all_ptrs_in_heap h'\<close>
+ \<open>local.CD.a_distinct_lists h'\<close> \<open>local.CD.a_owner_document_valid h'\<close>)
+
+ show "heap_is_wellformed h'"
+ using CD.heap_is_wellformed_impl \<open>acyclic (parent_child_rel h' \<union> local.a_host_shadow_root_rel h' \<union>
+local.a_ptr_disconnected_node_rel h')\<close> \<open>local.CD.a_heap_is_wellformed h'\<close> \<open>local.a_all_ptrs_in_heap h'\<close>
+ \<open>local.a_distinct_lists h'\<close> \<open>local.a_shadow_root_valid h'\<close> local.heap_is_wellformed_def by auto
+qed
+end
+
+interpretation l_create_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr type_wf DocumentClass.type_wf get_child_nodes
+ get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs get_shadow_root
+ get_shadow_root_locs get_tag_name get_tag_name_locs
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document get_disconnected_document_locs
+ heap_is_wellformed parent_child_rel set_val set_val_locs set_disconnected_nodes set_disconnected_nodes_locs
+ create_document known_ptrs
+ by(auto simp add: l_create_document_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+
+
+subsubsection \<open>attach\_shadow\_root\<close>
+
+locale l_attach_shadow_root_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M =
+ l_get_disconnected_nodes
+ type_wf get_disconnected_nodes get_disconnected_nodes_locs
+ + l_heap_is_wellformed\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ get_shadow_root get_shadow_root_locs get_tag_name get_tag_name_locs known_ptr type_wf
+ heap_is_wellformed parent_child_rel
+ heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document get_disconnected_document_locs
+ + l_attach_shadow_root\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr set_shadow_root set_shadow_root_locs set_mode set_mode_locs
+ attach_shadow_root type_wf get_tag_name get_tag_name_locs get_shadow_root get_shadow_root_locs
+ + l_new_shadow_root_get_disconnected_nodes
+ get_disconnected_nodes get_disconnected_nodes_locs
+
++ l_set_mode_get_disconnected_nodes
+type_wf set_mode set_mode_locs get_disconnected_nodes get_disconnected_nodes_locs
++ l_new_shadow_root_get_child_nodes
+type_wf known_ptr get_child_nodes get_child_nodes_locs
++ l_new_shadow_root_get_tag_name
+type_wf get_tag_name get_tag_name_locs
++ l_set_mode_get_child_nodes
+type_wf set_mode set_mode_locs known_ptr get_child_nodes get_child_nodes_locs
++ l_set_shadow_root_get_child_nodes
+type_wf set_shadow_root set_shadow_root_locs known_ptr get_child_nodes get_child_nodes_locs
++ l_set_shadow_root
+type_wf set_shadow_root set_shadow_root_locs
++ l_set_shadow_root_get_disconnected_nodes
+set_shadow_root set_shadow_root_locs get_disconnected_nodes get_disconnected_nodes_locs
++ l_set_mode_get_shadow_root type_wf set_mode set_mode_locs get_shadow_root get_shadow_root_locs
++ l_set_shadow_root_get_shadow_root type_wf set_shadow_root set_shadow_root_locs
+get_shadow_root get_shadow_root_locs
++ l_new_character_data_get_tag_name
+get_tag_name get_tag_name_locs
++ l_set_mode_get_tag_name type_wf set_mode set_mode_locs get_tag_name get_tag_name_locs
++ l_get_tag_name type_wf get_tag_name get_tag_name_locs
++ l_set_shadow_root_get_tag_name set_shadow_root set_shadow_root_locs get_tag_name get_tag_name_locs
++ l_new_shadow_root
+type_wf
++ l_known_ptrs
+known_ptr known_ptrs
+for known_ptr :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and known_ptrs :: "(_) heap \<Rightarrow> bool"
+ and type_wf :: "(_) heap \<Rightarrow> bool"
+ and get_child_nodes :: "(_) object_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_child_nodes_locs :: "(_) object_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_nodes :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, (_) node_ptr list) prog"
+ and get_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed :: "(_) heap \<Rightarrow> bool"
+ and parent_child_rel :: "(_) heap \<Rightarrow> ((_) object_ptr \<times> (_) object_ptr) set"
+ and set_tag_name :: "(_) element_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and set_disconnected_nodes :: "(_) document_ptr \<Rightarrow> (_) node_ptr list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_disconnected_nodes_locs :: "(_) document_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and create_element :: "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_shadow_root :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, (_) shadow_root_ptr option) prog"
+ and get_shadow_root_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_tag_name :: "(_) element_ptr \<Rightarrow> ((_) heap, exception, char list) prog"
+ and get_tag_name_locs :: "(_) element_ptr \<Rightarrow> ((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and get_host :: "(_) shadow_root_ptr \<Rightarrow> ((_) heap, exception, (_) element_ptr) prog"
+ and get_host_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and get_disconnected_document :: "(_) node_ptr \<Rightarrow> ((_) heap, exception, (_) document_ptr) prog"
+ and get_disconnected_document_locs :: "((_) heap \<Rightarrow> (_) heap \<Rightarrow> bool) set"
+ and set_val :: "(_) character_data_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, unit) prog"
+ and set_val_locs :: "(_) character_data_ptr \<Rightarrow> ((_) heap, exception, unit) prog set"
+ and create_character_data ::
+ "(_) document_ptr \<Rightarrow> char list \<Rightarrow> ((_) heap, exception, (_) character_data_ptr) prog"
+ and known_ptr\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_::linorder) object_ptr \<Rightarrow> bool"
+ and type_wf\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M :: "(_) heap \<Rightarrow> bool"
+ and set_shadow_root :: "(_) element_ptr \<Rightarrow> (_) shadow_root_ptr option \<Rightarrow> (_, unit) dom_prog"
+ and set_shadow_root_locs :: "(_) element_ptr \<Rightarrow> (_, unit) dom_prog set"
+ and set_mode :: "(_) shadow_root_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> (_, unit) dom_prog"
+ and set_mode_locs :: "(_) shadow_root_ptr \<Rightarrow> (_, unit) dom_prog set"
+ and attach_shadow_root :: "(_) element_ptr \<Rightarrow> shadow_root_mode \<Rightarrow> (_, (_) shadow_root_ptr) dom_prog"
+begin
+lemma attach_shadow_root_child_preserves:
+ assumes "heap_is_wellformed h" and "type_wf h" and "known_ptrs h"
+ assumes "h \<turnstile> attach_shadow_root element_ptr new_mode \<rightarrow>\<^sub>h h'"
+ shows "type_wf h'" and "known_ptrs h'" and "heap_is_wellformed h'"
+proof -
+ obtain h2 h3 new_shadow_root_ptr element_tag_name where
+ element_tag_name: "h \<turnstile> get_tag_name element_ptr \<rightarrow>\<^sub>r element_tag_name" and
+ "element_tag_name \<in> safe_shadow_root_element_types" and
+ prev_shadow_root: "h \<turnstile> get_shadow_root element_ptr \<rightarrow>\<^sub>r None" and
+ h2: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h2" and
+ new_shadow_root_ptr: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr" and
+ h3: "h2 \<turnstile> set_mode new_shadow_root_ptr new_mode \<rightarrow>\<^sub>h h3" and
+ h': "h3 \<turnstile> set_shadow_root element_ptr (Some new_shadow_root_ptr) \<rightarrow>\<^sub>h h'"
+ using assms(4)
+ by(auto simp add: attach_shadow_root_def elim!: bind_returns_heap_E
+ bind_returns_heap_E2[rotated, OF get_tag_name_pure, rotated]
+ bind_returns_heap_E2[rotated, OF get_shadow_root_pure, rotated] split: if_splits)
+
+ have "h \<turnstile> attach_shadow_root element_ptr new_mode \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ thm bind_pure_returns_result_I[OF get_tag_name_pure]
+ apply(unfold attach_shadow_root_def)[1]
+ using element_tag_name
+ apply(rule bind_pure_returns_result_I[OF get_tag_name_pure])
+ apply(rule bind_pure_returns_result_I)
+ using \<open>element_tag_name \<in> safe_shadow_root_element_types\<close> apply(simp)
+ using \<open>element_tag_name \<in> safe_shadow_root_element_types\<close> apply(simp)
+ using prev_shadow_root
+ apply(rule bind_pure_returns_result_I[OF get_shadow_root_pure])
+ apply(rule bind_pure_returns_result_I)
+ apply(simp)
+ apply(simp)
+ using h2 new_shadow_root_ptr h3 h'
+ by(auto intro!: bind_returns_result_I intro: is_OK_returns_result_E[OF is_OK_returns_heap_I[OF h3]]
+ is_OK_returns_result_E[OF is_OK_returns_heap_I[OF h']])
+
+ have "new_shadow_root_ptr \<notin> set |h \<turnstile> shadow_root_ptr_kinds_M|\<^sub>r"
+ using new_shadow_root_ptr ShadowRootMonad.ptr_kinds_ptr_kinds_M h2
+ using new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_not_in_heap by blast
+ then have "cast new_shadow_root_ptr \<notin> set |h \<turnstile> document_ptr_kinds_M|\<^sub>r"
+ by simp
+ then have "cast new_shadow_root_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ by simp
+
+
+
+ have object_ptr_kinds_eq_h:
+ "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_shadow_root_ptr|}"
+ using new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_new_ptr h2 new_shadow_root_ptr by blast
+ then have document_ptr_kinds_eq_h:
+ "document_ptr_kinds h2 = document_ptr_kinds h |\<union>| {|cast new_shadow_root_ptr|}"
+ apply(simp add: document_ptr_kinds_def)
+ by force
+ then have shadow_root_ptr_kinds_eq_h:
+ "shadow_root_ptr_kinds h2 = shadow_root_ptr_kinds h |\<union>| {|new_shadow_root_ptr|}"
+ apply(simp add: shadow_root_ptr_kinds_def)
+ by force
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_mode_writes h3])
+ using set_mode_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ then have shadow_root_ptr_kinds_eq_h2: "shadow_root_ptr_kinds h3 = shadow_root_ptr_kinds h2"
+ by (auto simp add: shadow_root_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_shadow_root_writes h'])
+ using set_shadow_root_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ then have shadow_root_ptr_kinds_eq_h3: "shadow_root_ptr_kinds h' = shadow_root_ptr_kinds h3"
+ by (auto simp add: shadow_root_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+
+ have "known_ptr (cast new_shadow_root_ptr)"
+ using \<open>h \<turnstile> attach_shadow_root element_ptr new_mode \<rightarrow>\<^sub>r new_shadow_root_ptr\<close> create_shadow_root_known_ptr
+ by blast
+ then
+ have "known_ptrs h2"
+ using known_ptrs_new_ptr object_ptr_kinds_eq_h \<open>known_ptrs h\<close> h2
+ by blast
+ then
+ have "known_ptrs h3"
+ using known_ptrs_preserved object_ptr_kinds_eq_h2 by blast
+ then
+ show "known_ptrs h'"
+ using known_ptrs_preserved object_ptr_kinds_eq_h3 by blast
+
+ have "element_ptr |\<in>| element_ptr_kinds h"
+ by (meson \<open>h \<turnstile> attach_shadow_root element_ptr new_mode \<rightarrow>\<^sub>r new_shadow_root_ptr\<close> is_OK_returns_result_I
+ local.attach_shadow_root_element_ptr_in_heap)
+
+
+ have children_eq_h: "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_shadow_root_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads h2 get_child_nodes_new_shadow_root[rotated, OF new_shadow_root_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h:
+ "\<And>ptr'. ptr' \<noteq> cast new_shadow_root_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have object_ptr_kinds_eq_h:
+ "object_ptr_kinds h2 = object_ptr_kinds h |\<union>| {|cast new_shadow_root_ptr|}"
+ using new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_new_ptr h2 new_shadow_root_ptr object_ptr_kinds_eq_h by blast
+ then have node_ptr_kinds_eq_h:
+ "node_ptr_kinds h2 = node_ptr_kinds h"
+ apply(simp add: node_ptr_kinds_def)
+ by force
+ then have character_data_ptr_kinds_eq_h:
+ "character_data_ptr_kinds h2 = character_data_ptr_kinds h"
+ apply(simp add: character_data_ptr_kinds_def)
+ done
+ have element_ptr_kinds_eq_h: "element_ptr_kinds h2 = element_ptr_kinds h"
+ using object_ptr_kinds_eq_h
+ by(auto simp add: node_ptr_kinds_def element_ptr_kinds_def)
+ have document_ptr_kinds_eq_h: "document_ptr_kinds h2 = document_ptr_kinds h |\<union>| {|cast new_shadow_root_ptr|}"
+ using object_ptr_kinds_eq_h
+ apply(auto simp add: document_ptr_kinds_def)[1]
+ by (metis (full_types) document_ptr_kinds_def document_ptr_kinds_eq_h finsert_fsubset fset.map_comp funion_upper2)
+
+ have object_ptr_kinds_eq_h2: "object_ptr_kinds h3 = object_ptr_kinds h2"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_mode_writes h3])
+ using set_mode_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h2: "document_ptr_kinds h3 = document_ptr_kinds h2"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h2: "node_ptr_kinds h3 = node_ptr_kinds h2"
+ using object_ptr_kinds_eq_h2
+ by(auto simp add: node_ptr_kinds_def)
+ then have character_data_ptr_kinds_eq_h2: "character_data_ptr_kinds h3 = character_data_ptr_kinds h2"
+ by(simp add: character_data_ptr_kinds_def)
+ have element_ptr_kinds_eq_h2: "element_ptr_kinds h3 = element_ptr_kinds h2"
+ using node_ptr_kinds_eq_h2
+ by(simp add: element_ptr_kinds_def)
+
+ have object_ptr_kinds_eq_h3: "object_ptr_kinds h' = object_ptr_kinds h3"
+ apply(rule writes_small_big[where P="\<lambda>h h'. object_ptr_kinds h' = object_ptr_kinds h",
+ OF set_shadow_root_writes h'])
+ using set_shadow_root_pointers_preserved
+ by (auto simp add: reflp_def transp_def)
+ then have document_ptr_kinds_eq_h3: "document_ptr_kinds h' = document_ptr_kinds h3"
+ by (auto simp add: document_ptr_kinds_def)
+ have node_ptr_kinds_eq_h3: "node_ptr_kinds h' = node_ptr_kinds h3"
+ using object_ptr_kinds_eq_h3
+ by(auto simp add: node_ptr_kinds_def)
+ then have character_data_ptr_kinds_eq_h3: "character_data_ptr_kinds h' = character_data_ptr_kinds h3"
+ by(simp add: character_data_ptr_kinds_def)
+ have element_ptr_kinds_eq_h3: "element_ptr_kinds h' = element_ptr_kinds h3"
+ using node_ptr_kinds_eq_h3
+ by(simp add: element_ptr_kinds_def)
+
+
+ have children_eq_h: "\<And>(ptr'::(_) object_ptr) children. ptr' \<noteq> cast new_shadow_root_ptr
+ \<Longrightarrow> h \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads h2 get_child_nodes_new_shadow_root[rotated, OF new_shadow_root_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have children_eq2_h: "\<And>ptr'. ptr' \<noteq> cast new_shadow_root_ptr
+ \<Longrightarrow> |h \<turnstile> get_child_nodes ptr'|\<^sub>r = |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_child_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []"
+ using h2 local.new_shadow_root_no_child_nodes new_shadow_root_ptr by auto
+
+ have disconnected_nodes_eq_h:
+ "\<And>doc_ptr disc_nodes. doc_ptr \<noteq> cast new_shadow_root_ptr
+ \<Longrightarrow> h \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads h2
+ get_disconnected_nodes_new_shadow_root_different_pointers[rotated, OF new_shadow_root_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by (metis (no_types, lifting))+
+ then have disconnected_nodes_eq2_h:
+ "\<And>doc_ptr. doc_ptr \<noteq> cast new_shadow_root_ptr
+ \<Longrightarrow> |h \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+
+ have "h2 \<turnstile> get_disconnected_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []"
+ using h2 new_shadow_root_no_disconnected_nodes new_shadow_root_ptr by auto
+
+ have tag_name_eq_h:
+ "\<And>ptr' disc_nodes. h \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes
+ = h2 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using get_tag_name_reads h2
+ get_tag_name_new_shadow_root[OF new_shadow_root_ptr h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ by blast+
+ then have tag_name_eq2_h: "\<And>ptr'. |h \<turnstile> get_tag_name ptr'|\<^sub>r = |h2 \<turnstile> get_tag_name ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have children_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads set_mode_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_mode_get_child_nodes)
+ then have children_eq2_h2:
+ "\<And>ptr'. |h2 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h2:
+ "\<And>doc_ptr disc_nodes. h2 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_mode_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_mode_get_disconnected_nodes)
+ then have disconnected_nodes_eq2_h2:
+ "\<And>doc_ptr. |h2 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have tag_name_eq_h2:
+ "\<And>ptr' disc_nodes. h2 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes
+ = h3 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using get_tag_name_reads set_mode_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_mode_get_tag_name)
+ then have tag_name_eq2_h2: "\<And>ptr'. |h2 \<turnstile> get_tag_name ptr'|\<^sub>r = |h3 \<turnstile> get_tag_name ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "type_wf h2"
+ using \<open>type_wf h\<close> new_shadow_root_types_preserved h2 by blast
+ then have "type_wf h3"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_mode_writes h3]
+ using set_mode_types_preserved
+ by(auto simp add: reflp_def transp_def)
+ then show "type_wf h'"
+ using writes_small_big[where P="\<lambda>h h'. type_wf h \<longrightarrow> type_wf h'", OF set_shadow_root_writes h']
+ using set_shadow_root_types_preserved
+ by(auto simp add: reflp_def transp_def)
+
+ have children_eq_h3:
+ "\<And>ptr' children. h3 \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_child_nodes ptr' \<rightarrow>\<^sub>r children"
+ using CD.get_child_nodes_reads set_shadow_root_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_shadow_root_get_child_nodes)
+ then have children_eq2_h3:
+ " \<And>ptr'. |h3 \<turnstile> get_child_nodes ptr'|\<^sub>r = |h' \<turnstile> get_child_nodes ptr'|\<^sub>r"
+ using select_result_eq by force
+ have disconnected_nodes_eq_h3: "\<And>doc_ptr disc_nodes. h3 \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_disconnected_nodes doc_ptr \<rightarrow>\<^sub>r disc_nodes"
+ using get_disconnected_nodes_reads set_shadow_root_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_shadow_root_get_disconnected_nodes)
+ then have disconnected_nodes_eq2_h3: "\<And>doc_ptr. |h3 \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r = |h' \<turnstile> get_disconnected_nodes doc_ptr|\<^sub>r"
+ using select_result_eq by force
+ have tag_name_eq_h3:
+ "\<And>ptr' disc_nodes. h3 \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes
+ = h' \<turnstile> get_tag_name ptr' \<rightarrow>\<^sub>r disc_nodes"
+ using get_tag_name_reads set_shadow_root_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_shadow_root_get_tag_name)
+ then have tag_name_eq2_h3: "\<And>ptr'. |h3 \<turnstile> get_tag_name ptr'|\<^sub>r = |h' \<turnstile> get_tag_name ptr'|\<^sub>r"
+ using select_result_eq by force
+
+ have "acyclic (parent_child_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def CD.acyclic_heap_def)
+ also have "parent_child_rel h = parent_child_rel h2"
+ proof(auto simp add: CD.parent_child_rel_def)[1]
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h2"
+ by (simp add: object_ptr_kinds_eq_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h"
+ and 1: "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis ObjectMonad.ptr_kinds_ptr_kinds_M
+ \<open>cast new_shadow_root_ptr \<notin> set |h \<turnstile> object_ptr_kinds_M|\<^sub>r\<close> children_eq2_h)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "a |\<in>| object_ptr_kinds h"
+ using object_ptr_kinds_eq_h \<open>h2 \<turnstile> get_child_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto)
+ next
+ fix a x
+ assume 0: "a |\<in>| object_ptr_kinds h2"
+ and 1: "x \<in> set |h2 \<turnstile> get_child_nodes a|\<^sub>r"
+ then show "x \<in> set |h \<turnstile> get_child_nodes a|\<^sub>r"
+ by (metis (no_types, lifting) \<open>h2 \<turnstile> get_child_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []\<close>
+ children_eq2_h empty_iff empty_set image_eqI select_result_I2)
+ qed
+ also have "\<dots> = parent_child_rel h3"
+ by(auto simp add: CD.parent_child_rel_def object_ptr_kinds_eq_h2 children_eq2_h2)
+ also have "\<dots> = parent_child_rel h'"
+ by(auto simp add: CD.parent_child_rel_def object_ptr_kinds_eq_h3 children_eq2_h3)
+ finally have "CD.a_acyclic_heap h'"
+ by (simp add: CD.acyclic_heap_def)
+
+ have "CD.a_all_ptrs_in_heap h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_all_ptrs_in_heap h2"
+ apply(auto simp add: CD.a_all_ptrs_in_heap_def)[1]
+ using node_ptr_kinds_eq_h
+ \<open>h2 \<turnstile> get_child_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []\<close>
+ apply (metis (no_types, lifting) CD.get_child_nodes_ok CD.l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms \<open>known_ptrs h2\<close>
+ \<open>parent_child_rel h = parent_child_rel h2\<close> \<open>type_wf h2\<close> assms(1) assms(2) l_heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M.parent_child_rel_child
+ local.known_ptrs_known_ptr local.parent_child_rel_child_in_heap node_ptr_kinds_commutes returns_result_select_result)
+ by (metis (no_types, hide_lams) \<open>h2 \<turnstile> get_disconnected_nodes (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_shadow_root_ptr) \<rightarrow>\<^sub>r []\<close>
+ \<open>type_wf h2\<close> disconnected_nodes_eq_h empty_iff finite_set_in is_OK_returns_result_E is_OK_returns_result_I
+ local.get_disconnected_nodes_ok local.get_disconnected_nodes_ptr_in_heap node_ptr_kinds_eq_h select_result_I2
+ set_empty subset_code(1))
+ then have "CD.a_all_ptrs_in_heap h3"
+ by (simp add: children_eq2_h2 disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ CD.a_all_ptrs_in_heap_def node_ptr_kinds_eq_h2 object_ptr_kinds_eq_h2)
+ then have "CD.a_all_ptrs_in_heap h'"
+ by (simp add: children_eq2_h3 disconnected_nodes_eq2_h3 document_ptr_kinds_eq_h3
+ CD.a_all_ptrs_in_heap_def node_ptr_kinds_eq_h3 object_ptr_kinds_eq_h3)
+
+ have "cast new_shadow_root_ptr |\<notin>| document_ptr_kinds h"
+ using h2 new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_not_in_heap new_shadow_root_ptr shadow_root_ptr_kinds_commutes by blast
+
+ have "CD.a_distinct_lists h"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_distinct_lists h2"
+ using \<open>h2 \<turnstile> get_disconnected_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []\<close>
+ \<open>h2 \<turnstile> get_child_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []\<close>
+
+ apply(auto simp add: children_eq2_h[symmetric] CD.a_distinct_lists_def insort_split object_ptr_kinds_eq_h
+ document_ptr_kinds_eq_h disconnected_nodes_eq2_h intro!: distinct_concat_map_I)[1]
+ apply (metis distinct_sorted_list_of_set finite_fset sorted_list_of_set_insert)
+
+ apply(auto simp add: dest: distinct_concat_map_E)[1]
+ apply(auto simp add: dest: distinct_concat_map_E)[1]
+ using \<open>cast new_shadow_root_ptr |\<notin>| document_ptr_kinds h\<close>
+ apply(auto simp add: distinct_insort dest: distinct_concat_map_E)[1]
+
+ apply (metis (no_types) DocumentMonad.ptr_kinds_M_ptr_kinds DocumentMonad.ptr_kinds_ptr_kinds_M
+ concat_map_all_distinct disconnected_nodes_eq2_h select_result_I2)
+ proof -
+ fix x :: "(_) document_ptr" and y :: "(_) document_ptr" and xa :: "(_) node_ptr"
+ assume a1: "x \<noteq> y"
+ assume a2: "x |\<in>| document_ptr_kinds h"
+ assume a3: "x \<noteq> cast new_shadow_root_ptr"
+ assume a4: "y |\<in>| document_ptr_kinds h"
+ assume a5: "y \<noteq> cast new_shadow_root_ptr"
+ assume a6: "distinct (concat (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h)))))"
+ assume a7: "xa \<in> set |h2 \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ assume a8: "xa \<in> set |h2 \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ have f9: "xa \<in> set |h \<turnstile> get_disconnected_nodes x|\<^sub>r"
+ using a7 a3 disconnected_nodes_eq2_h
+ by (simp add: disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3)
+ have f10: "xa \<in> set |h \<turnstile> get_disconnected_nodes y|\<^sub>r"
+ using a8 a5 disconnected_nodes_eq2_h
+ by (simp add: disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3)
+ have f11: "y \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))"
+ using a4 by simp
+ have "x \<in> set (sorted_list_of_set (fset (document_ptr_kinds h)))"
+ using a2 by simp
+ then show False
+ using f11 f10 f9 a6 a1 by (meson disjoint_iff_not_equal distinct_concat_map_E(1))
+ next
+ fix x xa xb
+ assume 0: "h2 \<turnstile> get_disconnected_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []"
+ and 1: "h2 \<turnstile> get_child_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []"
+ and 2: "distinct (concat (map (\<lambda>ptr. |h \<turnstile> get_child_nodes ptr|\<^sub>r)
+ (sorted_list_of_set (fset (object_ptr_kinds h)))))"
+ and 3: "distinct (concat (map (\<lambda>document_ptr. |h \<turnstile> get_disconnected_nodes document_ptr|\<^sub>r)
+ (sorted_list_of_set (fset (document_ptr_kinds h)))))"
+ and 4: "(\<Union>x\<in>fset (object_ptr_kinds h). set |h \<turnstile> get_child_nodes x|\<^sub>r)
+ \<inter> (\<Union>x\<in>fset (document_ptr_kinds h). set |h \<turnstile> get_disconnected_nodes x|\<^sub>r) = {}"
+ and 5: "x \<in> set |h \<turnstile> get_child_nodes xa|\<^sub>r"
+ and 6: "x \<in> set |h2 \<turnstile> get_disconnected_nodes xb|\<^sub>r"
+ and 7: "xa |\<in>| object_ptr_kinds h"
+ and 8: "xa \<noteq> cast new_shadow_root_ptr"
+ and 9: "xb |\<in>| document_ptr_kinds h"
+ and 10: "xb \<noteq> cast new_shadow_root_ptr"
+ then show "False"
+ by (metis CD.distinct_lists_no_parent \<open>local.CD.a_distinct_lists h\<close> assms(2) disconnected_nodes_eq2_h
+ local.get_disconnected_nodes_ok returns_result_select_result)
+ qed
+ then have "CD.a_distinct_lists h3"
+ by(auto simp add: CD.a_distinct_lists_def disconnected_nodes_eq2_h2 document_ptr_kinds_eq_h2
+ children_eq2_h2 object_ptr_kinds_eq_h2)[1]
+ then have "CD.a_distinct_lists h'"
+ by(auto simp add: CD.a_distinct_lists_def disconnected_nodes_eq2_h3 children_eq2_h3
+ object_ptr_kinds_eq_h3 document_ptr_kinds_eq_h3 intro!: distinct_concat_map_I)
+
+ have "CD.a_owner_document_valid h"
+ using \<open>heap_is_wellformed h\<close> by (simp add: heap_is_wellformed_def CD.heap_is_wellformed_def)
+ then have "CD.a_owner_document_valid h'"
+ (* using disc_nodes_h3 \<open>document_ptr |\<in>| document_ptr_kinds h\<close> *)
+ apply(simp add: CD.a_owner_document_valid_def)
+ apply(simp add: object_ptr_kinds_eq_h object_ptr_kinds_eq_h3 )
+ apply(simp add: object_ptr_kinds_eq_h2)
+ apply(simp add: document_ptr_kinds_eq_h document_ptr_kinds_eq_h3 )
+ apply(simp add: document_ptr_kinds_eq_h2)
+ apply(simp add: node_ptr_kinds_eq_h node_ptr_kinds_eq_h3 )
+ apply(simp add: node_ptr_kinds_eq_h2 node_ptr_kinds_eq_h )
+ apply(auto simp add: children_eq2_h2[symmetric] children_eq2_h3[symmetric] disconnected_nodes_eq2_h
+ disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3)[1]
+ by (metis CD.get_child_nodes_ok CD.get_child_nodes_ptr_in_heap
+ \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_shadow_root_ptr |\<notin>| document_ptr_kinds h\<close> assms(2) assms(3) children_eq2_h
+ children_eq_h disconnected_nodes_eq2_h disconnected_nodes_eq2_h2 disconnected_nodes_eq2_h3
+ document_ptr_kinds_commutes finite_set_in is_OK_returns_result_I local.known_ptrs_known_ptr
+ returns_result_select_result)
+
+
+
+
+
+
+
+
+
+ have shadow_root_eq_h: "\<And>character_data_ptr shadow_root_opt. h \<turnstile> get_shadow_root character_data_ptr \<rightarrow>\<^sub>r shadow_root_opt =
+h2 \<turnstile> get_shadow_root character_data_ptr \<rightarrow>\<^sub>r shadow_root_opt"
+ using get_shadow_root_reads h2 get_shadow_root_new_shadow_root[rotated, OF h2]
+ apply(auto simp add: reads_def reflp_def transp_def preserved_def)[1]
+ using local.get_shadow_root_locs_impl new_shadow_root_ptr apply blast
+ using local.get_shadow_root_locs_impl new_shadow_root_ptr by blast
+
+
+ have shadow_root_eq_h2:
+ "\<And>ptr' children. h2 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children = h3 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children"
+ using get_shadow_root_reads set_mode_writes h3
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_mode_get_shadow_root)
+ have shadow_root_eq_h3:
+ "\<And>ptr' children. element_ptr \<noteq> ptr' \<Longrightarrow> h3 \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children = h' \<turnstile> get_shadow_root ptr' \<rightarrow>\<^sub>r children"
+ using get_shadow_root_reads set_shadow_root_writes h'
+ apply(rule reads_writes_preserved)
+ by(auto simp add: set_shadow_root_get_shadow_root_different_pointers)
+ have shadow_root_h3: "h' \<turnstile> get_shadow_root element_ptr \<rightarrow>\<^sub>r Some new_shadow_root_ptr"
+ using \<open>type_wf h3\<close> h' local.set_shadow_root_get_shadow_root by blast
+
+
+ have "a_all_ptrs_in_heap h"
+ by (simp add: assms(1) local.a_all_ptrs_in_heap_def local.get_shadow_root_shadow_root_ptr_in_heap)
+ then have "a_all_ptrs_in_heap h2"
+ apply(auto simp add: a_all_ptrs_in_heap_def shadow_root_ptr_kinds_eq_h)[1]
+ using returns_result_eq shadow_root_eq_h by fastforce
+ then have "a_all_ptrs_in_heap h3"
+ apply(auto simp add: a_all_ptrs_in_heap_def shadow_root_ptr_kinds_eq_h2)[1]
+ using shadow_root_eq_h2 by blast
+ then have "a_all_ptrs_in_heap h'"
+ apply(auto simp add: a_all_ptrs_in_heap_def shadow_root_ptr_kinds_eq_h3)[1]
+ apply(case_tac "shadow_root_ptr = new_shadow_root_ptr")
+ using h2 new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_in_heap new_shadow_root_ptr shadow_root_ptr_kinds_eq_h2
+ apply blast
+ using \<open>type_wf h3\<close> h' local.set_shadow_root_get_shadow_root returns_result_eq shadow_root_eq_h3
+ apply fastforce
+ done
+
+ have "a_distinct_lists h"
+ using assms(1)
+ by (simp add: heap_is_wellformed_def)
+ then have "a_distinct_lists h2"
+ apply(auto simp add: a_distinct_lists_def character_data_ptr_kinds_eq_h)[1]
+ apply(auto simp add: distinct_insort intro!: distinct_concat_map_I split: option.splits)[1]
+ by (metis \<open>type_wf h2\<close> assms(1) assms(2) local.get_shadow_root_ok local.shadow_root_same_host
+ returns_result_select_result shadow_root_eq_h)
+ then have "a_distinct_lists h3"
+ by(auto simp add: a_distinct_lists_def element_ptr_kinds_eq_h2 select_result_eq[OF shadow_root_eq_h2])
+ then have "a_distinct_lists h'"
+ apply(auto simp add: a_distinct_lists_def element_ptr_kinds_eq_h3 select_result_eq[OF shadow_root_eq_h3])[1]
+ apply(auto simp add: distinct_insort intro!: distinct_concat_map_I split: option.splits)[1]
+ by (smt \<open>type_wf h3\<close> assms(1) assms(2) h' h2 local.get_shadow_root_ok
+ local.get_shadow_root_shadow_root_ptr_in_heap local.set_shadow_root_get_shadow_root local.shadow_root_same_host
+ new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_not_in_heap new_shadow_root_ptr returns_result_select_result select_result_I2 shadow_root_eq_h
+ shadow_root_eq_h2 shadow_root_eq_h3)
+
+
+ have "a_shadow_root_valid h"
+ using assms(1)
+ by (simp add: heap_is_wellformed_def)
+ then
+ have "a_shadow_root_valid h'"
+ proof(unfold a_shadow_root_valid_def; safe)
+ fix shadow_root_ptr
+ assume "\<forall>shadow_root_ptr\<in>fset (shadow_root_ptr_kinds h). \<exists>host\<in>fset (element_ptr_kinds h).
+|h \<turnstile> get_tag_name host|\<^sub>r \<in> safe_shadow_root_element_types \<and> |h \<turnstile> get_shadow_root host|\<^sub>r = Some shadow_root_ptr"
+ assume "a_shadow_root_valid h"
+ assume "shadow_root_ptr \<in> fset (shadow_root_ptr_kinds h')"
+ show "\<exists>host\<in>fset (element_ptr_kinds h'). |h' \<turnstile> get_tag_name host|\<^sub>r \<in> safe_shadow_root_element_types \<and>
+|h' \<turnstile> get_shadow_root host|\<^sub>r = Some shadow_root_ptr"
+ proof (cases "shadow_root_ptr = new_shadow_root_ptr")
+ case True
+ have "element_ptr \<in> fset (element_ptr_kinds h')"
+ by (simp add: \<open>element_ptr |\<in>| element_ptr_kinds h\<close> element_ptr_kinds_eq_h element_ptr_kinds_eq_h2
+ element_ptr_kinds_eq_h3)
+ moreover have "|h' \<turnstile> get_tag_name element_ptr|\<^sub>r \<in> safe_shadow_root_element_types"
+ by (smt \<open>\<And>thesis. (\<And>h2 h3 new_shadow_root_ptr element_tag_name. \<lbrakk>h \<turnstile> get_tag_name element_ptr \<rightarrow>\<^sub>r element_tag_name;
+element_tag_name \<in> safe_shadow_root_element_types; h \<turnstile> get_shadow_root element_ptr \<rightarrow>\<^sub>r None; h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h2;
+h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr; h2 \<turnstile> set_mode new_shadow_root_ptr new_mode \<rightarrow>\<^sub>h h3;
+h3 \<turnstile> set_shadow_root element_ptr (Some new_shadow_root_ptr) \<rightarrow>\<^sub>h h'\<rbrakk> \<Longrightarrow> thesis) \<Longrightarrow> thesis\<close>
+ select_result_I2 tag_name_eq2_h tag_name_eq2_h2 tag_name_eq2_h3)
+ moreover have "|h' \<turnstile> get_shadow_root element_ptr|\<^sub>r = Some shadow_root_ptr"
+ using shadow_root_h3
+ by (simp add: True)
+ ultimately
+ show ?thesis
+ by meson
+ next
+ case False
+ then obtain host where host: "host \<in> fset (element_ptr_kinds h)" and
+ "|h \<turnstile> get_tag_name host|\<^sub>r \<in> safe_shadow_root_element_types" and
+ "|h \<turnstile> get_shadow_root host|\<^sub>r = Some shadow_root_ptr"
+ using \<open>shadow_root_ptr \<in> fset (shadow_root_ptr_kinds h')\<close>
+ using \<open>\<forall>shadow_root_ptr\<in>fset (shadow_root_ptr_kinds h). \<exists>host\<in>fset (element_ptr_kinds h).
+|h \<turnstile> get_tag_name host|\<^sub>r \<in> safe_shadow_root_element_types \<and> |h \<turnstile> get_shadow_root host|\<^sub>r = Some shadow_root_ptr\<close>
+ apply(simp add: shadow_root_ptr_kinds_eq_h3 shadow_root_ptr_kinds_eq_h2 shadow_root_ptr_kinds_eq_h)
+ by (meson finite_set_in)
+ moreover have "host \<noteq> element_ptr"
+ using calculation(3) prev_shadow_root by auto
+ ultimately show ?thesis
+ using element_ptr_kinds_eq_h3 element_ptr_kinds_eq_h2 element_ptr_kinds_eq_h
+ by (smt \<open>type_wf h'\<close> assms(2) finite_set_in local.get_shadow_root_ok returns_result_eq
+ returns_result_select_result shadow_root_eq_h shadow_root_eq_h2 shadow_root_eq_h3 tag_name_eq2_h
+ tag_name_eq2_h2 tag_name_eq2_h3)
+ qed
+ qed
+
+
+ have "a_host_shadow_root_rel h = a_host_shadow_root_rel h2"
+ by(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h select_result_eq[OF shadow_root_eq_h])
+ have "a_host_shadow_root_rel h2 = a_host_shadow_root_rel h3"
+ by(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h2 select_result_eq[OF shadow_root_eq_h2])
+ have "a_host_shadow_root_rel h' = {(cast element_ptr, cast new_shadow_root_ptr)} \<union> a_host_shadow_root_rel h3"
+ apply(auto simp add: a_host_shadow_root_rel_def element_ptr_kinds_eq_h3 )[1]
+ apply(case_tac "element_ptr \<noteq> aa")
+ using select_result_eq[OF shadow_root_eq_h3] apply (simp add: image_iff)
+ using select_result_eq[OF shadow_root_eq_h3]
+ apply (metis (no_types, lifting) \<open>local.a_host_shadow_root_rel h = local.a_host_shadow_root_rel h2\<close>
+ \<open>local.a_host_shadow_root_rel h2 = local.a_host_shadow_root_rel h3\<close> \<open>type_wf h3\<close> host_shadow_root_rel_def
+ i_get_parent_get_host_get_disconnected_document_wf.a_host_shadow_root_rel_shadow_root local.get_shadow_root_impl
+ local.get_shadow_root_ok option.distinct(1) prev_shadow_root returns_result_select_result)
+ apply (metis (mono_tags, lifting) \<open>\<And>ptr'. (\<And>x. element_ptr \<noteq> ptr') \<Longrightarrow>
+|h3 \<turnstile> get_shadow_root ptr'|\<^sub>r = |h' \<turnstile> get_shadow_root ptr'|\<^sub>r\<close> case_prod_conv image_iff
+ is_OK_returns_result_I mem_Collect_eq option.inject returns_result_eq returns_result_select_result
+ shadow_root_h3)
+ using element_ptr_kinds_eq_h3 local.get_shadow_root_ptr_in_heap shadow_root_h3 apply fastforce
+ apply (smt Shadow_DOM.a_host_shadow_root_rel_def \<open>\<And>ptr'. (\<And>x. element_ptr \<noteq> ptr') \<Longrightarrow>
+|h3 \<turnstile> get_shadow_root ptr'|\<^sub>r = |h' \<turnstile> get_shadow_root ptr'|\<^sub>r\<close> \<open>type_wf h3\<close> case_prodE case_prodI
+ i_get_root_node_si_wf.a_host_shadow_root_rel_shadow_root image_iff local.get_shadow_root_impl
+ local.get_shadow_root_ok mem_Collect_eq option.distinct(1) prev_shadow_root returns_result_eq
+ returns_result_select_result shadow_root_eq_h shadow_root_eq_h2)
+ done
+
+ have "a_ptr_disconnected_node_rel h = a_ptr_disconnected_node_rel h2"
+ apply(auto simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h)[1]
+ apply (metis (no_types, lifting) \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_shadow_root_ptr |\<notin>| document_ptr_kinds h\<close>
+ case_prodI disconnected_nodes_eq2_h mem_Collect_eq pair_imageI)
+ using \<open>h2 \<turnstile> get_disconnected_nodes (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_shadow_root_ptr) \<rightarrow>\<^sub>r []\<close>
+ apply auto[1]
+ apply(case_tac "cast new_shadow_root_ptr \<noteq> aa")
+ apply (simp add: disconnected_nodes_eq2_h image_iff)
+ using \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_shadow_root_ptr |\<notin>| document_ptr_kinds h\<close>
+ apply blast
+ done
+ have "a_ptr_disconnected_node_rel h2 = a_ptr_disconnected_node_rel h3"
+ by(simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h2 disconnected_nodes_eq2_h2)
+ have "a_ptr_disconnected_node_rel h3 = a_ptr_disconnected_node_rel h'"
+ by(simp add: a_ptr_disconnected_node_rel_def document_ptr_kinds_eq_h3 disconnected_nodes_eq2_h3)
+
+ have "acyclic (parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h)"
+ using \<open>heap_is_wellformed h\<close>
+ by (simp add: heap_is_wellformed_def)
+ have "parent_child_rel h \<union> a_host_shadow_root_rel h \<union> a_ptr_disconnected_node_rel h =
+parent_child_rel h2 \<union> a_host_shadow_root_rel h2 \<union> a_ptr_disconnected_node_rel h2"
+ using \<open>local.a_host_shadow_root_rel h = local.a_host_shadow_root_rel h2\<close>
+ \<open>local.a_ptr_disconnected_node_rel h = local.a_ptr_disconnected_node_rel h2\<close> \<open>parent_child_rel h = parent_child_rel h2\<close>
+ by auto
+ have "parent_child_rel h2 \<union> a_host_shadow_root_rel h2 \<union> a_ptr_disconnected_node_rel h2 =
+parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3"
+ using \<open>local.a_host_shadow_root_rel h2 = local.a_host_shadow_root_rel h3\<close>
+ \<open>local.a_ptr_disconnected_node_rel h2 = local.a_ptr_disconnected_node_rel h3\<close> \<open>parent_child_rel h2 = parent_child_rel h3\<close>
+ by auto
+ have "parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h' =
+{(cast element_ptr, cast new_shadow_root_ptr)} \<union> parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3"
+ by (simp add: \<open>local.a_host_shadow_root_rel h' =
+{(cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr, cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_shadow_root_ptr)} \<union> local.a_host_shadow_root_rel h3\<close>
+ \<open>local.a_ptr_disconnected_node_rel h3 = local.a_ptr_disconnected_node_rel h'\<close> \<open>parent_child_rel h3 = parent_child_rel h'\<close>)
+
+ have "\<And>a b. (a, b) \<in> parent_child_rel h3 \<Longrightarrow> a \<noteq> cast new_shadow_root_ptr"
+ using CD.parent_child_rel_parent_in_heap \<open>cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_shadow_root_ptr |\<notin>| document_ptr_kinds h\<close>
+ \<open>parent_child_rel h = parent_child_rel h2\<close> \<open>parent_child_rel h2 = parent_child_rel h3\<close> document_ptr_kinds_commutes
+ by blast
+ moreover
+ have "\<And>a b. (a, b) \<in> a_host_shadow_root_rel h3 \<Longrightarrow> a \<noteq> cast new_shadow_root_ptr"
+ using shadow_root_eq_h2
+ by(auto simp add: a_host_shadow_root_rel_def)
+ moreover
+ have "\<And>a b. (a, b) \<in> a_ptr_disconnected_node_rel h3 \<Longrightarrow> a \<noteq> cast new_shadow_root_ptr"
+ using \<open>h2 \<turnstile> get_disconnected_nodes (cast new_shadow_root_ptr) \<rightarrow>\<^sub>r []\<close>
+ by(auto simp add: a_ptr_disconnected_node_rel_def disconnected_nodes_eq_h2)
+ moreover
+ have "cast new_shadow_root_ptr \<notin> {x. (x, cast element_ptr) \<in>
+(parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3)\<^sup>*}"
+ by (smt Un_iff calculation(1) calculation(2) calculation(3) cast_document_ptr_not_node_ptr(2) converse_rtranclE mem_Collect_eq)
+ moreover
+ have "acyclic (parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3)"
+ using \<open>acyclic (parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> local.a_ptr_disconnected_node_rel h)\<close>
+ \<open>parent_child_rel h \<union> local.a_host_shadow_root_rel h \<union> local.a_ptr_disconnected_node_rel h =
+parent_child_rel h2 \<union> local.a_host_shadow_root_rel h2 \<union> local.a_ptr_disconnected_node_rel h2\<close>
+ \<open>parent_child_rel h2 \<union> local.a_host_shadow_root_rel h2 \<union> local.a_ptr_disconnected_node_rel h2 =
+parent_child_rel h3 \<union> local.a_host_shadow_root_rel h3 \<union> local.a_ptr_disconnected_node_rel h3\<close> by auto
+ ultimately have "acyclic (parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h')"
+ by(simp add: \<open>parent_child_rel h' \<union> a_host_shadow_root_rel h' \<union> a_ptr_disconnected_node_rel h' =
+{(cast element_ptr, cast new_shadow_root_ptr)} \<union>
+parent_child_rel h3 \<union> a_host_shadow_root_rel h3 \<union> a_ptr_disconnected_node_rel h3\<close>)
+
+ have "CD.a_heap_is_wellformed h'"
+ apply(simp add: CD.a_heap_is_wellformed_def)
+ by (simp add: \<open>local.CD.a_acyclic_heap h'\<close> \<open>local.CD.a_all_ptrs_in_heap h'\<close> \<open>local.CD.a_distinct_lists h'\<close>
+ \<open>local.CD.a_owner_document_valid h'\<close>)
+
+ show "heap_is_wellformed h' "
+ using \<open>acyclic (parent_child_rel h' \<union> local.a_host_shadow_root_rel h' \<union> local.a_ptr_disconnected_node_rel h')\<close>
+ by(simp add: heap_is_wellformed_def CD.heap_is_wellformed_impl \<open>local.CD.a_heap_is_wellformed h'\<close>
+ \<open>local.a_all_ptrs_in_heap h'\<close> \<open>local.a_distinct_lists h'\<close> \<open>local.a_shadow_root_valid h'\<close>)
+qed
+end
+
+interpretation l_attach_shadow_root_wf?: l_attach_shadow_root_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M known_ptr known_ptrs type_wf
+ get_child_nodes get_child_nodes_locs get_disconnected_nodes get_disconnected_nodes_locs
+ heap_is_wellformed parent_child_rel set_tag_name set_tag_name_locs set_disconnected_nodes
+ set_disconnected_nodes_locs create_element get_shadow_root get_shadow_root_locs get_tag_name
+ get_tag_name_locs heap_is_wellformed\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M get_host get_host_locs get_disconnected_document
+ get_disconnected_document_locs set_val set_val_locs create_character_data DocumentClass.known_ptr
+ DocumentClass.type_wf set_shadow_root set_shadow_root_locs set_mode set_mode_locs attach_shadow_root
+ by(auto simp add: l_attach_shadow_root_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_def instances)
+declare l_attach_shadow_root_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>D\<^sub>O\<^sub>M_axioms [instances]
+
+end
diff --git a/thys/Shadow_SC_DOM/Shadow_DOM_Tests.thy b/thys/Shadow_SC_DOM/Shadow_DOM_Tests.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/Shadow_DOM_Tests.thy
@@ -0,0 +1,42 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Shadow DOM Tests\<close>
+
+theory Shadow_DOM_Tests
+ imports
+ "tests/slots"
+ "tests/slots_fallback"
+ "tests/Shadow_DOM_Document_adoptNode"
+ "tests/Shadow_DOM_Document_getElementById"
+ "tests/Shadow_DOM_Node_insertBefore"
+ "tests/Shadow_DOM_Node_removeChild"
+begin
+end
diff --git a/thys/Shadow_SC_DOM/classes/ShadowRootClass.thy b/thys/Shadow_SC_DOM/classes/ShadowRootClass.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/classes/ShadowRootClass.thy
@@ -0,0 +1,499 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ ********************************************************************************\***)
+
+section \<open>The Shadow DOM Data Model\<close>
+
+theory ShadowRootClass
+ imports
+ Core_SC_DOM.ShadowRootPointer
+ Core_SC_DOM.DocumentClass
+begin
+
+subsection \<open>ShadowRoot\<close>
+
+datatype shadow_root_mode = Open | Closed
+record ('node_ptr, 'element_ptr, 'character_data_ptr) RShadowRoot =
+ "('node_ptr, 'element_ptr, 'character_data_ptr) RDocument" +
+ nothing :: unit
+ mode :: shadow_root_mode
+ child_nodes :: "('node_ptr, 'element_ptr, 'character_data_ptr) node_ptr list"
+type_synonym ('node_ptr, 'element_ptr, 'character_data_ptr, 'ShadowRoot) ShadowRoot
+ = "('node_ptr, 'element_ptr, 'character_data_ptr, 'ShadowRoot option) RShadowRoot_scheme"
+register_default_tvars "('node_ptr, 'element_ptr, 'character_data_ptr, 'ShadowRoot) ShadowRoot"
+type_synonym ('node_ptr, 'element_ptr, 'character_data_ptr, 'Document, 'ShadowRoot) Document
+ = "('node_ptr, 'element_ptr, 'character_data_ptr, ('node_ptr, 'element_ptr, 'character_data_ptr,
+'ShadowRoot option) RShadowRoot_ext + 'Document) Document"
+register_default_tvars "('node_ptr, 'element_ptr, 'character_data_ptr, 'Document, 'ShadowRoot) Document"
+type_synonym ('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Object, 'Node,
+ 'Element, 'CharacterData, 'Document,
+ 'ShadowRoot) Object
+ = "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Object, 'Node, 'Element,
+'CharacterData, ('node_ptr, 'element_ptr, 'character_data_ptr, 'ShadowRoot option)
+ RShadowRoot_ext + 'Document) Object"
+register_default_tvars "('node_ptr, 'element_ptr, 'character_data_ptr, 'shadow_root_ptr, 'Object,
+'Node, 'Element, 'CharacterData,
+ 'Document, 'ShadowRoot) Object"
+
+type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+ 'shadow_root_ptr, 'Object, 'Node,
+ 'Element, 'CharacterData, 'Document, 'ShadowRoot) heap
+ = "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr, 'shadow_root_ptr,
+'Object, 'Node, 'Element, 'CharacterData, ('node_ptr, 'element_ptr,
+ 'character_data_ptr, 'ShadowRoot option) RShadowRoot_ext + 'Document) heap"
+register_default_tvars "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+'shadow_root_ptr, 'Object,
+ 'Node, 'Element, 'CharacterData, 'Document, 'ShadowRoot) heap"
+type_synonym heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l = "(unit, unit, unit, unit, unit, unit, unit, unit, unit, unit, unit, unit) heap"
+
+
+
+definition shadow_root_ptr_kinds :: "(_) heap \<Rightarrow> (_) shadow_root_ptr fset"
+ where
+ "shadow_root_ptr_kinds heap =
+the |`| (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r |`| (ffilter is_shadow_root_ptr_kind (document_ptr_kinds heap)))"
+
+lemma shadow_root_ptr_kinds_simp [simp]:
+ "shadow_root_ptr_kinds (Heap (fmupd (cast shadow_root_ptr) shadow_root (the_heap h))) =
+{|shadow_root_ptr|} |\<union>| shadow_root_ptr_kinds h"
+ apply(auto simp add: shadow_root_ptr_kinds_def)[1]
+ by force
+
+definition shadow_root_ptrs :: "(_) heap \<Rightarrow> (_) shadow_root_ptr fset"
+ where
+ "shadow_root_ptrs heap = ffilter is_shadow_root_ptr (shadow_root_ptr_kinds heap)"
+
+definition cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_) Document \<Rightarrow> (_) ShadowRoot option"
+ where
+ "cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t document = (case RDocument.more document of Some (Inl shadow_root) \<Rightarrow>
+Some (RDocument.extend (RDocument.truncate document) shadow_root) | _ \<Rightarrow> None)"
+adhoc_overloading cast cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+
+abbreviation cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_) Object \<Rightarrow> (_) ShadowRoot option"
+ where
+ "cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t obj \<equiv> (case cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t obj of
+Some document \<Rightarrow> cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t document | None \<Rightarrow> None)"
+adhoc_overloading cast cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+
+definition cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) ShadowRoot \<Rightarrow> (_) Document"
+ where
+ "cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t shadow_root = RDocument.extend (RDocument.truncate shadow_root)
+(Some (Inl (RDocument.more shadow_root)))"
+adhoc_overloading cast cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+
+abbreviation cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t :: "(_) ShadowRoot \<Rightarrow> (_) Object"
+ where
+ "cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr \<equiv> cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr)"
+adhoc_overloading cast cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+consts is_shadow_root_kind :: 'a
+definition is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t :: "(_) Document \<Rightarrow> bool"
+ where
+ "is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr \<longleftrightarrow> cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr \<noteq> None"
+
+adhoc_overloading is_shadow_root_kind is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+lemmas is_shadow_root_kind_def = is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+
+abbreviation is_shadow_root_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t :: "(_) Object \<Rightarrow> bool"
+ where
+ "is_shadow_root_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr \<equiv> cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr \<noteq> None"
+adhoc_overloading is_shadow_root_kind is_shadow_root_kind\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+
+definition get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_) shadow_root_ptr \<Rightarrow> (_) heap \<Rightarrow> (_) ShadowRoot option"
+ where
+ "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Option.bind (get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t (cast shadow_root_ptr) h) cast"
+adhoc_overloading get get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+
+locale l_type_wf_def\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+begin
+definition a_type_wf :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_type_wf h = (DocumentClass.type_wf h \<and> (\<forall>shadow_root_ptr \<in> fset (shadow_root_ptr_kinds h)
+ .get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h \<noteq> None))"
+end
+global_interpretation l_type_wf_def\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t defines type_wf = a_type_wf .
+lemmas type_wf_defs = a_type_wf_def
+
+locale l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t = l_type_wf type_wf for type_wf :: "((_) heap \<Rightarrow> bool)" +
+ assumes type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t: "type_wf h \<Longrightarrow> ShadowRootClass.type_wf h"
+
+sublocale l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t \<subseteq> l_type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ apply(unfold_locales)
+ using DocumentClass.a_type_wf_def
+ by (meson ShadowRootClass.a_type_wf_def l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_axioms l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
+
+locale l_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas = l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+begin
+sublocale l_get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_lemmas by unfold_locales
+
+lemma get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_type_wf:
+ assumes "type_wf h"
+ shows "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h \<longleftrightarrow> get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h \<noteq> None"
+proof
+ assume "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ then
+ show "get shadow_root_ptr h \<noteq> None"
+ using l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_axioms[unfolded l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def type_wf_defs] assms
+ by (meson notin_fset)
+next
+ assume "get shadow_root_ptr h \<noteq> None"
+ then
+ show "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ apply(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def shadow_root_ptr_kinds_def
+ document_ptr_kinds_def object_ptr_kinds_def
+ split: Option.bind_splits)[1]
+ by (metis comp_eq_dest_lhs document_ptr_casts_commute2 document_ptr_document_ptr_cast
+ ffmember_filter fimageI fmdomI is_shadow_root_ptr_kind_cast option.sel
+ shadow_root_ptr_casts_commute2)
+qed
+end
+
+global_interpretation l_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas type_wf
+ by unfold_locales
+
+definition put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_) shadow_root_ptr \<Rightarrow> (_) ShadowRoot \<Rightarrow> (_) heap \<Rightarrow> (_) heap"
+ where
+ "put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr shadow_root = put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t (cast shadow_root_ptr) (cast shadow_root)"
+adhoc_overloading put put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+
+lemma put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_in_heap:
+ assumes "put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr shadow_root h = h'"
+ shows "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h'"
+ using assms
+ unfolding put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def shadow_root_ptr_kinds_def
+ by (metis ffmember_filter fimage_eqI is_shadow_root_ptr_kind_cast option.sel
+ put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_in_heap shadow_root_ptr_casts_commute2)
+
+lemma put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_put_ptrs:
+ assumes "put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr shadow_root h = h'"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast shadow_root_ptr|}"
+ using assms
+ by (simp add: put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_put_ptrs)
+
+
+
+lemma cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_inject [simp]:
+ "cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t x = cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t y \<longleftrightarrow> x = y"
+ apply(auto simp add: cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RObject.extend_def RDocument.extend_def
+ RDocument.truncate_def)[1]
+ by (metis RDocument.select_convs(5) RShadowRoot.surjective old.unit.exhaust)
+
+lemma cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_none [simp]:
+ "cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t document = None \<longleftrightarrow> \<not> (\<exists>shadow_root. cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t shadow_root = document)"
+ apply(auto simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RObject.extend_def
+ RDocument.extend_def RDocument.truncate_def
+ split: sum.splits option.splits)[1]
+ by (metis (mono_tags, lifting) RDocument.select_convs(2) RDocument.select_convs(3)
+ RDocument.select_convs(4) RDocument.select_convs(5) RDocument.surjective old.unit.exhaust)
+
+
+lemma cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_some [simp]:
+ "cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t document = Some shadow_root \<longleftrightarrow> cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t shadow_root = document"
+ apply(auto simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RObject.extend_def
+ RDocument.extend_def RDocument.truncate_def
+ split: sum.splits option.splits)[1]
+ by (metis RDocument.select_convs(5) RShadowRoot.surjective old.unit.exhaust)
+
+
+lemma cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_inv [simp]:
+ "cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t (cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t shadow_root) = Some shadow_root"
+ by simp
+
+lemma is_shadow_root_kind_doctype [simp]:
+ "is_shadow_root_kind x \<longleftrightarrow> is_shadow_root_kind (doctype_update (\<lambda>_. v) x)"
+ apply(auto simp add: is_shadow_root_kind_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def
+ RDocument.truncate_def split: option.splits)[1]
+ apply (metis RDocument.ext_inject RDocument.select_convs(3) RDocument.surjective RObject.ext_inject)
+ by (smt RDocument.select_convs(2) RDocument.select_convs(3) RDocument.select_convs(4)
+ RDocument.select_convs(5) RDocument.surjective RDocument.update_convs(2) old.unit.exhaust)
+
+lemma is_shadow_root_kind_document_element [simp]:
+ "is_shadow_root_kind x \<longleftrightarrow> is_shadow_root_kind (document_element_update (\<lambda>_. v) x)"
+ apply(auto simp add: is_shadow_root_kind_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def
+ RDocument.truncate_def split: option.splits)[1]
+ apply (metis RDocument.ext_inject RDocument.select_convs(3) RDocument.surjective RObject.ext_inject)
+ by (metis (no_types, lifting) RDocument.ext_inject RDocument.surjective RDocument.update_convs(3)
+ RObject.select_convs(1) RObject.select_convs(2))
+
+lemma is_shadow_root_kind_disconnected_nodes [simp]:
+ "is_shadow_root_kind x \<longleftrightarrow> is_shadow_root_kind (disconnected_nodes_update (\<lambda>_. v) x)"
+ apply(auto simp add: is_shadow_root_kind_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def
+ RDocument.truncate_def split: option.splits)[1]
+ apply (metis RDocument.ext_inject RDocument.select_convs(3) RDocument.surjective RObject.ext_inject)
+ by (metis (no_types, lifting) RDocument.ext_inject RDocument.surjective RDocument.update_convs(4)
+ RObject.select_convs(1) RObject.select_convs(2))
+
+lemma shadow_root_ptr_kinds_commutes [simp]:
+ "cast shadow_root_ptr |\<in>| document_ptr_kinds h \<longleftrightarrow> shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ apply(auto simp add: document_ptr_kinds_def shadow_root_ptr_kinds_def)[1]
+ by (metis (no_types, lifting) shadow_root_ptr_casts_commute2 ffmember_filter fimage_eqI
+ fset.map_comp is_shadow_root_ptr_kind_none document_ptr_casts_commute3
+ document_ptr_kinds_commutes document_ptr_kinds_def option.sel option.simps(3))
+
+lemma get_shadow_root_ptr_simp1 [simp]:
+ "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr shadow_root h) = Some shadow_root"
+ by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
+lemma get_shadow_root_ptr_simp2 [simp]:
+ "shadow_root_ptr \<noteq> shadow_root_ptr'
+ \<Longrightarrow> get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' shadow_root h) =
+get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h"
+ by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
+
+lemma get_shadow_root_ptr_simp3 [simp]:
+ "get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr f h) = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h"
+ by(auto simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+lemma get_shadow_root_ptr_simp4 [simp]:
+ "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr f h) = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h"
+ by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+lemma get_shadow_root_ptr_simp5 [simp]:
+ "get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr f h) = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h"
+ by(auto simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+lemma get_shadow_root_ptr_simp6 [simp]:
+ "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr f h) = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h"
+ by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def put\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+
+lemma get_shadow_root_put_document [simp]:
+ "cast shadow_root_ptr \<noteq> document_ptr
+ \<Longrightarrow> get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr document h) = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h"
+ by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
+lemma get_document_put_shadow_root [simp]:
+ "document_ptr \<noteq> cast shadow_root_ptr
+ \<Longrightarrow> get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr (put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr shadow_root h) = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h"
+ by(auto simp add: put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
+
+lemma new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t [simp]:
+ assumes "new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_element_ptr, h')"
+ shows "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
+
+lemma new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t [simp]:
+ assumes "new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a h = (new_character_data_ptr, h')"
+ shows "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def Let_def)
+
+lemma new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t [simp]:
+ assumes "new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t h = (new_document_ptr, h')"
+ assumes "cast ptr \<noteq> new_document_ptr"
+ shows "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def)
+
+
+abbreviation "create_shadow_root_obj mode_arg child_nodes_arg
+ \<equiv> \<lparr> RObject.nothing = (), RDocument.nothing = (), RDocument.doctype = ''html'',
+RDocument.document_element = None, RDocument.disconnected_nodes = [], RShadowRoot.nothing = (),
+mode = mode_arg, RShadowRoot.child_nodes = child_nodes_arg, \<dots> = None \<rparr>"
+
+definition new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_)heap \<Rightarrow> ((_) shadow_root_ptr \<times> (_) heap)"
+ where
+ "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (let new_shadow_root_ptr = shadow_root_ptr.Ref
+(Suc (fMax (shadow_root_ptr.the_ref |`| (shadow_root_ptrs h)))) in
+ (new_shadow_root_ptr, put new_shadow_root_ptr (create_shadow_root_obj Open []) h))"
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_in_heap:
+ assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
+ shows "new_shadow_root_ptr |\<in>| shadow_root_ptr_kinds h'"
+ using assms
+ unfolding new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def
+ using put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_in_heap by blast
+
+lemma new_shadow_root_ptr_new: "shadow_root_ptr.Ref
+(Suc (fMax (finsert 0 (shadow_root_ptr.the_ref |`| shadow_root_ptrs h)))) |\<notin>| shadow_root_ptrs h"
+ by (metis Suc_n_not_le_n shadow_root_ptr.sel(1) fMax_ge fimage_finsert finsertI1 finsertI2
+ set_finsert)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_not_in_heap:
+ assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
+ shows "new_shadow_root_ptr |\<notin>| shadow_root_ptr_kinds h"
+ using assms
+ apply(auto simp add: Let_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def shadow_root_ptr_kinds_def)[1]
+ by (metis Suc_n_not_le_n fMax_ge ffmember_filter fimageI is_shadow_root_ptr_ref
+ shadow_root_ptr.disc(1) shadow_root_ptr.exhaust shadow_root_ptr.is_Ref_def shadow_root_ptr.sel(1)
+ shadow_root_ptr.simps(4) shadow_root_ptr_casts_commute3 shadow_root_ptr_kinds_commutes
+ shadow_root_ptrs_def)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_new_ptr:
+ assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_shadow_root_ptr|}"
+ using assms
+ by (metis Pair_inject new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_put_ptrs)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_is_shadow_root_ptr:
+ assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
+ shows "is_shadow_root_ptr new_shadow_root_ptr"
+ using assms
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def)
+
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t [simp]:
+ assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
+ assumes "ptr \<noteq> cast new_shadow_root_ptr"
+ shows "get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h = get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>N\<^sub>o\<^sub>d\<^sub>e [simp]:
+ assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
+ shows "get\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr h = get\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr h'"
+ using assms
+ apply(simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+ by(auto simp add: get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t [simp]:
+ assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
+ shows "get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a [simp]:
+ assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
+ shows "get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr h = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t [simp]:
+ assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
+ assumes "ptr \<noteq> cast new_shadow_root_ptr"
+ shows "get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr h'"
+ using assms
+ apply(simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+ by(auto simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t [simp]:
+ assumes "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h = (new_shadow_root_ptr, h')"
+ assumes "ptr \<noteq> new_shadow_root_ptr"
+ shows "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h'"
+ using assms
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def)
+
+
+locale l_known_ptr\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+begin
+definition a_known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+ where
+ "a_known_ptr ptr = (known_ptr ptr \<or> is_shadow_root_ptr ptr)"
+
+lemma known_ptr_not_shadow_root_ptr: "a_known_ptr ptr \<Longrightarrow> \<not>is_shadow_root_ptr ptr \<Longrightarrow> known_ptr ptr"
+ by(simp add: a_known_ptr_def)
+lemma known_ptr_new_shadow_root_ptr: "a_known_ptr ptr \<Longrightarrow> \<not>known_ptr ptr \<Longrightarrow> is_shadow_root_ptr ptr"
+ using l_known_ptr\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t.known_ptr_not_shadow_root_ptr by blast
+
+end
+global_interpretation l_known_ptr\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t defines known_ptr = a_known_ptr .
+lemmas known_ptr_defs = a_known_ptr_def
+
+locale l_known_ptrs\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t = l_known_ptr known_ptr for known_ptr :: "(_) object_ptr \<Rightarrow> bool"
+begin
+definition a_known_ptrs :: "(_) heap \<Rightarrow> bool"
+ where
+ "a_known_ptrs h = (\<forall>ptr \<in> fset (object_ptr_kinds h). known_ptr ptr)"
+
+lemma known_ptrs_known_ptr: "a_known_ptrs h \<Longrightarrow> ptr |\<in>| object_ptr_kinds h \<Longrightarrow> known_ptr ptr"
+ apply(simp add: a_known_ptrs_def)
+ using notin_fset by fastforce
+
+lemma known_ptrs_preserved:
+ "object_ptr_kinds h = object_ptr_kinds h' \<Longrightarrow> a_known_ptrs h = a_known_ptrs h'"
+ by(auto simp add: a_known_ptrs_def)
+lemma known_ptrs_subset:
+ "object_ptr_kinds h' |\<subseteq>| object_ptr_kinds h \<Longrightarrow> a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def less_eq_fset.rep_eq subsetD)
+lemma known_ptrs_new_ptr:
+ "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|new_ptr|} \<Longrightarrow> known_ptr new_ptr \<Longrightarrow>
+a_known_ptrs h \<Longrightarrow> a_known_ptrs h'"
+ by(simp add: a_known_ptrs_def)
+end
+global_interpretation l_known_ptrs\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t known_ptr defines known_ptrs = a_known_ptrs .
+lemmas known_ptrs_defs = a_known_ptrs_def
+
+lemma known_ptrs_is_l_known_ptrs [instances]: "l_known_ptrs known_ptr known_ptrs"
+ using known_ptrs_known_ptr known_ptrs_preserved l_known_ptrs_def known_ptrs_subset known_ptrs_new_ptr
+ by blast
+
+lemma known_ptrs_implies: "DocumentClass.known_ptrs h \<Longrightarrow> ShadowRootClass.known_ptrs h"
+ by(auto simp add: DocumentClass.known_ptrs_defs DocumentClass.known_ptr_defs
+ ShadowRootClass.known_ptrs_defs ShadowRootClass.known_ptr_defs)
+
+definition delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t :: "(_) shadow_root_ptr \<Rightarrow> (_) heap \<Rightarrow> (_) heap option" where
+ "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr = delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast shadow_root_ptr)"
+
+lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_pointer_removed:
+ assumes "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = Some h'"
+ shows "ptr |\<notin>| shadow_root_ptr_kinds h'"
+ using assms
+ by(auto simp add: delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_pointer_removed delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def shadow_root_ptr_kinds_def
+ document_ptr_kinds_def split: if_splits)
+
+lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_pointer_ptr_in_heap:
+ assumes "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h = Some h'"
+ shows "ptr |\<in>| shadow_root_ptr_kinds h"
+ using assms
+ apply(auto simp add: delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_pointer_ptr_in_heap delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def split: if_splits)[1]
+ using delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_pointer_ptr_in_heap
+ by fastforce
+
+lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok:
+ assumes "ptr |\<in>| shadow_root_ptr_kinds h"
+ shows "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr h \<noteq> None"
+ using assms
+ by (simp add: delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_ok delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
+
+lemma shadow_root_delete_get_1 [simp]:
+ "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow> get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h' = None"
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ split: if_splits)
+lemma shadow_root_delete_get_2 [simp]:
+ "shadow_root_ptr \<noteq> shadow_root_ptr' \<Longrightarrow> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' h = Some h' \<Longrightarrow>
+get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h' = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h"
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def
+ split: if_splits)
+
+
+lemma shadow_root_delete_get_3 [simp]:
+ "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow> object_ptr \<noteq> cast shadow_root_ptr \<Longrightarrow>
+get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr h' = get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr h"
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: if_splits)
+lemma shadow_root_delete_get_4 [simp]: "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow>
+get\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr h' = get\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr h"
+ by(auto simp add: get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def)
+lemma shadow_root_delete_get_5 [simp]: "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow>
+get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h' = get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr h"
+ by(simp add: get\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+lemma shadow_root_delete_get_6 [simp]: "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow>
+get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h' = get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr h"
+ by(simp add: get\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_def)
+lemma shadow_root_delete_get_7 [simp]:
+ "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow> document_ptr \<noteq> cast shadow_root_ptr \<Longrightarrow>
+get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h' = get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr h"
+ by(simp add: get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def)
+lemma shadow_root_delete_get_8 [simp]:
+ "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h = Some h' \<Longrightarrow> shadow_root_ptr' \<noteq> shadow_root_ptr \<Longrightarrow>
+get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' h' = get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' h"
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: if_splits)
+end
diff --git a/thys/Shadow_SC_DOM/document/root.bib b/thys/Shadow_SC_DOM/document/root.bib
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/document/root.bib
@@ -0,0 +1,601 @@
+@STRING{j-fac = "Formal Aspects of Computing" }
+@STRING{pub-springer={Springer-Verlag} }
+@STRING{pub-springer:adr={Heidelberg} }
+@STRING{s-lncs = "Lecture Notes in Computer Science" }
+
+@Book{ nipkow.ea:isabelle:2002,
+ author = {Tobias Nipkow and Lawrence C. Paulson and Markus Wenzel},
+ title = {Isabelle/HOL---A Proof Assistant for Higher-Order Logic},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ volume = 2283,
+ doi = {10.1007/3-540-45949-9},
+ abstract = {This book is a self-contained introduction to interactive proof in higher-order logic (HOL), using
+ the proof assistant Isabelle2002. It is a tutorial for potential users rather than a monograph for
+ researchers. The book has three parts.
+
+ 1. Elementary Techniques shows how to model functional programs in higher-order logic. Early examples
+ involve lists and the natural numbers. Most proofs are two steps long, consisting of induction on a
+ chosen variable followed by the auto tactic. But even this elementary part covers such advanced topics
+ as nested and mutual recursion. 2. Logic and Sets presents a collection of lower-level tactics that
+ you can use to apply rules selectively. It also describes Isabelle/HOL's treatment of sets, functions
+ and relations and explains how to define sets inductively. One of the examples concerns the theory of
+ model checking, and another is drawn from a classic textbook on formal languages. 3. Advanced Material
+ describes a variety of other topics. Among these are the real numbers, records and overloading.
+ Advanced techniques are described involving induction and recursion. A whole chapter is devoted to an
+ extended example: the verification of a security protocol. },
+ year = 2002,
+ acknowledgement={brucker, 2007-02-19},
+ bibkey = {nipkow.ea:isabelle:2002}
+}
+
+@Misc{ dom-specification,
+ year = 2016,
+ month = {DOM Living Standard -- Last Updated 20 October 2016},
+ day = 20,
+ url = {https://dom.spec.whatwg.org/},
+ organization = {Web Hypertext Application Technology Working Group (WHATWG)},
+ note = {An archived copy of the version from 20 October 2016 is available at
+ \url{https://git.logicalhacking.com/BrowserSecurity/fDOM-idl/}.}
+}
+
+@InProceedings{ brucker.ea:core-dom:2018,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {A Formal Semantics of the Core {DOM} in {Isabelle/HOL}},
+ booktitle = {Proceedings of the Web Programming, Design, Analysis, And Implementation (WPDAI) track at WWW 2018},
+ location = {Lyon, France},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-fdom-2018},
+ year = 2018,
+ abstract = {At its core, the Document Object Model (DOM) defines a tree-like data structure for representing
+ documents in general and HTML documents in particular. It forms the heart of any rendering engine of
+ modern web browsers. Formalizing the key concepts of the DOM is a pre-requisite for the formal
+ reasoning over client-side JavaScript programs as well as for the analysis of security concepts in
+ modern web browsers. In this paper, 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. },
+ keywords = {Document Object Model, DOM, Formal Semantics, Isabelle/HOL},
+ classification= {conference},
+ areas = {formal methods, software},
+ public = {yes}
+}
+
+@Article{ klein:operating:2009,
+ author = {Gerwin Klein},
+ title = {Operating System Verification --- An Overview},
+ journal = {S\={a}dhan\={a}},
+ publisher = pub-springer,
+ year = 2009,
+ volume = 34,
+ number = 1,
+ month = feb,
+ pages = {27--69},
+ abstract = {This paper gives a high-level introduction to the topic of formal, interactive, machine-checked
+ software verification in general, and the verification of operating systems code in particular. We
+ survey the state of the art, the advantages and limitations of machine-checked code proofs, and
+ describe two specific ongoing larger-scale verification projects in more detail.}
+}
+
+@InProceedings{ gardner.ea:securing:2009,
+ author = {Ryan W. Gardner and Sujata Garera and Matthew W. Pagano and Matthew Green and Aviel D. Rubin},
+ title = {Securing medical records on smart phones},
+ booktitle = {ACM workshop on Security and privacy in medical and home-care systems (SPIMACS)},
+ year = 2009,
+ isbn = {978-1-60558-790-5},
+ pages = {31--40},
+ location = {Chicago, Illinois, USA},
+ doi = {10.1145/1655084.1655090},
+ address = pub-acm:adr,
+ publisher = pub-acm,
+ abstract = {There is an inherent conflict between the desire to maintain privacy of one's medical records and the
+ need to make those records available during an emergency. To satisfy both objectives, we introduce a
+ flexible architecture for the secure storage of medical records on smart phones. In our system, a
+ person can view her records at any time, and emergency medical personnel can view the records as long
+ as the person is present (even if she is unconscious). Our solution allows for efficient revocation of
+ access rights and is robust against adversaries who can access the phone's storage offline.}
+}
+
+@InProceedings{ raad.ea:dom:2016,
+ author = {Azalea Raad and Jos{\'{e}} Fragoso Santos and Philippa Gardner},
+ title = {{DOM:} Specification and Client Reasoning},
+ booktitle = {Programming Languages and Systems - 14th Asian Symposium, {APLAS} 2016, Hanoi, Vietnam, November
+ 21-23, 2016, Proceedings},
+ pages = {401--422},
+ year = 2016,
+ crossref = {igarashi:programming:2016},
+ doi = {10.1007/978-3-319-47958-3_21},
+ abstract = {We present an axiomatic specification of a key fragment of DOM using structural separation logic.
+ This specification allows us to develop modular reasoning about client programs that call the DOM.}
+}
+
+@InProceedings{ bohannon.ea:featherweight:2010,
+ author = {Aaron Bohannon and Benjamin C. Pierce},
+ title = {Featherweight {F}irefox: {F}ormalizing the Core of a Web Browser},
+ booktitle = {Usenix Conference on Web Application Development (WebApps)},
+ year = 2010,
+ month = jun,
+ url = {http://www.cis.upenn.edu/~bohannon/browser-model/},
+ abstract = {We offer a formal specification of the core functionality of a web browser in the form of a
+ small-step operational semantics. The specification accurately models the asyn- chronous nature of web
+ browsers and covers the basic as- pects of windows, DOM trees, cookies, HTTP requests and responses,
+ user input, and a minimal scripting lan- guage with first-class functions, dynamic evaluation, and
+ AJAX requests. No security enforcement mechanisms are included{\^a}instead, the model is intended to
+ serve as a basis for formalizing and experimenting with different security policies and mechanisms. We
+ survey the most interesting design choices and discuss how our model re- lates to real web browsers.}
+}
+
+@Proceedings{ joyce.ea:higher:1994,
+ editor = {Jeffrey J. Joyce and Carl-Johan H. Seger},
+ title = {Higher Order Logic Theorem Proving and Its Applications (HUG)},
+ booktitle = {Higher Order Logic Theorem Proving and Its Applications (HUG)},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ abstract = {Theorem proving based techniques for formal hardware verification have been evolving constantly and
+ researchers are getting able to reason about more complex issues than it was possible or practically
+ feasible in the past. It is often the case that a model of a system is built in a formal logic and
+ then reasoning about this model is carried out in the logic. Concern is growing on how to consistently
+ interface a model built in a formal logic with an informal CAD environment. Researchers have been
+ investigating how to define the formal semantics of hardware description languages so that one can
+ formally reason about models informally dealt with in a CAD environment. At the University of
+ Cambridge, the embedding of hardware description languages in a logic is classified in two categories:
+ deep embedding and shallow embedding. In this paper we argue that there are degrees of formality in
+ shallow embedding a language in a logic. The choice of the degree of formality is a trade-off between
+ the security of the embedding and the amount and complexity of the proof effort in the logic. We also
+ argue that the design of a language could consider this verifiability issue. There are choices in the
+ design of a language that can make it easier to improve the degree of formality, without implying
+ serious drawbacks for the CAD environment.},
+ volume = 780,
+ year = 1994,
+ doi = {10.1007/3-540-57826-9},
+ isbn = {3-540-57826-9},
+ acknowledgement={brucker, 2007-02-19}
+}
+
+@Misc{ whatwg:dom:2017,
+ key = {whatwg},
+ author = {{WHATWG}},
+ url = {https://dom.spec.whatwg.org/commit-snapshots/6253e53af2fbfaa6d25ad09fd54280d8083b2a97/},
+ month = mar,
+ year = 2017,
+ day = 24,
+ title = {{DOM} -- Living Standard},
+ note = {Last Updated 24 {March} 2017},
+ institution = {WHATWG}
+}
+
+@Misc{ whatwg:html:2017,
+ key = {whatwg},
+ author = {{WHATWG}},
+ url = {https://html.spec.whatwg.org/},
+ month = apr,
+ year = 2017,
+ day = 13,
+ title = {{HTML} -- Living Standard},
+ note = {Last Updated 13 {April} 2017},
+ institution = {WHATWG}
+}
+
+@Misc{ w3c:dom:2015,
+ key = {w3c},
+ author = {{W3C}},
+ url = {https://www.w3.org/TR/dom/},
+ month = nov,
+ year = 2015,
+ day = 19,
+ title = {{W3C} {DOM4}},
+ institution = {W3C}
+}
+
+@Proceedings{ igarashi:programming:2016,
+ editor = {Atsushi Igarashi},
+ title = {Programming Languages and Systems - 14th Asian Symposium, {APLAS} 2016, Hanoi, Vietnam, November
+ 21-23, 2016, Proceedings},
+ series = {Lecture Notes in Computer Science},
+ volume = 10017,
+ year = 2016,
+ doi = {10.1007/978-3-319-47958-3},
+ isbn = {978-3-319-47957-6}
+}
+
+@InProceedings{ gardner.ea:dom:2008,
+ author = {Philippa Gardner and Gareth Smith and Mark J. Wheelhouse and Uri Zarfaty},
+ title = {{DOM:} Towards a Formal Specification},
+ booktitle = {{PLAN-X} 2008, Programming Language Technologies for XML, An {ACM} {SIGPLAN} Workshop colocated with
+ {POPL} 2008, San Francisco, California, USA, January 9, 2008},
+ year = 2008,
+ crossref = {plan-x:2008},
+ url = {http://gemo.futurs.inria.fr/events/PLANX2008/papers/p18.pdf},
+ abstract = {The W3C Document Object Model (DOM) specifies an XML up- date library. DOM is written in English, and
+ is therefore not compo- sitional and not complete. We provide a first step towards a compo- sitional
+ specification of DOM. Unlike DOM, we are able to work with a minimal set of commands and obtain a
+ complete reason- ing for straight-line code. Our work transfers O{\^a}Hearn, Reynolds and Yang{\^a}s
+ local Hoare reasoning for analysing heaps to XML, viewing XML as an in-place memory store as does DOM.
+ In par- ticular, we apply recent work by Calcagno, Gardner and Zarfaty on local Hoare reasoning about
+ a simple tree-update language to DOM, showing that our reasoning scales to DOM. Our reasoning not only
+ formally specifies a significant subset of DOM Core Level 1, but can also be used to verify e.g.
+ invariant properties of simple Javascript programs.}
+}
+
+@InProceedings{ jang.ea:establishing:2012,
+ author = {Dongseok Jang and Zachary Tatlock and Sorin Lerner},
+ title = {Establishing Browser Security Guarantees through Formal Shim Verification},
+ booktitle = {Proceedings of the 21th {USENIX} Security Symposium, Bellevue, WA, USA, August 8-10, 2012},
+ pages = {113--128},
+ year = 2012,
+ crossref = {kohno:proceedings:2012},
+ url = {https://www.usenix.org/conference/usenixsecurity12/technical-sessions/presentation/jang},
+ abstract = { Web browsers mediate access to valuable private data in domains ranging from health care to banking.
+ Despite this critical role, attackers routinely exploit browser vulnerabilities to exfiltrate private
+ data and take over the un- derlying system. We present Q UARK , a browser whose kernel has been
+ implemented and verified in Coq. We give a specification of our kernel, show that the implementation
+ satisfies the specification, and finally show that the specification implies several security
+ properties, including tab non-interference, cookie integrity and confidentiality, and address bar
+ integrity. }
+}
+
+@Proceedings{ kohno:proceedings:2012,
+ editor = {Tadayoshi Kohno},
+ title = {Proceedings of the 21th {USENIX} Security Symposium, Bellevue, WA, USA, August 8-10, 2012},
+ publisher = {{USENIX} Association},
+ year = 2012,
+ timestamp = {Thu, 15 May 2014 09:12:27 +0200}
+}
+
+@Proceedings{ plan-x:2008,
+ title = {{PLAN-X} 2008, Programming Language Technologies for XML, An {ACM} {SIGPLAN} Workshop colocated with
+ {POPL} 2008, San Francisco, California, USA, January 9, 2008},
+ year = 2008,
+ timestamp = {Fri, 18 Jan 2008 13:01:04 +0100}
+}
+
+@Article{ brucker.ea:extensible:2008-b,
+ abstract = {We present an extensible encoding of object-oriented data models into HOL. Our encoding is supported
+ by a datatype package that leverages the use of the shallow embedding technique to object-oriented
+ specification and programming languages. The package incrementally compiles an object-oriented data
+ model, i.e., a class model, to a theory containing object-universes, constructors, accessor functions,
+ coercions (casts) between dynamic and static types, characteristic sets, and co-inductive class
+ invariants. The package is conservative, i.e., all properties are derived entirely from constant
+ definitions, including the constraints over object structures. As an application, we use the package
+ for an object-oriented core-language called IMP++, for which we formally prove the correctness of a
+ Hoare-Logic with respect to a denotational semantics.},
+ address = {Heidelberg},
+ author = {Achim D. Brucker and Burkhart Wolff},
+ doi = {10.1007/s10817-008-9108-3},
+ issn = {0168-7433},
+ issue = 3,
+ journal = {Journal of Automated Reasoning},
+ keywords = {object-oriented data models, HOL, theorem proving, verification},
+ language = {USenglish},
+ pages = {219--249},
+ pdf = {https://www.brucker.ch/bibliography/download/2008/brucker.ea-extensible-2008-b.pdf},
+ publisher = {Springer-Verlag},
+ title = {An Extensible Encoding of Object-oriented Data Models in HOL},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-extensible-2008-b},
+ volume = 41,
+ year = 2008
+}
+
+@PhDThesis{ brucker:interactive:2007,
+ abstract = {We present a semantic framework for object-oriented specification languages. We develop this
+ framework as a conservative shallow embedding in Isabelle/HOL. Using only conservative extensions
+ guarantees by construction the consistency of our formalization. Moreover, we show how our framework
+ can be used to build an interactive proof environment, called HOL-OCL, for object-oriented
+ specifications in general and for UML/OCL in particular.\\\\Our main contributions are an extensible
+ encoding of object-oriented data structures in HOL, a datatype package for object-oriented
+ specifications, and the development of several equational and tableaux calculi for object-oriented
+ specifications. Further, we show that our formal framework can be the basis of a formal
+ machine-checked semantics for OCL that is compliant to the OCL 2.0 standard.},
+ abstract_de = {In dieser Arbeit wird ein semantisches Rahmenwerk f{\"u}r objektorientierte Spezifikationen
+ vorgestellt. Das Rahmenwerk ist als konservative, flache Einbettung in Isabelle/HOL realisiert. Durch
+ die Beschr{\"a}nkung auf konservative Erweiterungen kann die logische Konsistenz der Einbettung
+ garantiert werden. Das semantische Rahmenwerk wird verwendet, um das interaktives Beweissystem HOL-OCL
+ f{\"u}r objektorientierte Spezifikationen im Allgemeinen und insbesondere f{\"u}r UML/OCL zu
+ entwickeln.\\\\Die Hauptbeitr{\"a}ge dieser Arbeit sind die Entwicklung einer erweiterbaren Kodierung
+ objektorientierter Datenstrukturen in HOL, ein Datentyp-Paket f{\"u}r objektorientierte
+ Spezifikationen und die Entwicklung verschiedener Kalk{\"u}le f{\"u}r objektorientierte
+ Spezifikationen. Zudem zeigen wir, wie das formale Rahmenwerk verwendet werden kann, um eine formale,
+ maschinell gepr{\"u}fte Semantik f{\"u}r OCL anzugeben, die konform zum Standard f{\"u}r OCL 2.0 ist.},
+ author = {Achim D. Brucker},
+ keywords = {OCL, UML, formal semantics, theorem proving, Isabelle, HOL-OCL},
+ month = {mar},
+ note = {ETH Dissertation No. 17097.},
+ pdf = {https://www.brucker.ch/bibliography/download/2007/brucker-interactive-2007.pdf},
+ school = {ETH Zurich},
+ title = {An Interactive Proof Environment for Object-oriented Specifications},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker-interactive-2007},
+ year = 2007
+}
+
+@InCollection{ brucker.ea:standard-compliance-testing:2018,
+ talk = {talk:brucker.ea:standard-compliance-testing:2018},
+ abstract = {Most popular technologies are based on informal or semiformal standards that lack a rigid formal
+ semantics. Typical examples include web technologies such as the DOM or HTML, which are defined by the
+ Web Hypertext Application Technology Working Group (WHATWG) and the World Wide Web Consortium (W3C).
+ While there might be API specifications and test cases meant to assert the compliance of a certain
+ implementation, the actual standard is rarely accompanied by a formal model that would lend itself
+ for, e.g., verifying the security or safety properties of real systems.
+
+ Even when such a formalization of a standard exists, two important questions arise: first, to what
+ extend does the formal model comply to the standard and, second, to what extend does the
+ implementation comply to the formal model and the assumptions made during the verification? In this
+ paper, we present an approach that brings all three involved artifacts - the (semi-)formal standard,
+ the formalization of the standard, and the implementations - closer together by combining
+ verification, symbolic execution, and specification based testing.},
+ keywords = {standard compliance, compliance tests, DOM},
+ location = {Toulouse, France},
+ author = {Achim D. Brucker and Michael Herzberg},
+ booktitle = {{TAP} 2018: Tests And Proofs},
+ language = {USenglish},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ number = 10889,
+ editor = {Cathrine Dubois and Burkhart Wolff},
+ title = {Formalizing (Web) Standards: An Application of Test and Proof},
+ categories = {holtestgen, websecurity},
+ classification= {conference},
+ areas = {formal methods, software engineering},
+ public = {yes},
+ year = 2018,
+ doi = {10.1007/978-3-319-92994-1_9},
+ pages = {159--166},
+ isbn = {978-3-642-38915-3},
+ pdf = {http://www.brucker.ch/bibliography/download/2018/brucker.ea-standard-compliance-testing-2018.pdf},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-standard-compliance-testing-2018}
+}
+
+@InCollection{ brucker.ea:interactive:2005,
+ keywords = {symbolic test case generations, black box testing, white box testing, theorem proving, interactive
+ testing},
+ abstract = {HOL-TestGen is a test environment for specification-based unit testing build upon the proof assistant
+ Isabelle/HOL\@. While there is considerable skepticism with regard to interactive theorem provers in
+ testing communities, we argue that they are a natural choice for (automated) symbolic computations
+ underlying systematic tests. This holds in particular for the development on non-trivial formal test
+ plans of complex software, where some parts of the overall activity require inherently guidance by a
+ test engineer. In this paper, we present the underlying methods for both black box and white box
+ testing in interactive unit test scenarios. HOL-TestGen can also be understood as a unifying technical
+ and conceptual framework for presenting and investigating the variety of unit test techniques in a
+ logically consistent way. },
+ location = {Edinburgh},
+ author = {Achim D. Brucker and Burkhart Wolff},
+ booktitle = {Formal Approaches to Testing of Software},
+ language = {USenglish},
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ series = s-lncs,
+ number = 3997,
+ doi = {10.1007/11759744_7},
+ isbn = {3-540-25109-X},
+ editor = {Wolfgang Grieskamp and Carsten Weise},
+ pdf = {http://www.brucker.ch/bibliography/download/2005/brucker.ea-interactive-2005.pdf},
+ project = {CSFMDOS},
+ title = {Interactive Testing using {HOL}-{TestGen}},
+ classification= {workshop},
+ areas = {formal methods, software},
+ categories = {holtestgen},
+ year = 2005,
+ public = {yes},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-interactive-2005}
+}
+
+@Article{ brucker.ea:theorem-prover:2012,
+ author = {Achim D. Brucker and Burkhart Wolff},
+ journal = j-fac,
+ publisher = pub-springer,
+ address = pub-springer:adr,
+ language = {USenglish},
+ categories = {holtestgen},
+ title = {On Theorem Prover-based Testing},
+ year = 2013,
+ issn = {0934-5043},
+ pages = {683--721},
+ volume = 25,
+ number = 5,
+ classification= {journal},
+ areas = {formal methods, software},
+ public = {yes},
+ doi = {10.1007/s00165-012-0222-y},
+ keywords = {test case generation, domain partitioning, test sequence, theorem proving, HOL-TestGen},
+ abstract = {HOL-TestGen is a specification and test case generation environment extending the interactive theorem
+ prover Isabelle/HOL. As such, HOL-TestGen allows for an integrated workflow supporting interactive
+ theorem proving, test case generation, and test data generation.
+
+ The HOL-TestGen method is two-staged: first, the original formula is partitioned into test cases by
+ transformation into a normal form called test theorem. Second, the test cases are analyzed for ground
+ instances (the test data) satisfying the constraints of the test cases. Particular emphasis is put on
+ the control of explicit test-hypotheses which can be proven over concrete programs.
+
+ Due to the generality of the underlying framework, our system can be used for black-box unit,
+ sequence, reactive sequence and white-box test scenarios. Although based on particularly clean
+ theoretical foundations, the system can be applied for substantial case-studies. },
+ pdf = {http://www.brucker.ch/bibliography/download/2012/brucker.ea-theorem-prover-2012.pdf},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-theorem-prover-2012}
+}
+
+@Article{ brucker.ea:afp-core-dom:2018,
+ 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.},
+ author = {Achim D. Brucker and Michael Herzberg},
+ date = {2018-12-26},
+ file = {https://www.brucker.ch/bibliography/download/2018/brucker.ea-afp-core-dom-outline-2018.pdf},
+ filelabel = {Outline},
+ issn = {2150-914x},
+ journal = {Archive of Formal Proofs},
+ month = {dec},
+ note = {\url{http://www.isa-afp.org/entries/Core_DOM.html}, Formal proof development},
+ pdf = {https://www.brucker.ch/bibliography/download/2018/brucker.ea-afp-core-dom-2018.pdf},
+ title = {The Core {DOM}},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-afp-core-dom-2018-a},
+ year = 2018
+}
+
+@InCollection{ brucker.ea:web-components:2019,
+ abstract = {The trend towards ever more complex client-side web applications is unstoppable. Compared to
+ traditional software development, client-side web development lacks a well-established component
+ model, i.e., a method for easily and safely reusing already developed functionality. To address this
+ issue, the web community started to adopt shadow trees as part of the Document Object Model (DOM):
+ shadow trees allow developers to "partition" a DOM instance into parts that should be safely
+ separated, e.g., code modifying one part should not, unintentionally, affect other parts of the
+ DOM.\\\\While 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 this paper, 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.},
+ address = {Heidelberg},
+ author = {Achim D. Brucker and Michael Herzberg},
+ booktitle = {Formal Aspects of Component Software (FACS)},
+ doi = {10.1007/978-3-030-40914-2_3},
+ editor = {Sung-Shik Jongmans and Farhad Arbab},
+ isbn = {3-540-25109-X},
+ keywords = {Web Component, Shadow Tree, DOM, Isabelle/HOL},
+ language = {USenglish},
+ location = {Amsterdam, The Netherlands},
+ number = 12018,
+ pdf = {https://www.brucker.ch/bibliography/download/2019/brucker.ea-web-components-2019.pdf},
+ publisher = {Springer-Verlag},
+ series = {Lecture Notes in Computer Science},
+ title = {A Formally Verified Model of Web Components},
+ url = {https://www.brucker.ch/bibliography/abstract/brucker.ea-web-components-2019},
+ year = 2020
+}
+
+@Article{ brucker.ea:afp-dom-components:2020,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {A Formalization of Web Components},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ date = {2020-09-28},
+ note = {\url{http://www.isa-afp.org/entries/DOM_Components.html}, Formal proof development},
+ issn = {2150-914x},
+ public = {yes},
+ classification= {formal},
+ categories = {websecurity},
+ pdf = {download/2020/brucker.ea-afp-dom-components-2020.pdf},
+ filelabel = {Outline},
+ file = {download/2020/brucker.ea-afp-dom-components-outline-2020.pdf},
+ areas = {formal methods, security, software engineering}
+}
+
+@Article{ brucker.ea:afp-dom-components:2020-a,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {A Formalization of Web Components},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ date = {2020-09-28},
+ note = {\url{http://www.isa-afp.org/entries/DOM_Components.html}, Formal proof development},
+ issn = {2150-914x},
+ public = {yes},
+ classification= {formal},
+ categories = {websecurity},
+ pdf = {download/2020/brucker.ea-afp-dom-components-2020.pdf},
+ filelabel = {Outline},
+ file = {download/2020/brucker.ea-afp-dom-components-outline-2020.pdf},
+ areas = {formal methods, security, software engineering}
+}
+
+@Article{ brucker.ea:afp-core-sc-dom:2020,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {The Safely Composable {DOM}},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ date = {2020-09-28},
+ note = {\url{http://www.isa-afp.org/entries/Core_SC_DOM.html}, Formal proof development},
+ issn = {2150-914x},
+ 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 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. },
+ public = {yes},
+ classification= {formal},
+ categories = {websecurity},
+ pdf = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-core-sc-dom-2018.pdf},
+ filelabel = {Outline},
+ file = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-core-sc-dom-outline-2018.pdf},
+ areas = {formal methods, security, software engineering},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-afp-core-sc-dom-2020}
+}
+
+
+@Article{ brucker.ea:afp-shadow-dom:2020,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {Shadow DOM: A Formal Model of the Document Object Model \emph{with Shadow Roots}},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ date = {2020-09-28},
+ note = {\url{http://www.isa-afp.org/entries/Shadow_DOM.html}, Formal proof development},
+ issn = {2150-914x},
+ abstract = { In this AFP entry, we extend our formalization of the core DOM with \emph{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. },
+ public = {yes},
+ classification= {formal},
+ categories = {websecurity},
+ pdf = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-shadow-dom-2018.pdf},
+ filelabel = {Outline},
+ file = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-shadow-dom-outline-2018.pdf},
+ areas = {formal methods, security, software engineering},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-afp-shadow-dom-2020}
+}
+
+@Article{ brucker.ea:afp-sc-dom-components:2020,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {A Formalization of Safely Composable Web Components},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ date = {2020-09-28},
+ note = {\url{http://www.isa-afp.org/entries/SC_DOM_Components.html}, Formal proof development},
+ issn = {2150-914x},
+ public = {yes},
+ classification= {formal},
+ categories = {websecurity},
+ pdf = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-sc-dom-components-2020.pdf},
+ filelabel = {Outline},
+ file = {http://www.brucker.ch/bibliography/download/2020/brucker.ea-afp-sc-dom-components-outline-2020.pdf},
+ areas = {formal methods, security, software engineering},
+ url = {http://www.brucker.ch/bibliography/abstract/brucker.ea-afp-sc-dom-components-2020}
+}
+
+
+@PhdThesis{herzberg:web-components:2020,
+ author = {Michael Herzberg},
+ title = {Formal Foundations for Provably Safe Web Components},
+ school = {The University of Sheffield},
+ year = {2020}
+}
+
diff --git a/thys/Shadow_SC_DOM/document/root.tex b/thys/Shadow_SC_DOM/document/root.tex
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/document/root.tex
@@ -0,0 +1,231 @@
+\documentclass[10pt,DIV16,a4paper,abstract=true,twoside=semi,openright]
+{scrreprt}
+\usepackage[USenglish]{babel}
+\usepackage[numbers, sort&compress]{natbib}
+\usepackage{isabelle,isabellesym}
+\usepackage{booktabs}
+\usepackage{paralist}
+\usepackage{graphicx}
+\usepackage{amssymb}
+\usepackage{xspace}
+\usepackage{xcolor}
+\usepackage{listings}
+\lstloadlanguages{HTML}
+\usepackage[]{mathtools}
+\usepackage[pdfpagelabels, pageanchor=false, plainpages=false]{hyperref}
+\lstdefinestyle{html}{language=XML,
+ basicstyle=\ttfamily,
+ commentstyle=\itshape,
+ keywordstyle=\color{blue},
+ ndkeywordstyle=\color{blue},
+}
+\lstdefinestyle{displayhtml}{style=html,
+ floatplacement={tbp},
+ captionpos=b,
+ framexleftmargin=0pt,
+ basicstyle=\ttfamily\scriptsize,
+ backgroundcolor=\color{black!2},
+ frame=lines,
+}
+\lstnewenvironment{html}[1][]{\lstset{style=displayhtml, #1}}{}
+\def\inlinehtml{\lstinline[style=html, columns=fullflexible]}
+
+\pagestyle{headings}
+\isabellestyle{default}
+\setcounter{tocdepth}{1}
+\newcommand{\ie}{i.\,e.\xspace}
+\newcommand{\eg}{e.\,g.\xspace}
+\newcommand{\thy}{\isabellecontext}
+\renewcommand{\isamarkupsection}[1]{%
+ \begingroup%
+ \def\isacharunderscore{\textunderscore}%
+ \section{#1 (\thy)}%
+ \endgroup%
+}
+
+\title{Shadow SC DOM\\\medskip \Large
+ A Formal Model of the Safely Composable Document Object Model \emph{with Shadow Roots}}%
+
+
+
+\author{%
+ \href{https://www.brucker.ch/}{Achim~D.~Brucker}\footnotemark[1]
+ \and
+ \href{https://www.michael-herzberg.de/}{Michael Herzberg}\footnotemark[2]
+}
+
+\publishers{
+ \footnotemark[1]~Department of Computer Science, University of Exeter, Exeter, UK\texorpdfstring{\\}{, }
+ \texttt{a.brucker@exeter.ac.uk}\\[2em]
+ %
+ \footnotemark[2]~ Department of Computer Science, The University of Sheffield, Sheffield, UK\texorpdfstring{\\}{, }
+ \texttt{msherzberg1@sheffield.ac.uk}
+}
+\begin{document}
+ \maketitle
+ \begin{abstract}
+ \begin{quote}
+ In this AFP entry, we extend our formalization of the safely
+ composable DOM
+ (\href{https://www.isa-afp.org/entries/Core_SC_DOM.html}
+ {Core\_SC\_DOM}) with \emph{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
+ \begin{inparaenum}
+ \item \emph{extensible}, i.e., can be extended without the need of
+ re-proving already proven properties and
+ \item \emph{executable}, i.e., we can generate executable code
+ from our specification.
+ \end{inparaenum}
+ We exploit the executability to show that our formalization
+ complies to the official standard of the W3C, respectively,
+ the WHATWG.
+
+ \bigskip
+ \noindent{\textbf{Keywords:}}
+ Document Object Model, DOM, Shadow Root, Web Component, Formal
+ Semantics, Isabelle/HOL
+ \end{quote}
+ \end{abstract}
+
+
+\tableofcontents
+\cleardoublepage
+
+\chapter{Introduction}
+
+In a world in which more and more applications are offered as services
+on the internet, web browsers start to take on a similarly central
+role in our daily IT infrastructure as operating systems. Thus, web
+browsers should be developed as rigidly and formally as operating
+systems. While formal methods are a well-established technique in the
+development of operating systems (see,
+\eg,~\citet{klein:operating:2009} for an overview of formal
+verification of operating systems), there are few proposals for
+improving the development of web browsers using formal
+approaches~\cite{gardner.ea:dom:2008,raad.ea:dom:2016,jang.ea:establishing:2012,bohannon.ea:featherweight:2010}.
+
+In~\cite{brucker.ea:afp-core-sc-dom:2020}, we formalized the core of
+the safely composable Document Object Model (DOM) in
+Isabelle/HOL\@. The DOM~\cite{whatwg:dom:2017,w3c:dom:2015} is
+\emph{the} central data structure of all modern web browsers. In this
+work, we extend the formalization presented
+in~\cite{brucker.ea:afp-core-dom:2018} with support for \emph{shadow
+ trees}. Shadow trees are a recent addition to the DOM
+standard~\cite{whatwg:dom:2017} that promise support for web
+components. As we will see, this promise is not fully achieved and,
+for example, the DOM standard itself does not formally define what a
+component should be. In this work, we focus on a standard compliant
+representation of the DOM with shadow
+trees. As~\cite{brucker.ea:afp-core-sc-dom:2020}, our formalization has
+the following properties:
+\begin{itemize}
+\item It provides a \emph{consistency guarantee.} Since all
+ definitions in our formal semantics are conservative and all rules
+ are derived, the logical consistency of the DOM node-tree is reduced
+ to the consistency of HOL.
+\item It serves as a \emph{technical basis for a proof system.} Based
+ on the derived rules and specific setup of proof tactics over
+ node-trees, our formalization provides a generic proof environment
+ for the verification of programs manipulating node-trees.
+\item It is \emph{executable}, which allows to validate its compliance
+ to the standard by evaluating the compliance test suite on the
+ formal model and
+\item It is \emph{extensible} in the sense
+ of~\cite{brucker.ea:extensible:2008-b,brucker:interactive:2007},
+ \ie, properties proven over the core DOM do not need to be re-proven
+ for object-oriented extensions such as the HTML document model.
+\end{itemize}
+
+In this AFP entry, we limit ourselves to the faithful formalization of
+the DOM. As the DOM standard does not formally define web components,
+we address the question of formally defining web components and
+discussing their safety properties
+elsewhere~\cite{brucker.ea:afp-sc-dom-components:2020,brucker.ea:web-components:2019}.
+
+The rest of this document is automatically generated from the formalization
+in Isabelle/HOL, i.e., all content is checked by Isabelle (for a more
+abstract presentation and more explanations, please
+see~\cite{herzberg:web-components:2020}). The structure follows the theory
+dependencies (see \autoref{fig:session-graph}): first, we formalize the DOM
+with Shadow Roots (\autoref{cha:dom}) and then formalize we the relevant
+compliance test cases in \autoref{cha:tests}.
+
+\paragraph{Important Note:} This document describes the formalization
+of the \emph{Safely Composable Document Object Model with Shadow
+ Roots} (SC DOM with Shadow Roots), which deviated in one important
+aspect from the official DOM standard: in the SC DOM, the shadow root
+is a sub-class of the document class (instead of a base class). This
+modification results in a stronger notion of web components that
+provide improved safety properties for the composition of web
+components. While the SC DOM still passes the compliance test suite as
+provided by the authors of the DOM standard, its data model is
+different. We refer readers interested in a formalisation of the
+standard compliant DOM to the AFP entries
+``Core\_DOM''~\cite{brucker.ea:afp-core-dom:2018} and
+``Shadow\_DOM''~\cite{brucker.ea:afp-shadow-dom:2020}.
+
+
+\begin{figure}
+ \centering
+ \includegraphics[angle=90,scale=0.5]{session_graph}
+ \caption{The Dependency Graph of the Isabelle Theories.\label{fig:session-graph}}
+\end{figure}
+
+\clearpage
+
+\chapter{The Shadow DOM}
+\label{cha:dom}
+In this chapter, we introduce the formalization of the core DOM
+\emph{with Shadow Roots}, i.e., the most important algorithms for
+querying or modifying the Shadow DOM, as defined in the standard.
+
+\input{ShadowRootClass.tex}
+\input{ShadowRootMonad.tex}
+\input{Shadow_DOM.tex}
+
+
+\chapter{Test Suite}
+\label{cha:tests}
+In this chapter, we present the formalized compliance test cases for
+the core DOM. As our formalization is executable, we can
+(symbolically) execute the test cases on top of our model. Executing
+these test cases successfully shows that our model is compliant to the
+official DOM standard. As future work, we plan to generate test cases
+from our formal model (e.g.,
+using~\cite{brucker.ea:interactive:2005,brucker.ea:theorem-prover:2012})
+to improve the quality of the official compliance test suite. For more
+details on the relation of test and proof in the context of web
+standards, we refer the reader to
+\cite{brucker.ea:standard-compliance-testing:2018}.
+
+\input{Shadow_DOM_BaseTest.tex}
+\input{slots.tex}
+\input{slots_fallback.tex}
+\input{Shadow_DOM_Document_adoptNode.tex}
+\input{Shadow_DOM_Document_getElementById.tex}
+\input{Shadow_DOM_Node_insertBefore.tex}
+\input{Shadow_DOM_Node_removeChild.tex}
+\input{Shadow_DOM_Tests.tex}
+
+
+{\small
+ \bibliographystyle{abbrvnat}
+ \bibliography{root}
+}
+\end{document}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: t
+%%% End:
diff --git a/thys/Shadow_SC_DOM/monads/ShadowRootMonad.thy b/thys/Shadow_SC_DOM/monads/ShadowRootMonad.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/monads/ShadowRootMonad.thy
@@ -0,0 +1,1053 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Shadow Root Monad\<close>
+theory ShadowRootMonad
+ imports
+ "Core_SC_DOM.DocumentMonad"
+ "../classes/ShadowRootClass"
+begin
+
+
+type_synonym ('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+ 'shadow_root_ptr, 'Object, 'Node, 'Element, 'CharacterData, 'Document, 'ShadowRoot, 'result) dom_prog
+ = "((_) heap, exception, 'result) prog"
+register_default_tvars "('object_ptr, 'node_ptr, 'element_ptr, 'character_data_ptr, 'document_ptr,
+'shadow_root_ptr, 'Object, 'Node, 'Element, 'CharacterData, 'Document, 'ShadowRoot, 'result) dom_prog"
+
+
+
+global_interpretation l_ptr_kinds_M shadow_root_ptr_kinds defines shadow_root_ptr_kinds_M = a_ptr_kinds_M .
+lemmas shadow_root_ptr_kinds_M_defs = a_ptr_kinds_M_def
+
+lemma shadow_root_ptr_kinds_M_eq:
+ assumes "|h \<turnstile> object_ptr_kinds_M|\<^sub>r = |h' \<turnstile> object_ptr_kinds_M|\<^sub>r"
+ shows "|h \<turnstile> shadow_root_ptr_kinds_M|\<^sub>r = |h' \<turnstile> shadow_root_ptr_kinds_M|\<^sub>r"
+ using assms
+ by(auto simp add: shadow_root_ptr_kinds_M_defs document_ptr_kinds_def object_ptr_kinds_M_defs
+ shadow_root_ptr_kinds_def)
+
+
+
+global_interpretation l_dummy defines get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t = "l_get_M.a_get_M get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t" .
+lemma get_M_is_l_get_M: "l_get_M get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t type_wf shadow_root_ptr_kinds"
+ apply(simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_type_wf l_get_M_def)
+ apply(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def shadow_root_ptr_kinds_def)[1]
+ by (metis (no_types, lifting) DocumentMonad.l_get_M_axioms bind_eq_None_conv fset.map_comp
+ l_get_M_def option.discI shadow_root_ptr_kinds_commutes shadow_root_ptr_kinds_def)
+lemmas get_M_defs = get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def[unfolded l_get_M.a_get_M_def[OF get_M_is_l_get_M]]
+
+adhoc_overloading get_M get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+
+locale l_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas = l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+begin
+sublocale l_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas by unfold_locales
+
+interpretation l_get_M get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t type_wf shadow_root_ptr_kinds
+ apply(unfold_locales)
+ apply (simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_type_wf local.type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t)
+ by (meson ShadowRootMonad.get_M_is_l_get_M l_get_M_def)
+lemmas get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok = get_M_ok[folded get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def]
+lemmas get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_in_heap = get_M_ptr_in_heap[folded get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def]
+end
+
+global_interpretation l_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas type_wf by unfold_locales
+
+
+global_interpretation l_put_M type_wf shadow_root_ptr_kinds get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t rewrites
+ "a_get_M = get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t" defines put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t = a_put_M
+ apply (simp add: get_M_is_l_get_M l_put_M_def)
+ by (simp add: get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def)
+
+lemmas put_M_defs = a_put_M_def
+adhoc_overloading put_M put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+
+
+locale l_put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas = l_type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+begin
+sublocale l_put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_lemmas by unfold_locales
+
+interpretation l_put_M type_wf shadow_root_ptr_kinds get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t
+ apply(unfold_locales)
+ apply (simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_type_wf local.type_wf\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t)
+ by (meson ShadowRootMonad.get_M_is_l_get_M l_get_M_def)
+lemmas put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ok = put_M_ok[folded put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def]
+end
+
+global_interpretation l_put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_lemmas type_wf by unfold_locales
+
+
+lemma shadow_root_put_get [simp]: "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. getter (setter (\<lambda>_. v) x) = v)
+ \<Longrightarrow> h' \<turnstile> get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter \<rightarrow>\<^sub>r v"
+ by(auto simp add: put_M_defs get_M_defs split: option.splits)
+lemma get_M_Mshadow_root_preserved1 [simp]:
+ "shadow_root_ptr \<noteq> shadow_root_ptr'
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs preserved_def split: option.splits dest: get_heap_E)
+lemma shadow_root_put_get_preserved [simp]:
+ "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. getter (setter (\<lambda>_. v) x) = getter x)
+ \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' getter) h h'"
+ apply(cases "shadow_root_ptr = shadow_root_ptr'")
+ by(auto simp add: put_M_defs get_M_defs preserved_def split: option.splits dest: get_heap_E)
+
+lemma get_M_Mshadow_root_preserved2 [simp]:
+ "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs NodeMonad.get_M_defs
+ put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>N\<^sub>o\<^sub>d\<^sub>e_def preserved_def split: option.splits dest: get_heap_E)
+
+lemma get_M_Mshadow_root_preserved3 [simp]:
+ "cast shadow_root_ptr \<noteq> document_ptr
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def DocumentMonad.get_M_defs
+ preserved_def split: option.splits dest: get_heap_E)
+
+lemma get_M_Mshadow_root_preserved4 [simp]:
+ "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr getter) h h'"
+ apply(cases "cast shadow_root_ptr \<noteq> document_ptr")[1]
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ DocumentMonad.get_M_defs preserved_def
+ split: option.splits bind_splits dest: get_heap_E)
+
+lemma get_M_Mshadow_root_preserved3a [simp]:
+ "cast shadow_root_ptr \<noteq> object_ptr
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def ObjectMonad.get_M_defs
+ preserved_def split: option.splits dest: get_heap_E)
+
+lemma get_M_Mshadow_root_preserved4a [simp]:
+ "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. getter (cast (setter (\<lambda>_. v) x)) = getter (cast x))
+ \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr getter) h h'"
+ apply(cases "cast shadow_root_ptr \<noteq> object_ptr")[1]
+ by(auto simp add: put_M_defs get_M_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ ObjectMonad.get_M_defs preserved_def
+ split: option.splits bind_splits dest: get_heap_E)
+
+lemma get_M_Mshadow_root_preserved5 [simp]:
+ "cast shadow_root_ptr \<noteq> object_ptr
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter) h h'"
+ by(auto simp add: ObjectMonad.put_M_defs get_M_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def ObjectMonad.get_M_defs
+ preserved_def split: option.splits dest: get_heap_E)
+
+lemma get_M_Mshadow_root_preserved6 [simp]:
+ "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr getter) h h'"
+ by(auto simp add: put_M_defs ElementMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_Mshadow_root_preserved7 [simp]:
+ "h \<turnstile> put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr setter v \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter) h h'"
+ by(auto simp add: ElementMonad.put_M_defs get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_Mshadow_root_preserved8 [simp]:
+ "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr getter) h h'"
+ by(auto simp add: put_M_defs CharacterDataMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_Mshadow_root_preserved9 [simp]:
+ "h \<turnstile> put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter) h h'"
+ by(auto simp add: CharacterDataMonad.put_M_defs get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+
+lemma get_M_shadow_root_put_M_document_different_pointers [simp]:
+ "cast shadow_root_ptr \<noteq> document_ptr
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter) h h'"
+ by(auto simp add: DocumentMonad.put_M_defs get_M_defs DocumentMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_shadow_root_put_M_document [simp]:
+ "h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. is_shadow_root_kind x \<longleftrightarrow> is_shadow_root_kind (setter (\<lambda>_. v) x))
+ \<Longrightarrow> (\<And>x. getter (the (cast (((setter (\<lambda>_. v) (cast x)))))) = getter ((x)))
+ \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr getter) h h'"
+ apply(cases "cast shadow_root_ptr \<noteq> document_ptr ")
+ apply(auto simp add: preserved_def is_shadow_root_kind_def DocumentMonad.put_M_defs
+ get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get_M_defs DocumentMonad.get_M_defs split: option.splits)[1]
+ apply(auto simp add: preserved_def is_shadow_root_kind_def DocumentMonad.put_M_defs
+ get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get_M_defs DocumentMonad.get_M_defs split: option.splits)[1]
+ apply(metis cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_inv option.sel)
+ apply(metis cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_inv option.sel)
+ done
+
+lemma get_M_document_put_M_shadow_root_different_pointers [simp]:
+ "document_ptr \<noteq> cast shadow_root_ptr
+ \<Longrightarrow> h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr getter) h h'"
+ by(auto simp add: put_M_defs get_M_defs DocumentMonad.get_M_defs preserved_def
+ split: option.splits dest: get_heap_E)
+lemma get_M_document_put_M_shadow_root [simp]:
+ "h \<turnstile> put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr setter v \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> (\<And>x. is_shadow_root_kind x \<Longrightarrow> getter ((cast (((setter (\<lambda>_. v) (the (cast x))))))) = getter ((x)))
+ \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr getter) h h'"
+ apply(cases "document_ptr \<noteq> cast shadow_root_ptr ")
+ apply(auto simp add: preserved_def is_document_kind_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put_M_defs
+ get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def DocumentMonad.get_M_defs ShadowRootMonad.get_M_defs
+ split: option.splits Option.bind_splits)[1]
+ apply(auto simp add: preserved_def is_document_kind_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put_M_defs
+ get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def DocumentMonad.get_M_defs ShadowRootMonad.get_M_defs
+ split: option.splits Option.bind_splits)[1]
+ using is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def apply force
+ by (metis cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_inv is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def option.distinct(1) option.sel)
+
+lemma cast_shadow_root_child_nodes_document_disconnected_nodes [simp]:
+ "RShadowRoot.child_nodes (the (cast (cast x\<lparr>disconnected_nodes := y\<rparr>))) = RShadowRoot.child_nodes x"
+ apply(auto simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def RDocument.truncate_def
+ split: option.splits)[1]
+ by (metis RDocument.ext_inject RDocument.surjective RObject.ext_inject RShadowRoot.ext_inject
+ RShadowRoot.surjective)
+lemma cast_shadow_root_child_nodes_document_doctype [simp]:
+ "RShadowRoot.child_nodes (the (cast (cast x\<lparr>doctype := y\<rparr>))) = RShadowRoot.child_nodes x"
+ apply(auto simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def RDocument.truncate_def
+ split: option.splits)[1]
+ by (metis RDocument.ext_inject RDocument.surjective RObject.ext_inject RShadowRoot.ext_inject RShadowRoot.surjective)
+lemma cast_shadow_root_child_nodes_document_document_element [simp]:
+ "RShadowRoot.child_nodes (the (cast (cast x\<lparr>document_element := y\<rparr>))) = RShadowRoot.child_nodes x"
+ apply(auto simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def RDocument.truncate_def
+ split: option.splits)[1]
+ by (metis RDocument.ext_inject RDocument.surjective RObject.ext_inject RShadowRoot.ext_inject
+ RShadowRoot.surjective)
+
+lemma cast_shadow_root_mode_document_disconnected_nodes [simp]:
+ "RShadowRoot.mode (the (cast (cast x\<lparr>disconnected_nodes := y\<rparr>))) = RShadowRoot.mode x"
+ apply(auto simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def
+ RDocument.truncate_def split: option.splits)[1]
+ by (metis RDocument.ext_inject RDocument.surjective RObject.ext_inject RShadowRoot.ext_inject
+ RShadowRoot.surjective)
+lemma cast_shadow_root_mode_document_doctype [simp]:
+ "RShadowRoot.mode (the (cast (cast x\<lparr>doctype := y\<rparr>))) = RShadowRoot.mode x"
+ apply(auto simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def RDocument.truncate_def
+ split: option.splits)[1]
+ by (metis RDocument.ext_inject RDocument.surjective RObject.ext_inject RShadowRoot.ext_inject RShadowRoot.surjective)
+lemma cast_shadow_root_mode_document_document_element [simp]:
+ "RShadowRoot.mode (the (cast (cast x\<lparr>document_element := y\<rparr>))) = RShadowRoot.mode x"
+ apply(auto simp add: cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def RDocument.truncate_def
+ split: option.splits)[1]
+ by (metis RDocument.ext_inject RDocument.surjective RObject.ext_inject RShadowRoot.ext_inject RShadowRoot.surjective)
+
+lemma cast_document_disconnected_nodes_shadow_root_child_nodes [simp]:
+ "is_shadow_root_kind x \<Longrightarrow>
+disconnected_nodes (cast (the (cast x)\<lparr>RShadowRoot.child_nodes := arg\<rparr>)) = disconnected_nodes x"
+ by(auto simp add: is_shadow_root_kind_def cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ RDocument.extend_def RDocument.truncate_def split: option.splits sum.splits)
+lemma cast_document_doctype_shadow_root_child_nodes [simp]:
+ "is_shadow_root_kind x \<Longrightarrow> doctype (cast (the (cast x)\<lparr>RShadowRoot.child_nodes := arg\<rparr>)) = doctype x"
+ by(auto simp add: is_shadow_root_kind_def cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ RDocument.extend_def RDocument.truncate_def split: option.splits sum.splits)
+lemma cast_document_document_element_shadow_root_child_nodes [simp]:
+ "is_shadow_root_kind x \<Longrightarrow>
+document_element (cast (the (cast x)\<lparr>RShadowRoot.child_nodes := arg\<rparr>)) = document_element x"
+ by(auto simp add: is_shadow_root_kind_def cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ RDocument.extend_def RDocument.truncate_def split: option.splits sum.splits)
+lemma cast_document_disconnected_nodes_shadow_root_mode [simp]:
+ "is_shadow_root_kind x \<Longrightarrow>
+disconnected_nodes (cast (the (cast x)\<lparr>RShadowRoot.mode := arg\<rparr>)) = disconnected_nodes x"
+ by(auto simp add: is_shadow_root_kind_def cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ RDocument.extend_def RDocument.truncate_def split: option.splits sum.splits)
+lemma cast_document_doctype_shadow_root_mode [simp]:
+ "is_shadow_root_kind x \<Longrightarrow>
+doctype (cast (the (cast x)\<lparr>RShadowRoot.mode := arg\<rparr>)) = doctype x"
+ by(auto simp add: is_shadow_root_kind_def cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ RDocument.extend_def RDocument.truncate_def split: option.splits sum.splits)
+lemma cast_document_document_element_shadow_root_mode [simp]:
+ "is_shadow_root_kind x \<Longrightarrow>
+document_element (cast (the (cast x)\<lparr>RShadowRoot.mode := arg\<rparr>)) = document_element x"
+ by(auto simp add: is_shadow_root_kind_def cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ RDocument.extend_def RDocument.truncate_def split: option.splits sum.splits)
+
+
+lemma new_element_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t:
+ "h \<turnstile> new_element \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_element_def get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_character_data_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t:
+ "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_character_data_def get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_document_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>r new_document_ptr \<Longrightarrow> h \<turnstile> new_document \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> cast ptr \<noteq> new_document_ptr \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr getter) h h'"
+ by(auto simp add: new_document_def get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+
+definition delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M :: "(_) shadow_root_ptr \<Rightarrow> (_, unit) dom_prog" where
+ "delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr = do {
+ h \<leftarrow> get_heap;
+ (case delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr h of
+ Some h \<Rightarrow> return_heap h |
+ None \<Rightarrow> error HierarchyRequestError)
+ }"
+adhoc_overloading delete_M delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M
+
+lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ok [simp]:
+ assumes "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ shows "h \<turnstile> ok (delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr)"
+ using assms
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: prod.splits)
+
+lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_in_heap:
+ assumes "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'"
+ shows "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ using assms
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: if_splits)
+
+lemma delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_not_in_heap:
+ assumes "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'"
+ shows "shadow_root_ptr |\<notin>| shadow_root_ptr_kinds h'"
+ using assms
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def shadow_root_ptr_kinds_def
+ document_ptr_kinds_def object_ptr_kinds_def split: if_splits)
+
+lemma delete_shadow_root_pointers:
+ assumes "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'"
+ shows "object_ptr_kinds h = object_ptr_kinds h' |\<union>| {|cast shadow_root_ptr|}"
+ using assms
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def shadow_root_ptr_kinds_def
+ document_ptr_kinds_def object_ptr_kinds_def split: if_splits)
+
+lemma delete_shadow_root_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t:
+ "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow> ptr \<noteq> cast shadow_root_ptr \<Longrightarrow>
+preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'"
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def ObjectMonad.get_M_defs preserved_def
+ split: prod.splits option.splits if_splits elim!: bind_returns_heap_E)
+lemma delete_shadow_root_get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e:
+ "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr getter) h h'"
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def NodeMonad.get_M_defs ObjectMonad.get_M_defs
+ preserved_def
+ split: prod.splits option.splits if_splits elim!: bind_returns_heap_E)
+lemma delete_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
+ "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def ElementMonad.get_M_defs NodeMonad.get_M_defs
+ ObjectMonad.get_M_defs preserved_def
+ split: prod.splits option.splits if_splits elim!: bind_returns_heap_E)
+lemma delete_shadow_root_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a:
+ "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr getter) h h'"
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def CharacterDataMonad.get_M_defs NodeMonad.get_M_defs
+ ObjectMonad.get_M_defs preserved_def
+ split: prod.splits option.splits if_splits elim!: bind_returns_heap_E)
+lemma delete_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
+ "cast shadow_root_ptr \<noteq> ptr \<Longrightarrow> h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def DocumentMonad.get_M_defs ObjectMonad.get_M_defs
+ preserved_def
+ split: prod.splits option.splits if_splits elim!: bind_returns_heap_E)
+lemma delete_shadow_root_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t:
+ "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h' \<Longrightarrow> shadow_root_ptr \<noteq> shadow_root_ptr' \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr' getter) h h'"
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get_M_defs ObjectMonad.get_M_defs preserved_def
+ split: prod.splits option.splits if_splits elim!: bind_returns_heap_E)
+
+
+
+subsection \<open>new\_M\<close>
+
+definition new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M :: "(_, (_) shadow_root_ptr) dom_prog"
+ where
+ "new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M = do {
+ h \<leftarrow> get_heap;
+ (new_ptr, h') \<leftarrow> return (new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t h);
+ return_heap h';
+ return new_ptr
+ }"
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ok [simp]:
+ "h \<turnstile> ok new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M"
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def split: prod.splits)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_in_heap:
+ assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ shows "new_shadow_root_ptr |\<in>| shadow_root_ptr_kinds h'"
+ using assms
+ unfolding new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_in_heap is_OK_returns_result_I
+ elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_ptr_not_in_heap:
+ assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ shows "new_shadow_root_ptr |\<notin>| shadow_root_ptr_kinds h"
+ using assms new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_not_in_heap
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def split: prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_new_ptr:
+ assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'"
+ and "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ shows "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_shadow_root_ptr|}"
+ using assms new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_new_ptr
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def split: prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_is_shadow_root_ptr:
+ assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ shows "is_shadow_root_ptr new_shadow_root_ptr"
+ using assms new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_is_shadow_root_ptr
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def elim!: bind_returns_result_E split: prod.splits)
+
+lemma new_shadow_root_mode:
+ assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ shows "h' \<turnstile> get_M new_shadow_root_ptr mode \<rightarrow>\<^sub>r Open"
+ using assms
+ by(auto simp add: get_M_defs new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def
+ split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_shadow_root_children:
+ assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ shows "h' \<turnstile> get_M new_shadow_root_ptr child_nodes \<rightarrow>\<^sub>r []"
+ using assms
+ by(auto simp add: get_M_defs new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def
+ split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_shadow_root_disconnected_nodes:
+ assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'"
+ assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ shows "h' \<turnstile> get_M (cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r new_shadow_root_ptr) disconnected_nodes \<rightarrow>\<^sub>r []"
+ using assms
+ by(auto simp add: DocumentMonad.get_M_defs put_M_defs put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def
+ cast\<^sub>s\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>_\<^sub>r\<^sub>o\<^sub>o\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r_def cast\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def RDocument.extend_def RDocument.truncate_def
+ split: option.splits prod.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+lemma new_shadow_root_get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
+ \<Longrightarrow> ptr \<noteq> cast new_shadow_root_ptr \<Longrightarrow> preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr getter) h h'"
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def ObjectMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_shadow_root_get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e ptr getter) h h'"
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def NodeMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_shadow_root_get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def ElementMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_shadow_root_get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ptr getter) h h'"
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def CharacterDataMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_shadow_root_get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr \<Longrightarrow> ptr \<noteq> cast new_shadow_root_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ptr getter) h h'"
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def DocumentMonad.get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+lemma new_shadow_root_get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t:
+ "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h'
+ \<Longrightarrow> h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr \<Longrightarrow> ptr \<noteq> new_shadow_root_ptr
+ \<Longrightarrow> preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t ptr getter) h h'"
+ by(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def get_M_defs preserved_def
+ split: prod.splits option.splits elim!: bind_returns_result_E bind_returns_heap_E)
+
+
+subsection \<open>modified heaps\<close>
+
+lemma shadow_root_get_put_1 [simp]: "get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h) =
+(if ptr = cast shadow_root_ptr then cast obj else get shadow_root_ptr h)"
+ by(auto simp add: get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def split: option.splits Option.bind_splits)
+
+lemma shadow_root_ptr_kinds_new [simp]: "shadow_root_ptr_kinds (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h) =
+shadow_root_ptr_kinds h |\<union>| (if is_shadow_root_ptr_kind ptr then {|the (cast ptr)|} else {||})"
+ by(auto simp add: shadow_root_ptr_kinds_def is_document_ptr_kind_def split: option.splits)
+
+lemma type_wf_put_I:
+ assumes "type_wf h"
+ assumes "DocumentClass.type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "is_shadow_root_ptr_kind ptr \<Longrightarrow> is_shadow_root_kind obj"
+ shows "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ using assms
+ by(auto simp add: type_wf_defs is_shadow_root_kind_def split: option.splits)
+
+lemma type_wf_put_ptr_not_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<notin>| object_ptr_kinds h"
+ shows "type_wf h"
+ using assms
+ by (metis (no_types, lifting) DocumentMonad.type_wf_put_ptr_not_in_heap_E ObjectClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf
+ ObjectMonad.type_wf_put_ptr_not_in_heap_E ShadowRootClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ShadowRootClass.type_wf_defs
+ document_ptr_kinds_commutes get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def get_document_ptr_simp get_object_ptr_simp2 notin_fset
+ shadow_root_ptr_kinds_commutes)
+
+
+lemma type_wf_put_ptr_in_heap_E:
+ assumes "type_wf (put\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t ptr obj h)"
+ assumes "ptr |\<in>| object_ptr_kinds h"
+ assumes "DocumentClass.type_wf h"
+ assumes "is_shadow_root_ptr_kind ptr \<Longrightarrow> is_shadow_root_kind (the (get ptr h))"
+ shows "type_wf h"
+ using assms
+ apply(auto simp add: type_wf_defs elim!: DocumentMonad.type_wf_put_ptr_in_heap_E
+ split: option.splits if_splits)[1]
+ by (metis (no_types, lifting) DocumentClass.l_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas_axioms assms(2) bind.bind_lunit
+ cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_inv cast\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>2\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_inv finite_set_in get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def l_get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_lemmas.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf option.collapse)
+
+
+subsection \<open>type\_wf\<close>
+
+lemma new_element_type_wf_preserved [simp]:
+ assumes "h \<turnstile> new_element \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+proof -
+ obtain new_element_ptr where "h \<turnstile> new_element \<rightarrow>\<^sub>r new_element_ptr"
+ using assms
+ by (meson is_OK_returns_heap_I is_OK_returns_result_E)
+ with assms have "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_element_ptr|}"
+ using new_element_new_ptr by auto
+ then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+
+ with assms show ?thesis
+ by(auto simp add: ElementMonad.new_element_def type_wf_defs Let_def elim!: bind_returns_heap_E
+ split: prod.splits)
+qed
+
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_tag_name_type_wf_preserved [simp]:
+ assumes "h \<turnstile> put_M element_ptr tag_name_update v \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+proof -
+ have "object_ptr_kinds h = object_ptr_kinds h'"
+ using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
+ then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ with assms show ?thesis
+ by(auto simp add: ElementMonad.put_M_defs type_wf_defs)
+qed
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_child_nodes_type_wf_preserved [simp]:
+ assumes "h \<turnstile> put_M element_ptr RElement.child_nodes_update v \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+proof -
+ have "object_ptr_kinds h = object_ptr_kinds h'"
+ using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
+ then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ with assms show ?thesis
+ by(auto simp add: ElementMonad.put_M_defs type_wf_defs)
+qed
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_attrs_type_wf_preserved [simp]:
+ assumes "h \<turnstile> put_M element_ptr attrs_update v \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+proof -
+ have "object_ptr_kinds h = object_ptr_kinds h'"
+ using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
+ then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ with assms show ?thesis
+ by(auto simp add: ElementMonad.put_M_defs type_wf_defs)
+qed
+lemma put_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t_shadow_root_opt_type_wf_preserved [simp]:
+ assumes "h \<turnstile> put_M element_ptr shadow_root_opt_update v \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+proof -
+ have "object_ptr_kinds h = object_ptr_kinds h'"
+ using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
+ then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ with assms show ?thesis
+ by(auto simp add: ElementMonad.put_M_defs type_wf_defs)
+qed
+
+lemma new_character_data_type_wf_preserved [simp]:
+ assumes "h \<turnstile> new_character_data \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+proof -
+ obtain new_character_data_ptr where "h \<turnstile> new_character_data \<rightarrow>\<^sub>r new_character_data_ptr"
+ using assms
+ by (meson is_OK_returns_heap_I is_OK_returns_result_E)
+ with assms have "object_ptr_kinds h' = object_ptr_kinds h |\<union>| {|cast new_character_data_ptr|}"
+ using new_character_data_new_ptr by auto
+ then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ with assms show ?thesis
+ by(auto simp add: CharacterDataMonad.new_character_data_def type_wf_defs Let_def
+ elim!: bind_returns_heap_E split: prod.splits)
+qed
+lemma put_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a_val_type_wf_preserved [simp]:
+ assumes "h \<turnstile> put_M character_data_ptr val_update v \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+proof -
+ have "object_ptr_kinds h = object_ptr_kinds h'"
+ using writes_singleton assms object_ptr_kinds_preserved unfolding all_args_def by fastforce
+ then have "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ with assms show ?thesis
+ by(auto simp add: CharacterDataMonad.put_M_defs type_wf_defs)
+qed
+
+lemma new_document_type_wf_preserved [simp]:
+ "h \<turnstile> new_document \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: new_document_def new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def Let_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ is_node_ptr_kind_none
+ elim!: bind_returns_heap_E type_wf_put_ptr_not_in_heap_E
+ intro!: type_wf_put_I DocumentMonad.type_wf_put_I ElementMonad.type_wf_put_I CharacterDataMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I
+ split: if_splits)[1]
+ apply(auto simp add: type_wf_defs ElementClass.type_wf_defs CharacterDataClass.type_wf_defs
+ NodeClass.type_wf_defs ObjectClass.type_wf_defs is_document_kind_def
+ split: option.splits)[1]
+ apply (metis fMax_finsert fimage_is_fempty new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def new\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_ptr_not_in_heap)
+ apply(auto simp add: type_wf_defs ElementClass.type_wf_defs CharacterDataClass.type_wf_defs
+ NodeClass.type_wf_defs ObjectClass.type_wf_defs is_document_kind_def
+ split: option.splits)[1]
+ apply(metis Suc_n_not_le_n document_ptr.sel(1) document_ptrs_def fMax_ge ffmember_filter fimage_eqI is_document_ptr_ref)
+ done
+
+lemma put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_doctype_type_wf_preserved [simp]:
+ "h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr doctype_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: DocumentMonad.put_M_defs put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I DocumentMonad.type_wf_put_I CharacterDataMonad.type_wf_put_I
+ ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+proof -
+ fix x
+ assume 0: "h \<turnstile> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr id \<rightarrow>\<^sub>r x"
+ and 1: "h' = put (cast document_ptr) (cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (x\<lparr>doctype := v\<rparr>)) h"
+ and 2: "ShadowRootClass.type_wf h"
+ and 3: "is_shadow_root_ptr_kind document_ptr"
+ obtain shadow_root_ptr where shadow_root_ptr: "document_ptr = cast shadow_root_ptr" and
+ "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ by (metis "0" "3" DocumentMonad.get_M_ptr_in_heap is_OK_returns_result_I
+ is_shadow_root_ptr_kind_obtains shadow_root_ptr_kinds_commutes)
+
+ then have "is_shadow_root_kind x"
+ using 0 2
+ apply(auto simp add: is_document_kind_def type_wf_defs is_shadow_root_kind_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
+ split: option.splits Option.bind_splits)[1]
+ by (metis (no_types, lifting) DocumentMonad.get_M_defs finite_set_in get_heap_returns_result
+ id_apply option.simps(5) return_returns_result)
+
+
+ then show "\<exists>y. cast y = x\<lparr>doctype := v\<rparr>"
+ using cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_none is_shadow_root_kind_doctype is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def by blast
+next
+ fix x
+ assume 0: "h \<turnstile> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr id \<rightarrow>\<^sub>r x"
+ and 1: "h' = put (cast document_ptr) (cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (x\<lparr>doctype := v\<rparr>)) h"
+ and 2: "ShadowRootClass.type_wf (put (cast document_ptr) (cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (x\<lparr>doctype := v\<rparr>)) h)"
+ have 3: "\<And>document_ptr'. document_ptr' \<noteq> document_ptr \<Longrightarrow> get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast document_ptr') h = get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast document_ptr') h'"
+ by (simp add: "1")
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ by (meson "0" DocumentMonad.get_M_ptr_in_heap is_OK_returns_result_I)
+ show "ShadowRootClass.type_wf h"
+ proof (cases "is_shadow_root_ptr_kind document_ptr")
+ case True
+ then obtain shadow_root_ptr where shadow_root_ptr: "document_ptr = cast shadow_root_ptr"
+ using is_shadow_root_ptr_kind_obtains by blast
+ then
+ have "is_shadow_root_kind (x\<lparr>doctype := v\<rparr>)"
+ using 2 True
+ by(simp add: type_wf_defs is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def split: if_splits option.splits)
+ then
+ have "is_shadow_root_kind x"
+ using is_shadow_root_kind_doctype by blast
+ then
+ have "is_shadow_root_kind (the (get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast document_ptr) h))"
+ using 0
+ by(auto simp add: DocumentMonad.a_get_M_def get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def is_shadow_root_kind_def
+ split: option.splits Option.bind_splits)
+ show ?thesis
+ using 0 2 \<open>is_shadow_root_kind x\<close> shadow_root_ptr
+ by(auto simp add: DocumentMonad.a_get_M_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def is_shadow_root_kind_def
+ is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits if_splits)
+ next
+ case False
+ then show ?thesis
+ using 0 1 2
+ by(auto simp add: DocumentMonad.a_get_M_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def is_shadow_root_kind_def
+ is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits if_splits)
+ qed
+qed
+
+lemma put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_document_element_type_wf_preserved [simp]:
+ assumes "h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr document_element_update v \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+ using assms
+ apply(auto simp add: DocumentMonad.put_M_defs put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I DocumentMonad.type_wf_put_I CharacterDataMonad.type_wf_put_I
+ ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+proof -
+ fix x
+ assume 0: "h \<turnstile> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr id \<rightarrow>\<^sub>r x"
+ and 1: "h' = put (cast document_ptr) (cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (x\<lparr>document_element := v\<rparr>)) h"
+ and 2: "ShadowRootClass.type_wf h"
+ and 3: "is_shadow_root_ptr_kind document_ptr"
+ obtain shadow_root_ptr where shadow_root_ptr: "document_ptr = cast shadow_root_ptr" and
+ "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ by (metis "0" "3" DocumentMonad.get_M_ptr_in_heap is_OK_returns_result_I
+ is_shadow_root_ptr_kind_obtains shadow_root_ptr_kinds_commutes)
+
+ then have "is_shadow_root_kind x"
+ using 0 2
+ apply(auto simp add: is_document_kind_def type_wf_defs is_shadow_root_kind_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
+ split: option.splits Option.bind_splits)[1]
+ by (metis (no_types, lifting) DocumentMonad.get_M_defs finite_set_in get_heap_returns_result id_def
+ option.simps(5) return_returns_result)
+
+ then show "\<exists>y. cast y = x\<lparr>document_element := v\<rparr>"
+ using cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_none is_shadow_root_kind_document_element is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ by blast
+next
+ fix x
+ assume 0: "h \<turnstile> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr id \<rightarrow>\<^sub>r x"
+ and 1: "h' = put (cast document_ptr) (cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (x\<lparr>document_element := v\<rparr>)) h"
+ and 2: "ShadowRootClass.type_wf (put (cast document_ptr) (cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (x\<lparr>document_element := v\<rparr>)) h)"
+ have 3: "\<And>document_ptr'. document_ptr' \<noteq> document_ptr \<Longrightarrow> get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast document_ptr') h = get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast document_ptr') h'"
+ by (simp add: "1")
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ by (meson "0" DocumentMonad.get_M_ptr_in_heap is_OK_returns_result_I)
+ show "ShadowRootClass.type_wf h"
+ proof (cases "is_shadow_root_ptr_kind document_ptr")
+ case True
+ then obtain shadow_root_ptr where shadow_root_ptr: "document_ptr = cast shadow_root_ptr"
+ using is_shadow_root_ptr_kind_obtains by blast
+ then
+ have "is_shadow_root_kind (x\<lparr>document_element := v\<rparr>)"
+ using 2 True
+ by(simp add: type_wf_defs is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def split: if_splits option.splits)
+ then
+ have "is_shadow_root_kind x"
+ using is_shadow_root_kind_document_element by blast
+ then
+ have "is_shadow_root_kind (the (get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast document_ptr) h))"
+ using 0
+ by(auto simp add: DocumentMonad.a_get_M_def get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def is_shadow_root_kind_def
+ split: option.splits Option.bind_splits)
+ show ?thesis
+ using 0 2 \<open>is_shadow_root_kind x\<close> shadow_root_ptr
+ by(auto simp add: DocumentMonad.a_get_M_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def is_shadow_root_kind_def
+ is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits if_splits)
+ next
+ case False
+ then show ?thesis
+ using 0 1 2
+ by(auto simp add: DocumentMonad.a_get_M_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def is_shadow_root_kind_def
+ is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits if_splits)
+ qed
+qed
+
+lemma put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_disconnected_nodes_type_wf_preserved [simp]:
+ assumes "h \<turnstile> put_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr disconnected_nodes_update v \<rightarrow>\<^sub>h h'"
+ shows "type_wf h = type_wf h'"
+
+ using assms
+ apply(auto simp add: DocumentMonad.put_M_defs put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def dest!: get_heap_E
+ elim!: bind_returns_heap_E2
+ intro!: type_wf_put_I DocumentMonad.type_wf_put_I CharacterDataMonad.type_wf_put_I
+ ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+ apply(auto simp add: is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits)[1]
+proof -
+ fix x
+ assume 0: "h \<turnstile> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr id \<rightarrow>\<^sub>r x"
+ and 1: "h' = put (cast document_ptr) (cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (x\<lparr>disconnected_nodes := v\<rparr>)) h"
+ and 2: "ShadowRootClass.type_wf h"
+ and 3: "is_shadow_root_ptr_kind document_ptr"
+ obtain shadow_root_ptr where shadow_root_ptr: "document_ptr = cast shadow_root_ptr" and
+ "shadow_root_ptr |\<in>| shadow_root_ptr_kinds h"
+ by (metis "0" "3" DocumentMonad.get_M_ptr_in_heap is_OK_returns_result_I is_shadow_root_ptr_kind_obtains
+ shadow_root_ptr_kinds_commutes)
+
+ then have "is_shadow_root_kind x"
+ using 0 2
+ apply(auto simp add: is_document_kind_def type_wf_defs is_shadow_root_kind_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
+ split: option.splits Option.bind_splits)[1]
+ by (metis (no_types, lifting) DocumentMonad.get_M_defs finite_set_in get_heap_returns_result
+ id_def option.simps(5) return_returns_result)
+
+ then show "\<exists>y. cast y = x\<lparr>disconnected_nodes := v\<rparr>"
+ using cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_none is_shadow_root_kind_disconnected_nodes is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ by blast
+next
+ fix x
+ assume 0: "h \<turnstile> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr id \<rightarrow>\<^sub>r x"
+ and 1: "h' = put (cast document_ptr) (cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (x\<lparr>disconnected_nodes := v\<rparr>)) h"
+ and 2: "ShadowRootClass.type_wf (put (cast document_ptr) (cast\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>2\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (x\<lparr>disconnected_nodes := v\<rparr>)) h)"
+ have 3: "\<And>document_ptr'. document_ptr' \<noteq> document_ptr \<Longrightarrow> get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast document_ptr') h = get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast document_ptr') h'"
+ by (simp add: "1")
+ have "document_ptr |\<in>| document_ptr_kinds h"
+ by (meson "0" DocumentMonad.get_M_ptr_in_heap is_OK_returns_result_I)
+ show "ShadowRootClass.type_wf h"
+ proof (cases "is_shadow_root_ptr_kind document_ptr")
+ case True
+ then obtain shadow_root_ptr where shadow_root_ptr: "document_ptr = cast shadow_root_ptr"
+ using is_shadow_root_ptr_kind_obtains by blast
+ then
+ have "is_shadow_root_kind (x\<lparr>disconnected_nodes := v\<rparr>)"
+ using 2 True
+ by(simp add: type_wf_defs is_shadow_root_kind\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def split: if_splits option.splits)
+ then
+ have "is_shadow_root_kind x"
+ using is_shadow_root_kind_disconnected_nodes by blast
+ then
+ have "is_shadow_root_kind (the (get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t (cast document_ptr) h))"
+ using 0
+ by(auto simp add: DocumentMonad.a_get_M_def get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def is_shadow_root_kind_def
+ split: option.splits Option.bind_splits)
+ show ?thesis
+ using 0 2 \<open>is_shadow_root_kind x\<close> shadow_root_ptr
+ by(auto simp add: DocumentMonad.a_get_M_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def is_shadow_root_kind_def
+ is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits if_splits)
+ next
+ case False
+ then show ?thesis
+ using 0 1 2
+ by(auto simp add: DocumentMonad.a_get_M_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def is_shadow_root_kind_def
+ is_document_kind_def type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs
+ CharacterDataClass.type_wf_defs split: option.splits if_splits)
+ qed
+qed
+
+lemma put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_mode_type_wf_preserved [simp]:
+ "h \<turnstile> put_M shadow_root_ptr mode_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ by(auto simp add: get_M_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def DocumentMonad.get_M_defs put_M_defs put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
+ put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def dest!: get_heap_E elim!: bind_returns_heap_E2 intro!: type_wf_put_I DocumentMonad.type_wf_put_I
+ CharacterDataMonad.type_wf_put_I ElementMonad.type_wf_put_I NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I
+ simp add: is_shadow_root_kind_def is_document_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs CharacterDataClass.type_wf_defs DocumentClass.type_wf_defs split: option.splits)[1]
+
+lemma put_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_child_nodes_type_wf_preserved [simp]:
+ "h \<turnstile> put_M shadow_root_ptr RShadowRoot.child_nodes_update v \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ by(auto simp add: get_M_defs get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def DocumentMonad.get_M_defs put_M_defs put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def
+ put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def dest!: get_heap_E elim!: bind_returns_heap_E2 intro!: type_wf_put_I
+ DocumentMonad.type_wf_put_I CharacterDataMonad.type_wf_put_I ElementMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I
+ simp add: is_shadow_root_kind_def is_document_kind_def type_wf_defs ElementClass.type_wf_defs
+ NodeClass.type_wf_defs ElementMonad.get_M_defs ObjectClass.type_wf_defs CharacterDataClass.type_wf_defs
+ DocumentClass.type_wf_defs split: option.splits)[1]
+
+lemma shadow_root_ptr_kinds_small:
+ assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ shows "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
+ by(auto simp add: shadow_root_ptr_kinds_def document_ptr_kinds_def preserved_def
+ object_ptr_kinds_preserved_small[OF assms])
+
+lemma shadow_root_ptr_kinds_preserved:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h'. \<forall>w \<in> SW. h \<turnstile> w \<rightarrow>\<^sub>h h' \<longrightarrow> (\<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h')"
+ shows "shadow_root_ptr_kinds h = shadow_root_ptr_kinds h'"
+ using writes_small_big[OF assms]
+ apply(simp add: reflp_def transp_def preserved_def shadow_root_ptr_kinds_def document_ptr_kinds_def)
+ by (metis assms object_ptr_kinds_preserved)
+
+
+lemma new_shadow_root_known_ptr:
+ assumes "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>r new_shadow_root_ptr"
+ shows "known_ptr (cast new_shadow_root_ptr)"
+ using assms
+ apply(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def a_known_ptr_def
+ elim!: bind_returns_result_E2 split: prod.splits)[1]
+ using assms new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_is_shadow_root_ptr by blast
+
+
+lemma new_shadow_root_type_wf_preserved [simp]: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ apply(auto simp add: new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def Let_def put\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def put\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ ShadowRootClass.type_wf\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t ShadowRootClass.type_wf\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a ShadowRootClass.type_wf\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t
+ ShadowRootClass.type_wf\<^sub>N\<^sub>o\<^sub>d\<^sub>e ShadowRootClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t
+ is_node_ptr_kind_none new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_ptr_not_in_heap
+ elim!: bind_returns_heap_E type_wf_put_ptr_not_in_heap_E
+ intro!: type_wf_put_I DocumentMonad.type_wf_put_I ElementMonad.type_wf_put_I CharacterDataMonad.type_wf_put_I
+ NodeMonad.type_wf_put_I ObjectMonad.type_wf_put_I
+ split: if_splits)[1]
+ by(auto simp add: type_wf_defs DocumentClass.type_wf_defs ElementClass.type_wf_defs CharacterDataClass.type_wf_defs
+ NodeClass.type_wf_defs ObjectClass.type_wf_defs is_shadow_root_kind_def is_document_kind_def
+ split: option.splits)[1]
+
+
+locale l_new_shadow_root = l_type_wf +
+ assumes new_shadow_root_types_preserved: "h \<turnstile> new\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+
+lemma new_shadow_root_is_l_new_shadow_root [instances]: "l_new_shadow_root type_wf"
+ using l_new_shadow_root.intro new_shadow_root_type_wf_preserved
+ by blast
+
+lemma type_wf_preserved_small:
+ assumes "\<And>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ assumes "\<And>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
+ assumes "\<And>element_ptr. preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr RElement.nothing) h h'"
+ assumes "\<And>character_data_ptr. preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr RCharacterData.nothing) h h'"
+ assumes "\<And>document_ptr. preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr RDocument.nothing) h h'"
+ assumes "\<And>shadow_root_ptr. preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr RShadowRoot.nothing) h h'"
+ shows "type_wf h = type_wf h'"
+ using type_wf_preserved_small[OF assms(1) assms(2) assms(3) assms(4) assms(5)]
+ allI[OF assms(6), of id, simplified] shadow_root_ptr_kinds_small[OF assms(1)]
+ apply(auto simp add: type_wf_defs )[1]
+ apply(auto simp add: preserved_def get_M_defs shadow_root_ptr_kinds_small[OF assms(1)]
+ split: option.splits)[1]
+ apply(force)
+ apply(auto simp add: preserved_def get_M_defs shadow_root_ptr_kinds_small[OF assms(1)]
+ split: option.splits)[1]
+ apply(force)
+ done
+
+lemma type_wf_preserved:
+ assumes "writes SW setter h h'"
+ assumes "h \<turnstile> setter \<rightarrow>\<^sub>h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> \<forall>object_ptr. preserved (get_M\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t object_ptr RObject.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> \<forall>node_ptr. preserved (get_M\<^sub>N\<^sub>o\<^sub>d\<^sub>e node_ptr RNode.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> \<forall>element_ptr. preserved (get_M\<^sub>E\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t element_ptr RElement.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> \<forall>character_data_ptr. preserved (get_M\<^sub>C\<^sub>h\<^sub>a\<^sub>r\<^sub>a\<^sub>c\<^sub>t\<^sub>e\<^sub>r\<^sub>D\<^sub>a\<^sub>t\<^sub>a character_data_ptr RCharacterData.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> \<forall>document_ptr. preserved (get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr RDocument.nothing) h h'"
+ assumes "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> \<forall>shadow_root_ptr. preserved (get_M\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t shadow_root_ptr RShadowRoot.nothing) h h'"
+ shows "type_wf h = type_wf h'"
+proof -
+ have "\<And>h h' w. w \<in> SW \<Longrightarrow> h \<turnstile> w \<rightarrow>\<^sub>h h' \<Longrightarrow> type_wf h = type_wf h'"
+ using assms type_wf_preserved_small by fast
+ with assms(1) assms(2) show ?thesis
+ apply(rule writes_small_big)
+ by(auto simp add: reflp_def transp_def)
+qed
+
+lemma type_wf_drop: "type_wf h \<Longrightarrow> type_wf (Heap (fmdrop ptr (the_heap h)))"
+ apply(auto simp add: type_wf_defs)[1]
+ using type_wf_drop
+ apply blast
+ by (metis (no_types, lifting) DocumentClass.type_wf\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t DocumentMonad.type_wf_drop
+ ObjectClass.get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_type_wf document_ptr_kinds_commutes finite_set_in fmlookup_drop get\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t_def
+ get\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def get\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def heap.sel shadow_root_ptr_kinds_commutes)
+
+lemma delete_shadow_root_type_wf_preserved [simp]:
+ assumes "h \<turnstile> delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M shadow_root_ptr \<rightarrow>\<^sub>h h'"
+ assumes "type_wf h"
+ shows "type_wf h'"
+ using assms
+ using type_wf_drop
+ by(auto simp add: delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_M_def delete\<^sub>S\<^sub>h\<^sub>a\<^sub>d\<^sub>o\<^sub>w\<^sub>R\<^sub>o\<^sub>o\<^sub>t_def delete\<^sub>O\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t_def split: if_splits)
+
+
+
+lemma new_element_is_l_new_element [instances]:
+ "l_new_element type_wf"
+ using l_new_element.intro new_element_type_wf_preserved
+ by blast
+
+lemma new_character_data_is_l_new_character_data [instances]:
+ "l_new_character_data type_wf"
+ using l_new_character_data.intro new_character_data_type_wf_preserved
+ by blast
+
+lemma new_document_is_l_new_document [instances]:
+ "l_new_document type_wf"
+ using l_new_document.intro new_document_type_wf_preserved
+ by blast
+end
diff --git a/thys/Shadow_SC_DOM/tests/Document-adoptNode.html b/thys/Shadow_SC_DOM/tests/Document-adoptNode.html
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/Document-adoptNode.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Document.adoptNode</title>
+<link rel=help href="https://dom.spec.whatwg.org/#dom-document-adoptnode">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<x<>x</x<>
+<script>
+test(function() {
+ var y = document.getElementsByTagName("x<")[0]
+ var child = y.firstChild
+ assert_equals(y.parentNode, document.body)
+ assert_equals(y.ownerDocument, document)
+ assert_equals(document.adoptNode(y), y)
+ assert_equals(y.parentNode, null)
+ assert_equals(y.firstChild, child)
+ assert_equals(y.ownerDocument, document)
+ assert_equals(child.ownerDocument, document)
+ var doc = document.implementation.createDocument(null, null, null)
+ assert_equals(doc.adoptNode(y), y)
+ assert_equals(y.parentNode, null)
+ assert_equals(y.firstChild, child)
+ assert_equals(y.ownerDocument, doc)
+ assert_equals(child.ownerDocument, doc)
+}, "Adopting an Element called 'x<' should work.")
+
+test(function() {
+ var x = document.createElement(":good:times:")
+ assert_equals(document.adoptNode(x), x);
+ var doc = document.implementation.createDocument(null, null, null)
+ assert_equals(doc.adoptNode(x), x)
+ assert_equals(x.parentNode, null)
+ assert_equals(x.ownerDocument, doc)
+}, "Adopting an Element called ':good:times:' should work.")
+</script>
diff --git a/thys/Shadow_SC_DOM/tests/Document-getElementById.html b/thys/Shadow_SC_DOM/tests/Document-getElementById.html
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/Document-getElementById.html
@@ -0,0 +1,251 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Document.getElementById</title>
+<link rel="author" title="Tetsuharu OHZEKI" href="mailto:saneyuki.snyk@gmail.com">
+<link rel=help href="https://dom.spec.whatwg.org/#dom-document-getelementbyid">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+ <div id="log"></div>
+
+ <div id=""></div>
+
+ <div id="test1"></div>
+
+ <div id="test5" data-name="1st">
+ <p id="test5" data-name="2nd">P</p>
+ <input id="test5" type="submit" value="Submit" data-name="3rd">
+ </div>
+
+ <div id="outer">
+ <div id="middle">
+ <div id="inner"></div>
+ </div>
+ </div>
+
+<script>
+ test(function() {
+ var gBody = document.body;
+
+ var TEST_ID = "test2";
+
+ var test = document.createElement("div");
+ test.setAttribute("id", TEST_ID);
+ gBody.appendChild(test);
+
+ // test: appended element
+ var result = document.getElementById(TEST_ID);
+ assert_not_equals(result, null, "should not be null.");
+ assert_equals(result.tagName, "div", "should have appended element's tag name");
+
+ // test: removed element
+ gBody.removeChild(test);
+ var removed = document.getElementById(TEST_ID);
+ // `document.getElementById()` returns `null` if there is none.
+ // https://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid
+ assert_equals(removed, null, "should not get removed element.");
+ }, "Document.getElementById with a script-inserted element");
+
+
+ test(function() {
+ var gBody = document.body;
+
+ // setup fixtures.
+ var TEST_ID = "test3";
+ var test = document.createElement("div");
+ test.setAttribute("id", TEST_ID);
+ gBody.appendChild(test);
+
+ // update id
+ var UPDATED_ID = "test3-updated";
+ test.setAttribute("id", UPDATED_ID);
+ var e = document.getElementById(UPDATED_ID);
+ assert_equals(e, test, "should get the element with id.");
+
+ var old = document.getElementById(TEST_ID);
+ assert_equals(old, null, "shouldn't get the element by the old id.");
+
+ // remove id.
+ test.removeAttribute("id");
+ var e2 = document.getElementById(UPDATED_ID);
+ assert_equals(e2, null, "should return null when the passed id is none in document.");
+ }, "update `id` attribute via setAttribute/removeAttribute");
+
+
+ test(function() {
+ var TEST_ID = "test4-should-not-exist";
+
+ var e = document.createElement('div');
+ e.setAttribute("id", TEST_ID);
+
+ assert_equals(document.getElementById(TEST_ID), null, "should be null");
+ document.body.appendChild(e);
+ assert_equals(document.getElementById(TEST_ID), e, "should be the appended element");
+ }, "Ensure that the id attribute only affects elements present in a document");
+
+
+ test(function() {
+ var gBody = document.body;
+
+ // the method should return the 1st element.
+ var TEST_ID = "test5";
+ var target = document.getElementById(TEST_ID);
+ assert_not_equals(target, null, "should not be null");
+ assert_equals(target.getAttribute("data-name"), "1st", "should return the 1st");
+
+ // even if after the new element was appended.
+ var element4 = document.createElement("div");
+ element4.setAttribute("id", TEST_ID);
+ element4.setAttribute("data-name", "4th");
+ gBody.appendChild(element4);
+ var target2 = document.getElementById(TEST_ID);
+ assert_not_equals(target2, null, "should not be null");
+ assert_equals(target2.getAttribute("data-name"), "1st", "should be the 1st");
+
+ // should return the next element after removed the subtree including the 1st element.
+ target2.parentNode.removeChild(target2);
+ var target3 = document.getElementById(TEST_ID);
+ assert_not_equals(target3, null, "should not be null");
+ assert_equals(target3.getAttribute("data-name"), "4th", "should be the 4th");
+ }, "in tree order, within the context object's tree");
+
+
+ test(function() {
+ var TEST_ID = "test6";
+ var s = document.createElement("div");
+ s.setAttribute("id", TEST_ID);
+ // append to Element, not Document.
+ document.createElement("div").appendChild(s);
+
+ assert_equals(document.getElementById(TEST_ID), null, "should be null");
+ }, "Modern browsers optimize this method with using internal id cache. This test checks that their optimization should effect only append to `Document`, not append to `Node`.");
+
+
+ test(function() {
+ var gBody = document.body;
+
+ var TEST_ID = "test7"
+ var element = document.createElement("div");
+ element.setAttribute("id", TEST_ID);
+ gBody.appendChild(element);
+
+ var target = document.getElementById(TEST_ID);
+ assert_equals(target, element, "should return the element before changing the value");
+
+ element.setAttribute("id", TEST_ID + "-updated");
+ var target2 = document.getElementById(TEST_ID);
+ assert_equals(target2, null, "should return null after updated id via Attr.value");
+ var target3 = document.getElementById(TEST_ID + "-updated");
+ assert_equals(target3, element, "should be equal to the updated element.");
+ }, "changing attribute's value via `Attr` gotten from `Element.attribute`.");
+
+
+ test(function() {
+ var gBody = document.body;
+
+ // setup fixtures.
+ var TEST_ID = "test12";
+ var test = document.createElement("div");
+ test.setAttribute("id", TEST_ID);
+ gBody.appendChild(test);
+
+ // update id
+ var UPDATED_ID = TEST_ID + "-updated";
+ test.setAttribute("id", UPDATED_ID);
+ var e = document.getElementById(UPDATED_ID);
+ assert_equals(e, test, "should get the element with id.");
+
+ var old = document.getElementById(TEST_ID);
+ assert_equals(old, null, "shouldn't get the element by the old id.");
+
+ // remove id.
+ test.setAttribute("id", "");
+ var e2 = document.getElementById(UPDATED_ID);
+ assert_equals(e2, null, "should return null when the passed id is none in document.");
+ }, "update `id` attribute via element.id");
+
+
+ test(function() {
+ var gBody = document.body;
+
+ var TEST_ID = "test13";
+
+ // create fixture
+ var container = document.createElement("div");
+ container.setAttribute("id", TEST_ID + "-fixture");
+ gBody.appendChild(container);
+
+ var element1 = document.createElement("div");
+ element1.setAttribute("id", TEST_ID);
+ var element2 = document.createElement("div");
+ element2.setAttribute("id", TEST_ID);
+ var element3 = document.createElement("div");
+ element3.setAttribute("id", TEST_ID);
+ var element4 = document.createElement("div");
+ element4.setAttribute("id", TEST_ID);
+
+ // append element: 2 -> 4 -> 3 -> 1
+ container.appendChild(element2);
+ container.appendChild(element4);
+ container.insertBefore(element3, element4);
+ container.insertBefore(element1, element2);
+
+
+ var test = document.getElementById(TEST_ID);
+ assert_equals(test, element1, "should return 1st element");
+ container.removeChild(element1);
+
+ test = document.getElementById(TEST_ID);
+ assert_equals(test, element2, "should return 2nd element");
+ container.removeChild(element2);
+
+ test = document.getElementById(TEST_ID);
+ assert_equals(test, element3, "should return 3rd element");
+ container.removeChild(element3);
+
+ test = document.getElementById(TEST_ID);
+ assert_equals(test, element4, "should return 4th element");
+ container.removeChild(element4);
+
+
+ }, "where insertion order and tree order don't match");
+
+ test(function() {
+ var gBody = document.body;
+
+ var TEST_ID = "test14";
+ var a = document.createElement("a");
+ var b = document.createElement("b");
+ a.appendChild(b);
+ b.setAttribute("id", TEST_ID);
+ assert_equals(document.getElementById(TEST_ID), null);
+
+ gBody.appendChild(a);
+ assert_equals(document.getElementById(TEST_ID), b);
+ }, "Inserting an id by inserting its parent node");
+
+ test(function () {
+ var TEST_ID = "test15"
+ var outer = document.getElementById("outer");
+ var middle = document.getElementById("middle");
+ var inner = document.getElementById("inner");
+ outer.removeChild(middle);
+
+ var new_el = document.createElement("h1");
+ new_el.setAttribute("id", "heading");
+ inner.appendChild(new_el);
+ // the new element is not part of the document since
+ // "middle" element was removed previously
+ assert_equals(document.getElementById("heading"), null);
+ }, "Document.getElementById must not return nodes not present in document");
+
+ // TODO:
+ // id attribute in a namespace
+
+
+ // TODO:
+ // SVG + MathML elements with id attributes
+
+</script>
+</body>
+</html>
diff --git a/thys/Shadow_SC_DOM/tests/Node-insertBefore.html b/thys/Shadow_SC_DOM/tests/Node-insertBefore.html
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/Node-insertBefore.html
@@ -0,0 +1,288 @@
+<!DOCTYPE html>
+<title>Node.insertBefore</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+ <div id="log"></div>
+</body>
+<script>
+test(function() {
+ var node = document.createTextNode("Foo");
+ assert_throws("HIERARCHY_REQUEST_ERR", function() { node.insertBefore(document.createTextNode("fail"), null) })
+
+}, "Calling insertBefore an a leaf node Text must throw HIERARCHY_REQUEST_ERR.")
+
+
+test(function() {
+ // Step 2.
+ assert_throws("HIERARCHY_REQUEST_ERR", function() { document.body.insertBefore(document.body, document.getElementById("log")) })
+ assert_throws("HIERARCHY_REQUEST_ERR", function() { document.body.insertBefore(document.documentElement, document.getElementById("log")) })
+}, "Calling insertBefore with an inclusive ancestor of the context object must throw HIERARCHY_REQUEST_ERR.")
+
+// Step 3.
+test(function() {
+ var a = document.createElement("div");
+ var b = document.createElement("div");
+ var c = document.createElement("div");
+ assert_throws("NotFoundError", function() {
+ a.insertBefore(b, c);
+ });
+}, "Calling insertBefore with a reference child whose parent is not the context node must throw a NotFoundError.")
+
+// Step 4.1.
+test(function() {
+ var doc = document.implementation.createHTMLDocument("title");
+ var doc2 = document.implementation.createHTMLDocument("title2");
+ assert_throws("HierarchyRequestError", function() {
+ doc.insertBefore(doc2, doc.documentElement);
+ });
+
+ assert_throws("HierarchyRequestError", function() {
+ doc.insertBefore(doc.createTextNode("text"), doc.documentElement);
+ });
+}, "If the context node is a document, inserting a document or text node should throw a HierarchyRequestError.")
+//
+// // Step 4.2.1.
+// test(function() {
+// var doc = document.implementation.createHTMLDocument("title");
+// doc.removeChild(doc.documentElement);
+//
+// var df = doc.createDocumentFragment();
+// df.appendChild(doc.createElement("a"));
+// df.appendChild(doc.createElement("b"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, null);
+// });
+//
+// df = doc.createDocumentFragment();
+// df.appendChild(doc.createTextNode("text"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, null);
+// });
+//
+// df = doc.createDocumentFragment();
+// df.appendChild(doc.createComment("comment"));
+// df.appendChild(doc.createTextNode("text"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, null);
+// });
+// }, "If the context node is a document, appending a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.")
+// test(function() {
+// var doc = document.implementation.createHTMLDocument("title");
+// doc.removeChild(doc.documentElement);
+//
+// var df = doc.createDocumentFragment();
+// df.appendChild(doc.createElement("a"));
+// df.appendChild(doc.createElement("b"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.firstChild);
+// });
+//
+// df = doc.createDocumentFragment();
+// df.appendChild(doc.createTextNode("text"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.firstChild);
+// });
+//
+// df = doc.createDocumentFragment();
+// df.appendChild(doc.createComment("comment"));
+// df.appendChild(doc.createTextNode("text"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.firstChild);
+// });
+// }, "If the context node is a document, inserting a DocumentFragment that contains a text node or too many elements should throw a HierarchyRequestError.")
+//
+// // Step 4.2.2.
+// test(function() {
+// // The context node has an element child.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.appendChild(doc.createComment("foo"));
+// assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
+//
+// var df = doc.createDocumentFragment();
+// df.appendChild(doc.createElement("a"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.doctype);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.documentElement);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, comment);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, null);
+// });
+// }, "If the context node is a document, inserting a DocumentFragment with an element if there already is an element child should throw a HierarchyRequestError.")
+// test(function() {
+// // /child/ is a doctype.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
+// doc.removeChild(doc.documentElement);
+// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
+//
+// var df = doc.createDocumentFragment();
+// df.appendChild(doc.createElement("a"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, doc.doctype);
+// });
+// }, "If the context node is a document and a doctype is following the reference child, inserting a DocumentFragment with an element should throw a HierarchyRequestError.")
+// test(function() {
+// // /child/ is not null and a doctype is following /child/.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
+// doc.removeChild(doc.documentElement);
+// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
+//
+// var df = doc.createDocumentFragment();
+// df.appendChild(doc.createElement("a"));
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(df, comment);
+// });
+// }, "If the context node is a document, inserting a DocumentFragment with an element before the doctype should throw a HierarchyRequestError.")
+//
+// // Step 4.3.
+// test(function() {
+// // The context node has an element child.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.appendChild(doc.createComment("foo"));
+// assert_array_equals(doc.childNodes, [doc.doctype, doc.documentElement, comment]);
+//
+// var a = doc.createElement("a");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, doc.doctype);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, doc.documentElement);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, comment);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, null);
+// });
+// }, "If the context node is a document, inserting an element if there already is an element child should throw a HierarchyRequestError.")
+// test(function() {
+// // /child/ is a doctype.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
+// doc.removeChild(doc.documentElement);
+// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
+//
+// var a = doc.createElement("a");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, doc.doctype);
+// });
+// }, "If the context node is a document, inserting an element before the doctype should throw a HierarchyRequestError.")
+// test(function() {
+// // /child/ is not null and a doctype is following /child/.
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
+// doc.removeChild(doc.documentElement);
+// assert_array_equals(doc.childNodes, [comment, doc.doctype]);
+//
+// var a = doc.createElement("a");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(a, comment);
+// });
+// }, "If the context node is a document and a doctype is following the reference child, inserting an element should throw a HierarchyRequestError.")
+//
+// // Step 4.4.
+// test(function() {
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.insertBefore(doc.createComment("foo"), doc.firstChild);
+// assert_array_equals(doc.childNodes, [comment, doc.doctype, doc.documentElement]);
+//
+// var doctype = document.implementation.createDocumentType("html", "", "");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, comment);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, doc.doctype);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, doc.documentElement);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, null);
+// });
+// }, "If the context node is a document, inserting a doctype if there already is a doctype child should throw a HierarchyRequestError.")
+// test(function() {
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.appendChild(doc.createComment("foo"));
+// doc.removeChild(doc.doctype);
+// assert_array_equals(doc.childNodes, [doc.documentElement, comment]);
+//
+// var doctype = document.implementation.createDocumentType("html", "", "");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, comment);
+// });
+// }, "If the context node is a document, inserting a doctype after the document element should throw a HierarchyRequestError.")
+// test(function() {
+// var doc = document.implementation.createHTMLDocument("title");
+// var comment = doc.appendChild(doc.createComment("foo"));
+// doc.removeChild(doc.doctype);
+// assert_array_equals(doc.childNodes, [doc.documentElement, comment]);
+//
+// var doctype = document.implementation.createDocumentType("html", "", "");
+// assert_throws("HierarchyRequestError", function() {
+// doc.insertBefore(doctype, null);
+// });
+// }, "If the context node is a document with and element child, appending a doctype should throw a HierarchyRequestError.")
+//
+// // Step 5.
+// test(function() {
+// var df = document.createDocumentFragment();
+// var a = df.appendChild(document.createElement("a"));
+//
+// var doc = document.implementation.createHTMLDocument("title");
+// assert_throws("HierarchyRequestError", function() {
+// df.insertBefore(doc, a);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// df.insertBefore(doc, null);
+// });
+//
+// var doctype = document.implementation.createDocumentType("html", "", "");
+// assert_throws("HierarchyRequestError", function() {
+// df.insertBefore(doctype, a);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// df.insertBefore(doctype, null);
+// });
+// }, "If the context node is a DocumentFragment, inserting a document or a doctype should throw a HierarchyRequestError.")
+// test(function() {
+// var el = document.createElement("div");
+// var a = el.appendChild(document.createElement("a"));
+//
+// var doc = document.implementation.createHTMLDocument("title");
+// assert_throws("HierarchyRequestError", function() {
+// el.insertBefore(doc, a);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// el.insertBefore(doc, null);
+// });
+//
+// var doctype = document.implementation.createDocumentType("html", "", "");
+// assert_throws("HierarchyRequestError", function() {
+// el.insertBefore(doctype, a);
+// });
+// assert_throws("HierarchyRequestError", function() {
+// el.insertBefore(doctype, null);
+// });
+// }, "If the context node is an element, inserting a document or a doctype should throw a HierarchyRequestError.")
+//
+// Step 7.
+test(function() {
+ var a = document.createElement("div");
+ var b = document.createElement("div");
+ var c = document.createElement("div");
+ a.appendChild(b);
+ a.appendChild(c);
+ assert_array_equals(a.childNodes, [b, c]);
+ assert_equals(a.insertBefore(b, b), b);
+ assert_array_equals(a.childNodes, [b, c]);
+ assert_equals(a.insertBefore(c, c), c);
+ assert_array_equals(a.childNodes, [b, c]);
+}, "Inserting a node before itself should not move the node");
+</script>
diff --git a/thys/Shadow_SC_DOM/tests/Node-removeChild.html b/thys/Shadow_SC_DOM/tests/Node-removeChild.html
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/Node-removeChild.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<title>Node.removeChild</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="creators.js"></script>
+<body>
+ <div id="log"></div>
+</body>
+<iframe src=about:blank></iframe>
+<script>
+
+test(function() {
+ var doc = document;
+ var s = doc.createElement("div");
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
+ assert_equals(s.ownerDocument, doc)
+}, "Passing a detached Element to removeChild should not affect it.")
+
+test(function() {
+ var doc = document;
+ var s = doc.createElement("div");
+ doc.documentElement.appendChild(s)
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
+ assert_equals(s.ownerDocument, doc)
+}, "Passing a non-detached Element to removeChild should not affect it.")
+
+test(function() {
+ var doc = document;
+ var s = doc.createElement("div");
+ doc.body.appendChild(s)
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { s.removeChild(doc) })
+}, "Calling removeChild on an Element with no children should throw NOT_FOUND_ERR.")
+
+test(function() {
+ var doc = document.implementation.createHTMLDocument("");
+ var s = doc.createElement("div");
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
+ assert_equals(s.ownerDocument, doc)
+}, "Passing a detached Element to removeChild should not affect it.")
+
+test(function() {
+ var doc = document.implementation.createHTMLDocument("");
+ var s = doc.createElement("div");
+ doc.documentElement.appendChild(s)
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { document.body.removeChild(s) })
+ assert_equals(s.ownerDocument, doc)
+}, "Passing a non-detached Element to removeChild should not affect it.")
+
+test(function() {
+ var doc = document.implementation.createHTMLDocument("");
+ var s = doc.createElement("div");
+ doc.body.appendChild(s)
+ assert_equals(s.ownerDocument, doc)
+ assert_throws("NOT_FOUND_ERR", function() { s.removeChild(doc) })
+}, "Calling removeChild on an Element with no children should throw NOT_FOUND_ERR.")
+
+test(function() {
+ assert_throws(new TypeError(), function() { document.body.removeChild(null) })
+ //assert_throws(new TypeError(), function() { document.body.removeChild({'a':'b'}) })
+}, "Passing a value that is not a Node reference to removeChild should throw TypeError.")
+</script>
diff --git a/thys/Shadow_SC_DOM/tests/Shadow_DOM_BaseTest.thy b/thys/Shadow_SC_DOM/tests/Shadow_DOM_BaseTest.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/Shadow_DOM_BaseTest.thy
@@ -0,0 +1,460 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+section\<open>Shadow DOM Base Tests\<close>
+
+theory Shadow_DOM_BaseTest
+ imports
+ "../Shadow_DOM"
+begin
+
+
+definition "assert_throws e p = do {
+ h \<leftarrow> get_heap;
+ (if (h \<turnstile> p \<rightarrow>\<^sub>e e) then return () else error AssertException)
+}"
+notation assert_throws ("assert'_throws'(_, _')")
+
+definition "test p h \<longleftrightarrow> h \<turnstile> ok p"
+
+
+definition field_access :: "(string \<Rightarrow> (_, (_) object_ptr option) dom_prog) \<Rightarrow> string \<Rightarrow>
+(_, (_) object_ptr option) dom_prog" (infix "." 80)
+ where
+ "field_access m field = m field"
+
+definition assert_equals :: "'a \<Rightarrow> 'a \<Rightarrow> (_, unit) dom_prog"
+ where
+ "assert_equals l r = (if l = r then return () else error AssertException)"
+definition assert_equals_with_message :: "'a \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> (_, unit) dom_prog"
+ where
+ "assert_equals_with_message l r _ = (if l = r then return () else error AssertException)"
+notation assert_equals ("assert'_equals'(_, _')")
+notation assert_equals_with_message ("assert'_equals'(_, _, _')")
+notation assert_equals ("assert'_array'_equals'(_, _')")
+notation assert_equals_with_message ("assert'_array'_equals'(_, _, _')")
+
+definition assert_not_equals :: "'a \<Rightarrow> 'a \<Rightarrow> (_, unit) dom_prog"
+ where
+ "assert_not_equals l r = (if l \<noteq> r then return () else error AssertException)"
+definition assert_not_equals_with_message :: "'a \<Rightarrow> 'a \<Rightarrow> 'b \<Rightarrow> (_, unit) dom_prog"
+ where
+ "assert_not_equals_with_message l r _ = (if l \<noteq> r then return () else error AssertException)"
+notation assert_not_equals ("assert'_not'_equals'(_, _')")
+notation assert_not_equals_with_message ("assert'_not'_equals'(_, _, _')")
+notation assert_not_equals ("assert'_array'_not'_equals'(_, _')")
+notation assert_not_equals_with_message ("assert'_array'_not'_equals'(_, _, _')")
+
+(* TODO: why don't the code equations of noop work here? *)
+definition removeWhiteSpaceOnlyTextNodes :: "((_) object_ptr option) \<Rightarrow> (_, unit) dom_prog"
+ where
+ "removeWhiteSpaceOnlyTextNodes _ = return ()"
+
+partial_function (dom_prog) assert_equal_subtrees :: "(_::linorder) object_ptr option \<Rightarrow>
+(_::linorder) object_ptr option \<Rightarrow> (_, unit) dom_prog"
+ where
+ [code]: "assert_equal_subtrees ptr ptr' = (case cast (the ptr) of
+ None \<Rightarrow> (case cast (the ptr) of
+ None \<Rightarrow> (case cast (the ptr) of
+ None \<Rightarrow> (case cast (the ptr) of
+ None \<Rightarrow> error AssertException |
+ Some shadow_root_ptr \<Rightarrow> (case cast (the ptr') of
+ None \<Rightarrow> error AssertException |
+ Some shadow_root_ptr' \<Rightarrow> do {
+ mode_val \<leftarrow> get_M shadow_root_ptr mode;
+ mode_val' \<leftarrow> get_M shadow_root_ptr' mode;
+ (if mode_val = mode_val' then return () else error AssertException);
+ child_nodes_val \<leftarrow> get_M shadow_root_ptr RShadowRoot.child_nodes;
+ child_nodes_val' \<leftarrow> get_M shadow_root_ptr' RShadowRoot.child_nodes;
+ (if length child_nodes_val = length child_nodes_val'
+ then return () else error AssertException);
+ map_M (\<lambda>(ptr, ptr'). assert_equal_subtrees (Some (cast ptr)) (Some (cast ptr')))
+ (zip child_nodes_val child_nodes_val');
+ document_ptr \<leftarrow> return (cast shadow_root_ptr);
+ document_ptr' \<leftarrow> return (cast shadow_root_ptr');
+ document_element_val \<leftarrow> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr document_element;
+ document_element_val' \<leftarrow> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr' document_element;
+ (if (document_element_val = None) \<and> (document_element_val' = None)
+ then return () else assert_equal_subtrees (Some (cast (the document_element_val)))
+ (Some (cast (the document_element_val'))));
+ disconnected_nodes_val \<leftarrow> get_M document_ptr disconnected_nodes;
+ disconnected_nodes_val' \<leftarrow> get_M document_ptr' disconnected_nodes;
+ (if length disconnected_nodes_val = length disconnected_nodes_val'
+ then return () else error AssertException);
+ map_M (\<lambda>(ptr, ptr'). assert_equal_subtrees (Some (cast ptr)) (Some (cast ptr')))
+ (zip disconnected_nodes_val disconnected_nodes_val');
+ doctype_val \<leftarrow> get_M document_ptr doctype;
+ doctype_val' \<leftarrow> get_M document_ptr' doctype;
+ (if doctype_val = doctype_val' then return () else error AssertException);
+ return ()
+ })) |
+ Some document_ptr \<Rightarrow> (case cast (the ptr') of
+ None \<Rightarrow> error AssertException |
+ Some document_ptr' \<Rightarrow> do {
+ document_element_val \<leftarrow> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr document_element;
+ document_element_val' \<leftarrow> get_M\<^sub>D\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t document_ptr' document_element;
+ (if (document_element_val = None) \<and> (document_element_val' = None)
+ then return () else assert_equal_subtrees (Some (cast (the document_element_val)))
+ (Some (cast (the document_element_val'))));
+ disconnected_nodes_val \<leftarrow> get_M document_ptr disconnected_nodes;
+ disconnected_nodes_val' \<leftarrow> get_M document_ptr' disconnected_nodes;
+ (if length disconnected_nodes_val = length disconnected_nodes_val'
+ then return () else error AssertException);
+ map_M (\<lambda>(ptr, ptr'). assert_equal_subtrees (Some (cast ptr)) (Some (cast ptr')))
+ (zip disconnected_nodes_val disconnected_nodes_val');
+ doctype_val \<leftarrow> get_M document_ptr doctype;
+ doctype_val' \<leftarrow> get_M document_ptr' doctype;
+ (if doctype_val = doctype_val' then return () else error AssertException);
+ return ()
+ })) |
+ Some character_data_ptr \<Rightarrow> (case cast (the ptr') of
+ None \<Rightarrow> error AssertException |
+ Some character_data_ptr' \<Rightarrow> do {
+ val_val \<leftarrow> get_M character_data_ptr val;
+ val_val' \<leftarrow> get_M character_data_ptr' val;
+ (if val_val = val_val' then return () else error AssertException)
+ })) |
+ Some element_ptr \<Rightarrow> (case cast (the ptr') of
+ None \<Rightarrow> error AssertException |
+ Some element_ptr' \<Rightarrow> do {
+ tag_name_val \<leftarrow> get_M element_ptr tag_name;
+ tag_name_val' \<leftarrow> get_M element_ptr' tag_name;
+ (if tag_name_val = tag_name_val' then return () else error AssertException);
+ child_nodes_val \<leftarrow> get_M element_ptr RElement.child_nodes;
+ child_nodes_val' \<leftarrow> get_M element_ptr' RElement.child_nodes;
+ (if length child_nodes_val = length child_nodes_val' then return () else error AssertException);
+ map_M (\<lambda>(ptr, ptr'). assert_equal_subtrees (Some (cast ptr)) (Some (cast ptr')))
+ (zip child_nodes_val child_nodes_val');
+ attrs_val \<leftarrow> get_M element_ptr attrs;
+ attrs_val' \<leftarrow> get_M element_ptr' attrs;
+ (if attrs_val = attrs_val' then return () else error AssertException);
+ shadow_root_opt_val \<leftarrow> get_M element_ptr shadow_root_opt;
+ shadow_root_opt_val' \<leftarrow> get_M element_ptr' shadow_root_opt;
+ (if (shadow_root_opt_val = None) \<and> (shadow_root_opt_val' = None)
+ then return () else assert_equal_subtrees (Some (cast (the shadow_root_opt_val)))
+ (Some (cast (the shadow_root_opt_val'))));
+ return ()
+ }))"
+notation assert_equal_subtrees ("assert'_equal'_subtrees'(_, _')")
+
+
+subsection \<open>Making the functions under test compatible with untyped languages such as JavaScript\<close>
+
+fun set_attribute_with_null :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> attr_value \<Rightarrow> (_, unit) dom_prog"
+ where
+ "set_attribute_with_null (Some ptr) k v = (case cast ptr of
+ Some element_ptr \<Rightarrow> set_attribute element_ptr k (Some v))"
+fun set_attribute_with_null2 :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> attr_value option \<Rightarrow> (_, unit) dom_prog"
+ where
+ "set_attribute_with_null2 (Some ptr) k v = (case cast ptr of
+ Some element_ptr \<Rightarrow> set_attribute element_ptr k v)"
+notation set_attribute_with_null ("_ . setAttribute'(_, _')")
+notation set_attribute_with_null2 ("_ . setAttribute'(_, _')")
+
+fun get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_with_null :: "((_) object_ptr option) \<Rightarrow> (_, (_) object_ptr option list) dom_prog"
+ where
+ "get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_with_null (Some ptr) = do {
+ children \<leftarrow> get_child_nodes ptr;
+ return (map (Some \<circ> cast) children)
+ }"
+notation get_child_nodes\<^sub>C\<^sub>o\<^sub>r\<^sub>e\<^sub>_\<^sub>D\<^sub>O\<^sub>M_with_null ("_ . childNodes")
+
+fun create_element_with_null :: "((_) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "create_element_with_null (Some owner_document_obj) tag = (case cast owner_document_obj of
+ Some owner_document \<Rightarrow> do {
+ element_ptr \<leftarrow> create_element owner_document tag;
+ return (Some (cast element_ptr))})"
+notation create_element_with_null ("_ . createElement'(_')")
+
+fun create_character_data_with_null :: "((_) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "create_character_data_with_null (Some owner_document_obj) tag = (case cast owner_document_obj of
+ Some owner_document \<Rightarrow> do {
+ character_data_ptr \<leftarrow> create_character_data owner_document tag;
+ return (Some (cast character_data_ptr))})"
+notation create_character_data_with_null ("_ . createTextNode'(_')")
+
+definition create_document_with_null :: "string \<Rightarrow> (_, ((_::linorder) object_ptr option)) dom_prog"
+ where
+ "create_document_with_null title = do {
+ new_document_ptr \<leftarrow> create_document;
+ html \<leftarrow> create_element new_document_ptr ''html'';
+ append_child (cast new_document_ptr) (cast html);
+ heap \<leftarrow> create_element new_document_ptr ''heap'';
+ append_child (cast html) (cast heap);
+ body \<leftarrow> create_element new_document_ptr ''body'';
+ append_child (cast html) (cast body);
+ return (Some (cast new_document_ptr))
+ }"
+abbreviation "create_document_with_null2 _ _ _ \<equiv> create_document_with_null ''''"
+notation create_document_with_null ("createDocument'(_')")
+notation create_document_with_null2 ("createDocument'(_, _, _')")
+
+fun get_element_by_id_with_null ::
+ "((_::linorder) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "get_element_by_id_with_null (Some ptr) id' = do {
+ element_ptr_opt \<leftarrow> get_element_by_id ptr id';
+ (case element_ptr_opt of
+ Some element_ptr \<Rightarrow> return (Some (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr))
+ | None \<Rightarrow> return None)}"
+ | "get_element_by_id_with_null _ _ = error SegmentationFault"
+notation get_element_by_id_with_null ("_ . getElementById'(_')")
+
+fun get_elements_by_class_name_with_null ::
+ "((_::linorder) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option) list) dom_prog"
+ where
+ "get_elements_by_class_name_with_null (Some ptr) class_name =
+ get_elements_by_class_name ptr class_name \<bind> map_M (return \<circ> Some \<circ> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r)"
+notation get_elements_by_class_name_with_null ("_ . getElementsByClassName'(_')")
+
+fun get_elements_by_tag_name_with_null ::
+ "((_::linorder) object_ptr option) \<Rightarrow> string \<Rightarrow> (_, ((_) object_ptr option) list) dom_prog"
+ where
+ "get_elements_by_tag_name_with_null (Some ptr) tag =
+ get_elements_by_tag_name ptr tag \<bind> map_M (return \<circ> Some \<circ> cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r)"
+notation get_elements_by_tag_name_with_null ("_ . getElementsByTagName'(_')")
+
+fun insert_before_with_null ::
+ "((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow>
+(_, ((_) object_ptr option)) dom_prog"
+ where
+ "insert_before_with_null (Some ptr) (Some child_obj) ref_child_obj_opt = (case cast child_obj of
+ Some child \<Rightarrow> do {
+ (case ref_child_obj_opt of
+ Some ref_child_obj \<Rightarrow> insert_before ptr child (cast ref_child_obj)
+ | None \<Rightarrow> insert_before ptr child None);
+ return (Some child_obj)}
+ | None \<Rightarrow> error HierarchyRequestError)"
+notation insert_before_with_null ("_ . insertBefore'(_, _')")
+
+fun append_child_with_null ::
+ "((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow> (_, unit) dom_prog"
+ where
+ "append_child_with_null (Some ptr) (Some child_obj) = (case cast child_obj of
+ Some child \<Rightarrow> append_child ptr child
+ | None \<Rightarrow> error SegmentationFault)"
+notation append_child_with_null ("_ . appendChild'(_')")
+code_thms append_child_with_null
+fun get_body :: "((_::linorder) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "get_body ptr = do {
+ ptrs \<leftarrow> ptr . getElementsByTagName(''body'');
+ return (hd ptrs)
+ }"
+notation get_body ("_ . body")
+
+fun get_document_element_with_null ::
+ "((_::linorder) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "get_document_element_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some document_ptr \<Rightarrow> do {
+ element_ptr_opt \<leftarrow> get_M document_ptr document_element;
+ return (case element_ptr_opt of
+ Some element_ptr \<Rightarrow> Some (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr)
+ | None \<Rightarrow> None)})"
+notation get_document_element_with_null ("_ . documentElement")
+
+fun get_owner_document_with_null :: "((_::linorder) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "get_owner_document_with_null (Some ptr) = (do {
+ document_ptr \<leftarrow> get_owner_document ptr;
+ return (Some (cast\<^sub>d\<^sub>o\<^sub>c\<^sub>u\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r document_ptr))})"
+notation get_owner_document_with_null ("_ . ownerDocument")
+
+fun remove_with_null :: "((_::linorder) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "remove_with_null (Some child) = (case cast child of
+ Some child_node \<Rightarrow> do {
+ remove child_node;
+ return (Some child)}
+ | None \<Rightarrow> error NotFoundError)"
+ | "remove_with_null None = error TypeError"
+notation remove_with_null ("_ . remove'(')")
+
+fun remove_child_with_null ::
+ "((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "remove_child_with_null (Some ptr) (Some child) = (case cast child of
+ Some child_node \<Rightarrow> do {
+ remove_child ptr child_node;
+ return (Some child)}
+ | None \<Rightarrow> error NotFoundError)"
+ | "remove_child_with_null None _ = error TypeError"
+ | "remove_child_with_null _ None = error TypeError"
+notation remove_child_with_null ("_ . removeChild")
+
+fun get_tag_name_with_null :: "((_) object_ptr option) \<Rightarrow> (_, attr_value) dom_prog"
+ where
+ "get_tag_name_with_null (Some ptr) = (case cast ptr of
+ Some element_ptr \<Rightarrow> get_M element_ptr tag_name)"
+notation get_tag_name_with_null ("_ . tagName")
+
+abbreviation "remove_attribute_with_null ptr k \<equiv> set_attribute_with_null2 ptr k None"
+notation remove_attribute_with_null ("_ . removeAttribute'(_')")
+
+fun get_attribute_with_null :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> (_, attr_value option) dom_prog"
+ where
+ "get_attribute_with_null (Some ptr) k = (case cast ptr of
+ Some element_ptr \<Rightarrow> get_attribute element_ptr k)"
+fun get_attribute_with_null2 :: "((_) object_ptr option) \<Rightarrow> attr_key \<Rightarrow> (_, attr_value) dom_prog"
+ where
+ "get_attribute_with_null2 (Some ptr) k = (case cast ptr of
+ Some element_ptr \<Rightarrow> do {
+ a \<leftarrow> get_attribute element_ptr k;
+ return (the a)})"
+notation get_attribute_with_null ("_ . getAttribute'(_')")
+notation get_attribute_with_null2 ("_ . getAttribute'(_')")
+
+fun get_parent_with_null :: "((_::linorder) object_ptr option) \<Rightarrow> (_, (_) object_ptr option) dom_prog"
+ where
+ "get_parent_with_null (Some ptr) = (case cast ptr of
+ Some node_ptr \<Rightarrow> get_parent node_ptr)"
+notation get_parent_with_null ("_ . parentNode")
+
+fun first_child_with_null :: "((_) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "first_child_with_null (Some ptr) = do {
+ child_opt \<leftarrow> first_child ptr;
+ return (case child_opt of
+ Some child \<Rightarrow> Some (cast child)
+ | None \<Rightarrow> None)}"
+notation first_child_with_null ("_ . firstChild")
+
+fun adopt_node_with_null ::
+ "((_::linorder) object_ptr option) \<Rightarrow> ((_) object_ptr option) \<Rightarrow> (_, ((_) object_ptr option)) dom_prog"
+ where
+ "adopt_node_with_null (Some ptr) (Some child) = (case cast ptr of
+ Some document_ptr \<Rightarrow> (case cast child of
+ Some child_node \<Rightarrow> do {
+ adopt_node document_ptr child_node;
+ return (Some child)}))"
+notation adopt_node_with_null ("_ . adoptNode'(_')")
+
+
+fun get_shadow_root_with_null :: "((_) object_ptr option) \<Rightarrow> (_, (_) object_ptr option) dom_prog"
+ where
+ "get_shadow_root_with_null (Some ptr) = (case cast ptr of
+ Some element_ptr \<Rightarrow> do {
+ shadow_root \<leftarrow> get_shadow_root element_ptr;
+ (case shadow_root of Some sr \<Rightarrow> return (Some (cast sr))
+ | None \<Rightarrow> return None)})"
+notation get_shadow_root_with_null ("_ . shadowRoot")
+
+
+subsection \<open>Making the functions under test compatible with untyped languages such as JavaScript\<close>
+fun get_element_by_id_si_with_null ::
+ "(_::linorder) object_ptr option \<Rightarrow> string \<Rightarrow> (_, (_) object_ptr option) dom_prog"
+ where
+ "get_element_by_id_si_with_null (Some ptr) id' = do {
+ element_ptr_opt \<leftarrow> get_element_by_id_si ptr id';
+ (case element_ptr_opt of
+ Some element_ptr \<Rightarrow> return (Some (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr))
+ | None \<Rightarrow> return None)}"
+ | "get_element_by_id_si_with_null _ _ = error SegmentationFault"
+
+fun find_slot_closed_with_null ::
+ "(_::linorder) object_ptr option \<Rightarrow> (_, (_) object_ptr option) dom_prog"
+ where
+ "find_slot_closed_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some node_ptr \<Rightarrow> do {
+ element_ptr_opt \<leftarrow> find_slot True node_ptr;
+ (case element_ptr_opt of
+ Some element_ptr \<Rightarrow> return (Some (cast\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r element_ptr))
+ | None \<Rightarrow> return None)}
+ | None \<Rightarrow> error SegmentationFault)"
+ | "find_slot_closed_with_null None = error SegmentationFault"
+notation find_slot_closed_with_null ("_ . assignedSlot")
+
+fun assigned_nodes_with_null ::
+ "(_::linorder) object_ptr option \<Rightarrow> (_, (_) object_ptr option list) dom_prog"
+ where
+ "assigned_nodes_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some element_ptr \<Rightarrow> do {
+ l \<leftarrow> assigned_nodes element_ptr;
+ return (map Some (map cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r l))}
+ | None \<Rightarrow> error SegmentationFault)"
+ | "assigned_nodes_with_null None = error SegmentationFault"
+notation assigned_nodes_with_null ("_ . assignedNodes'(')")
+
+fun assigned_nodes_flatten_with_null ::
+ "(_::linorder) object_ptr option \<Rightarrow> (_, (_) object_ptr option list) dom_prog"
+ where
+ "assigned_nodes_flatten_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some element_ptr \<Rightarrow> do {
+ l \<leftarrow> assigned_nodes_flatten element_ptr;
+ return (map Some (map cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r l))}
+ | None \<Rightarrow> error SegmentationFault)"
+ | "assigned_nodes_flatten_with_null None = error SegmentationFault"
+notation assigned_nodes_flatten_with_null ("_ . assignedNodes'(True')")
+
+fun get_assigned_elements_with_null ::
+ "(_::linorder) object_ptr option \<Rightarrow> (_, (_) object_ptr option list) dom_prog"
+ where
+ "get_assigned_elements_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some element_ptr \<Rightarrow> do {
+ l \<leftarrow> assigned_nodes element_ptr;
+ l \<leftarrow> map_filter_M (return \<circ> cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r) l;
+ return (map Some (map cast l))}
+ | None \<Rightarrow> error SegmentationFault)"
+ | "get_assigned_elements_with_null None = error SegmentationFault"
+notation get_assigned_elements_with_null ("_ . assignedElements'(')")
+
+fun get_assigned_elements_flatten_with_null ::
+ "(_::linorder) object_ptr option \<Rightarrow> (_, (_) object_ptr option list) dom_prog"
+ where
+ "get_assigned_elements_flatten_with_null (Some ptr) = (case cast\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>e\<^sub>l\<^sub>e\<^sub>m\<^sub>e\<^sub>n\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r ptr of
+ Some element_ptr \<Rightarrow> do {
+ l \<leftarrow> assigned_nodes_flatten element_ptr;
+ return (map Some (map cast\<^sub>n\<^sub>o\<^sub>d\<^sub>e\<^sub>_\<^sub>p\<^sub>t\<^sub>r\<^sub>2\<^sub>o\<^sub>b\<^sub>j\<^sub>e\<^sub>c\<^sub>t\<^sub>_\<^sub>p\<^sub>t\<^sub>r l))}
+ | None \<Rightarrow> error SegmentationFault)"
+ | "get_assigned_elements_flatten_with_null None = error SegmentationFault"
+notation get_assigned_elements_flatten_with_null ("_ . assignedElements'(True')")
+
+fun createTestTree ::
+ "(_::linorder) object_ptr option \<Rightarrow> (_, string \<Rightarrow> (_, (_) object_ptr option) dom_prog) dom_prog"
+ where
+ "createTestTree (Some ref) = do {
+ tups \<leftarrow> to_tree_order_si ref \<bind> map_filter_M (\<lambda>ptr. do {
+ (case cast ptr of
+ Some element_ptr \<Rightarrow> do {
+ iden_opt \<leftarrow> get_attribute element_ptr ''id'';
+ (case iden_opt of
+ Some iden \<Rightarrow> return (Some (iden, ptr))
+ | None \<Rightarrow> return None)
+ }
+ | None \<Rightarrow> return None)});
+ return (return \<circ> map_of tups)
+ }"
+ | "createTestTree None = error SegmentationFault"
+
+
+end
diff --git a/thys/Shadow_SC_DOM/tests/Shadow_DOM_Document_adoptNode.thy b/thys/Shadow_SC_DOM/tests/Shadow_DOM_Document_adoptNode.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/Shadow_DOM_Document_adoptNode.thy
@@ -0,0 +1,114 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+(* This file is automatically generated, please do not modify! *)
+
+section\<open>Testing Document\_adoptNode\<close>
+text\<open>This theory contains the test cases for Document\_adoptNode.\<close>
+
+theory Shadow_DOM_Document_adoptNode
+imports
+ "Shadow_DOM_BaseTest"
+begin
+
+definition Document_adoptNode_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
+ "Document_adoptNode_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
+ (cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 8)] fmempty None)),
+ (cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6), cast (element_ptr.Ref 7)] fmempty None)),
+ (cast (element_ptr.Ref 3), cast (create_element_obj ''meta'' [] (fmap_of_list [(''charset'', ''utf-8'')]) None)),
+ (cast (element_ptr.Ref 4), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
+ (cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Document.adoptNode'')),
+ (cast (element_ptr.Ref 5), cast (create_element_obj ''link'' [] (fmap_of_list [(''rel'', ''help''), (''href'', ''https://dom.spec.whatwg.org/#dom-document-adoptnode'')]) None)),
+ (cast (element_ptr.Ref 6), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
+ (cast (element_ptr.Ref 7), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
+ (cast (element_ptr.Ref 8), cast (create_element_obj ''body'' [cast (element_ptr.Ref 9), cast (element_ptr.Ref 10), cast (element_ptr.Ref 11)] fmempty None)),
+ (cast (element_ptr.Ref 9), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
+ (cast (element_ptr.Ref 10), cast (create_element_obj ''x<'' [cast (character_data_ptr.Ref 2)] fmempty None)),
+ (cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''x'')),
+ (cast (element_ptr.Ref 11), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 3)] fmempty None)),
+ (cast (character_data_ptr.Ref 3), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
+
+definition Document_adoptNode_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Document_adoptNode_document = Some (cast (document_ptr.Ref 1))"
+
+
+text \<open>"Adopting an Element called 'x<' should work."\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> Document_adoptNode_document . getElementsByTagName(''x<'');
+ y \<leftarrow> return (tmp0 ! 0);
+ child \<leftarrow> y . firstChild;
+ tmp1 \<leftarrow> y . parentNode;
+ tmp2 \<leftarrow> Document_adoptNode_document . body;
+ assert_equals(tmp1, tmp2);
+ tmp3 \<leftarrow> y . ownerDocument;
+ assert_equals(tmp3, Document_adoptNode_document);
+ tmp4 \<leftarrow> Document_adoptNode_document . adoptNode(y);
+ assert_equals(tmp4, y);
+ tmp5 \<leftarrow> y . parentNode;
+ assert_equals(tmp5, None);
+ tmp6 \<leftarrow> y . firstChild;
+ assert_equals(tmp6, child);
+ tmp7 \<leftarrow> y . ownerDocument;
+ assert_equals(tmp7, Document_adoptNode_document);
+ tmp8 \<leftarrow> child . ownerDocument;
+ assert_equals(tmp8, Document_adoptNode_document);
+ doc \<leftarrow> createDocument(None, None, None);
+ tmp9 \<leftarrow> doc . adoptNode(y);
+ assert_equals(tmp9, y);
+ tmp10 \<leftarrow> y . parentNode;
+ assert_equals(tmp10, None);
+ tmp11 \<leftarrow> y . firstChild;
+ assert_equals(tmp11, child);
+ tmp12 \<leftarrow> y . ownerDocument;
+ assert_equals(tmp12, doc);
+ tmp13 \<leftarrow> child . ownerDocument;
+ assert_equals(tmp13, doc)
+}) Document_adoptNode_heap"
+ by eval
+
+
+text \<open>"Adopting an Element called ':good:times:' should work."\<close>
+
+lemma "test (do {
+ x \<leftarrow> Document_adoptNode_document . createElement('':good:times:'');
+ tmp0 \<leftarrow> Document_adoptNode_document . adoptNode(x);
+ assert_equals(tmp0, x);
+ doc \<leftarrow> createDocument(None, None, None);
+ tmp1 \<leftarrow> doc . adoptNode(x);
+ assert_equals(tmp1, x);
+ tmp2 \<leftarrow> x . parentNode;
+ assert_equals(tmp2, None);
+ tmp3 \<leftarrow> x . ownerDocument;
+ assert_equals(tmp3, doc)
+}) Document_adoptNode_heap"
+ by eval
+
+
+end
diff --git a/thys/Shadow_SC_DOM/tests/Shadow_DOM_Document_getElementById.thy b/thys/Shadow_SC_DOM/tests/Shadow_DOM_Document_getElementById.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/Shadow_DOM_Document_getElementById.thy
@@ -0,0 +1,278 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+(* This file is automatically generated, please do not modify! *)
+
+section\<open>Testing Document\_getElementById\<close>
+text\<open>This theory contains the test cases for Document\_getElementById.\<close>
+
+theory Shadow_DOM_Document_getElementById
+imports
+ "Shadow_DOM_BaseTest"
+begin
+
+definition Document_getElementById_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
+ "Document_getElementById_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
+ (cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 9)] fmempty None)),
+ (cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6), cast (element_ptr.Ref 7), cast (element_ptr.Ref 8)] fmempty None)),
+ (cast (element_ptr.Ref 3), cast (create_element_obj ''meta'' [] (fmap_of_list [(''charset'', ''utf-8'')]) None)),
+ (cast (element_ptr.Ref 4), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
+ (cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Document.getElementById'')),
+ (cast (element_ptr.Ref 5), cast (create_element_obj ''link'' [] (fmap_of_list [(''rel'', ''author''), (''title'', ''Tetsuharu OHZEKI''), (''href'', ''mailto:saneyuki.snyk@gmail.com'')]) None)),
+ (cast (element_ptr.Ref 6), cast (create_element_obj ''link'' [] (fmap_of_list [(''rel'', ''help''), (''href'', ''https://dom.spec.whatwg.org/#dom-document-getelementbyid'')]) None)),
+ (cast (element_ptr.Ref 7), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
+ (cast (element_ptr.Ref 8), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
+ (cast (element_ptr.Ref 9), cast (create_element_obj ''body'' [cast (element_ptr.Ref 10), cast (element_ptr.Ref 11), cast (element_ptr.Ref 12), cast (element_ptr.Ref 13), cast (element_ptr.Ref 16), cast (element_ptr.Ref 19)] fmempty None)),
+ (cast (element_ptr.Ref 10), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
+ (cast (element_ptr.Ref 11), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', '''')]) None)),
+ (cast (element_ptr.Ref 12), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''test1'')]) None)),
+ (cast (element_ptr.Ref 13), cast (create_element_obj ''div'' [cast (element_ptr.Ref 14), cast (element_ptr.Ref 15)] (fmap_of_list [(''id'', ''test5''), (''data-name'', ''1st'')]) None)),
+ (cast (element_ptr.Ref 14), cast (create_element_obj ''p'' [cast (character_data_ptr.Ref 2)] (fmap_of_list [(''id'', ''test5''), (''data-name'', ''2nd'')]) None)),
+ (cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''P'')),
+ (cast (element_ptr.Ref 15), cast (create_element_obj ''input'' [] (fmap_of_list [(''id'', ''test5''), (''type'', ''submit''), (''value'', ''Submit''), (''data-name'', ''3rd'')]) None)),
+ (cast (element_ptr.Ref 16), cast (create_element_obj ''div'' [cast (element_ptr.Ref 17)] (fmap_of_list [(''id'', ''outer'')]) None)),
+ (cast (element_ptr.Ref 17), cast (create_element_obj ''div'' [cast (element_ptr.Ref 18)] (fmap_of_list [(''id'', ''middle'')]) None)),
+ (cast (element_ptr.Ref 18), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''inner'')]) None)),
+ (cast (element_ptr.Ref 19), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 3)] fmempty None)),
+ (cast (character_data_ptr.Ref 3), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
+
+definition Document_getElementById_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Document_getElementById_document = Some (cast (document_ptr.Ref 1))"
+
+
+text \<open>"Document.getElementById with a script-inserted element"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test2'';
+ test \<leftarrow> Document_getElementById_document . createElement(''div'');
+ test . setAttribute(''id'', TEST_ID);
+ gBody . appendChild(test);
+ result \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_not_equals(result, None, ''should not be null.'');
+ tmp0 \<leftarrow> result . tagName;
+ assert_equals(tmp0, ''div'', ''should have appended element's tag name'');
+ gBody . removeChild(test);
+ removed \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(removed, None, ''should not get removed element.'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"update `id` attribute via setAttribute/removeAttribute"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test3'';
+ test \<leftarrow> Document_getElementById_document . createElement(''div'');
+ test . setAttribute(''id'', TEST_ID);
+ gBody . appendChild(test);
+ UPDATED_ID \<leftarrow> return ''test3-updated'';
+ test . setAttribute(''id'', UPDATED_ID);
+ e \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
+ assert_equals(e, test, ''should get the element with id.'');
+ old \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(old, None, ''shouldn't get the element by the old id.'');
+ test . removeAttribute(''id'');
+ e2 \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
+ assert_equals(e2, None, ''should return null when the passed id is none in document.'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"Ensure that the id attribute only affects elements present in a document"\<close>
+
+lemma "test (do {
+ TEST_ID \<leftarrow> return ''test4-should-not-exist'';
+ e \<leftarrow> Document_getElementById_document . createElement(''div'');
+ e . setAttribute(''id'', TEST_ID);
+ tmp0 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(tmp0, None, ''should be null'');
+ tmp1 \<leftarrow> Document_getElementById_document . body;
+ tmp1 . appendChild(e);
+ tmp2 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(tmp2, e, ''should be the appended element'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"in tree order, within the context object's tree"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test5'';
+ target \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_not_equals(target, None, ''should not be null'');
+ tmp0 \<leftarrow> target . getAttribute(''data-name'');
+ assert_equals(tmp0, ''1st'', ''should return the 1st'');
+ element4 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element4 . setAttribute(''id'', TEST_ID);
+ element4 . setAttribute(''data-name'', ''4th'');
+ gBody . appendChild(element4);
+ target2 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_not_equals(target2, None, ''should not be null'');
+ tmp1 \<leftarrow> target2 . getAttribute(''data-name'');
+ assert_equals(tmp1, ''1st'', ''should be the 1st'');
+ tmp2 \<leftarrow> target2 . parentNode;
+ tmp2 . removeChild(target2);
+ target3 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_not_equals(target3, None, ''should not be null'');
+ tmp3 \<leftarrow> target3 . getAttribute(''data-name'');
+ assert_equals(tmp3, ''4th'', ''should be the 4th'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"Modern browsers optimize this method with using internal id cache. This test checks that their optimization should effect only append to `Document`, not append to `Node`."\<close>
+
+lemma "test (do {
+ TEST_ID \<leftarrow> return ''test6'';
+ s \<leftarrow> Document_getElementById_document . createElement(''div'');
+ s . setAttribute(''id'', TEST_ID);
+ tmp0 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ tmp0 . appendChild(s);
+ tmp1 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(tmp1, None, ''should be null'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"changing attribute's value via `Attr` gotten from `Element.attribute`."\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test7'';
+ element \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element . setAttribute(''id'', TEST_ID);
+ gBody . appendChild(element);
+ target \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(target, element, ''should return the element before changing the value'');
+ element . setAttribute(''id'', (TEST_ID @ ''-updated''));
+ target2 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(target2, None, ''should return null after updated id via Attr.value'');
+ target3 \<leftarrow> Document_getElementById_document . getElementById((TEST_ID @ ''-updated''));
+ assert_equals(target3, element, ''should be equal to the updated element.'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"update `id` attribute via element.id"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test12'';
+ test \<leftarrow> Document_getElementById_document . createElement(''div'');
+ test . setAttribute(''id'', TEST_ID);
+ gBody . appendChild(test);
+ UPDATED_ID \<leftarrow> return (TEST_ID @ ''-updated'');
+ test . setAttribute(''id'', UPDATED_ID);
+ e \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
+ assert_equals(e, test, ''should get the element with id.'');
+ old \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(old, None, ''shouldn't get the element by the old id.'');
+ test . setAttribute(''id'', '''');
+ e2 \<leftarrow> Document_getElementById_document . getElementById(UPDATED_ID);
+ assert_equals(e2, None, ''should return null when the passed id is none in document.'')
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"where insertion order and tree order don't match"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test13'';
+ container \<leftarrow> Document_getElementById_document . createElement(''div'');
+ container . setAttribute(''id'', (TEST_ID @ ''-fixture''));
+ gBody . appendChild(container);
+ element1 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element1 . setAttribute(''id'', TEST_ID);
+ element2 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element2 . setAttribute(''id'', TEST_ID);
+ element3 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element3 . setAttribute(''id'', TEST_ID);
+ element4 \<leftarrow> Document_getElementById_document . createElement(''div'');
+ element4 . setAttribute(''id'', TEST_ID);
+ container . appendChild(element2);
+ container . appendChild(element4);
+ container . insertBefore(element3, element4);
+ container . insertBefore(element1, element2);
+ test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(test, element1, ''should return 1st element'');
+ container . removeChild(element1);
+ test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(test, element2, ''should return 2nd element'');
+ container . removeChild(element2);
+ test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(test, element3, ''should return 3rd element'');
+ container . removeChild(element3);
+ test \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(test, element4, ''should return 4th element'');
+ container . removeChild(element4)
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"Inserting an id by inserting its parent node"\<close>
+
+lemma "test (do {
+ gBody \<leftarrow> Document_getElementById_document . body;
+ TEST_ID \<leftarrow> return ''test14'';
+ a \<leftarrow> Document_getElementById_document . createElement(''a'');
+ b \<leftarrow> Document_getElementById_document . createElement(''b'');
+ a . appendChild(b);
+ b . setAttribute(''id'', TEST_ID);
+ tmp0 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(tmp0, None);
+ gBody . appendChild(a);
+ tmp1 \<leftarrow> Document_getElementById_document . getElementById(TEST_ID);
+ assert_equals(tmp1, b)
+}) Document_getElementById_heap"
+ by eval
+
+
+text \<open>"Document.getElementById must not return nodes not present in document"\<close>
+
+lemma "test (do {
+ TEST_ID \<leftarrow> return ''test15'';
+ outer \<leftarrow> Document_getElementById_document . getElementById(''outer'');
+ middle \<leftarrow> Document_getElementById_document . getElementById(''middle'');
+ inner \<leftarrow> Document_getElementById_document . getElementById(''inner'');
+ tmp0 \<leftarrow> Document_getElementById_document . getElementById(''middle'');
+ outer . removeChild(tmp0);
+ new_el \<leftarrow> Document_getElementById_document . createElement(''h1'');
+ new_el . setAttribute(''id'', ''heading'');
+ inner . appendChild(new_el);
+ tmp1 \<leftarrow> Document_getElementById_document . getElementById(''heading'');
+ assert_equals(tmp1, None)
+}) Document_getElementById_heap"
+ by eval
+
+
+end
diff --git a/thys/Shadow_SC_DOM/tests/Shadow_DOM_Node_insertBefore.thy b/thys/Shadow_SC_DOM/tests/Shadow_DOM_Node_insertBefore.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/Shadow_DOM_Node_insertBefore.thy
@@ -0,0 +1,129 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+(* This file is automatically generated, please do not modify! *)
+
+section\<open>Testing Node\_insertBefore\<close>
+text\<open>This theory contains the test cases for Node\_insertBefore.\<close>
+
+theory Shadow_DOM_Node_insertBefore
+imports
+ "Shadow_DOM_BaseTest"
+begin
+
+definition Node_insertBefore_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
+ "Node_insertBefore_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
+ (cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 6)] fmempty None)),
+ (cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5)] fmempty None)),
+ (cast (element_ptr.Ref 3), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
+ (cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Node.insertBefore'')),
+ (cast (element_ptr.Ref 4), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
+ (cast (element_ptr.Ref 5), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
+ (cast (element_ptr.Ref 6), cast (create_element_obj ''body'' [cast (element_ptr.Ref 7), cast (element_ptr.Ref 8)] fmempty None)),
+ (cast (element_ptr.Ref 7), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
+ (cast (element_ptr.Ref 8), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 2)] fmempty None)),
+ (cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
+
+definition Node_insertBefore_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Node_insertBefore_document = Some (cast (document_ptr.Ref 1))"
+
+
+text \<open>"Calling insertBefore an a leaf node Text must throw HIERARCHY\_REQUEST\_ERR."\<close>
+
+lemma "test (do {
+ node \<leftarrow> Node_insertBefore_document . createTextNode(''Foo'');
+ tmp0 \<leftarrow> Node_insertBefore_document . createTextNode(''fail'');
+ assert_throws(HierarchyRequestError, node . insertBefore(tmp0, None))
+}) Node_insertBefore_heap"
+ by eval
+
+
+text \<open>"Calling insertBefore with an inclusive ancestor of the context object must throw HIERARCHY\_REQUEST\_ERR."\<close>
+
+lemma "test (do {
+ tmp1 \<leftarrow> Node_insertBefore_document . body;
+ tmp2 \<leftarrow> Node_insertBefore_document . getElementById(''log'');
+ tmp0 \<leftarrow> Node_insertBefore_document . body;
+ assert_throws(HierarchyRequestError, tmp0 . insertBefore(tmp1, tmp2));
+ tmp4 \<leftarrow> Node_insertBefore_document . documentElement;
+ tmp5 \<leftarrow> Node_insertBefore_document . getElementById(''log'');
+ tmp3 \<leftarrow> Node_insertBefore_document . body;
+ assert_throws(HierarchyRequestError, tmp3 . insertBefore(tmp4, tmp5))
+}) Node_insertBefore_heap"
+ by eval
+
+
+text \<open>"Calling insertBefore with a reference child whose parent is not the context node must throw a NotFoundError."\<close>
+
+lemma "test (do {
+ a \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ b \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ c \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ assert_throws(NotFoundError, a . insertBefore(b, c))
+}) Node_insertBefore_heap"
+ by eval
+
+
+text \<open>"If the context node is a document, inserting a document or text node should throw a HierarchyRequestError."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> createDocument(''title'');
+ doc2 \<leftarrow> createDocument(''title2'');
+ tmp0 \<leftarrow> doc . documentElement;
+ assert_throws(HierarchyRequestError, doc . insertBefore(doc2, tmp0));
+ tmp1 \<leftarrow> doc . createTextNode(''text'');
+ tmp2 \<leftarrow> doc . documentElement;
+ assert_throws(HierarchyRequestError, doc . insertBefore(tmp1, tmp2))
+}) Node_insertBefore_heap"
+ by eval
+
+
+text \<open>"Inserting a node before itself should not move the node"\<close>
+
+lemma "test (do {
+ a \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ b \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ c \<leftarrow> Node_insertBefore_document . createElement(''div'');
+ a . appendChild(b);
+ a . appendChild(c);
+ tmp0 \<leftarrow> a . childNodes;
+ assert_array_equals(tmp0, [b, c]);
+ tmp1 \<leftarrow> a . insertBefore(b, b);
+ assert_equals(tmp1, b);
+ tmp2 \<leftarrow> a . childNodes;
+ assert_array_equals(tmp2, [b, c]);
+ tmp3 \<leftarrow> a . insertBefore(c, c);
+ assert_equals(tmp3, c);
+ tmp4 \<leftarrow> a . childNodes;
+ assert_array_equals(tmp4, [b, c])
+}) Node_insertBefore_heap"
+ by eval
+
+
+end
diff --git a/thys/Shadow_SC_DOM/tests/Shadow_DOM_Node_removeChild.thy b/thys/Shadow_SC_DOM/tests/Shadow_DOM_Node_removeChild.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/Shadow_DOM_Node_removeChild.thy
@@ -0,0 +1,160 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+(* This file is automatically generated, please do not modify! *)
+
+section\<open>Testing Node\_removeChild\<close>
+text\<open>This theory contains the test cases for Node\_removeChild.\<close>
+
+theory Shadow_DOM_Node_removeChild
+imports
+ "Shadow_DOM_BaseTest"
+begin
+
+definition Node_removeChild_heap :: heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l where
+ "Node_removeChild_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
+ (cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 7)] fmempty None)),
+ (cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6)] fmempty None)),
+ (cast (element_ptr.Ref 3), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
+ (cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Node.removeChild'')),
+ (cast (element_ptr.Ref 4), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
+ (cast (element_ptr.Ref 5), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
+ (cast (element_ptr.Ref 6), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''creators.js'')]) None)),
+ (cast (element_ptr.Ref 7), cast (create_element_obj ''body'' [cast (element_ptr.Ref 8), cast (element_ptr.Ref 9), cast (element_ptr.Ref 10)] fmempty None)),
+ (cast (element_ptr.Ref 8), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''log'')]) None)),
+ (cast (element_ptr.Ref 9), cast (create_element_obj ''iframe'' [] (fmap_of_list [(''src'', ''about:blank'')]) None)),
+ (cast (element_ptr.Ref 10), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 2)] fmempty None)),
+ (cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
+
+definition Node_removeChild_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "Node_removeChild_document = Some (cast (document_ptr.Ref 1))"
+
+
+text \<open>"Passing a detached Element to removeChild should not affect it."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> return Node_removeChild_document;
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp0, doc);
+ tmp1 \<leftarrow> Node_removeChild_document . body;
+ assert_throws(NotFoundError, tmp1 . removeChild(s));
+ tmp2 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp2, doc)
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Passing a non-detached Element to removeChild should not affect it."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> return Node_removeChild_document;
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> doc . documentElement;
+ tmp0 . appendChild(s);
+ tmp1 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp1, doc);
+ tmp2 \<leftarrow> Node_removeChild_document . body;
+ assert_throws(NotFoundError, tmp2 . removeChild(s));
+ tmp3 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp3, doc)
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Calling removeChild on an Element with no children should throw NOT\_FOUND\_ERR."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> return Node_removeChild_document;
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> doc . body;
+ tmp0 . appendChild(s);
+ tmp1 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp1, doc);
+ assert_throws(NotFoundError, s . removeChild(doc))
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Passing a detached Element to removeChild should not affect it."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> createDocument('''');
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp0, doc);
+ tmp1 \<leftarrow> Node_removeChild_document . body;
+ assert_throws(NotFoundError, tmp1 . removeChild(s));
+ tmp2 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp2, doc)
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Passing a non-detached Element to removeChild should not affect it."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> createDocument('''');
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> doc . documentElement;
+ tmp0 . appendChild(s);
+ tmp1 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp1, doc);
+ tmp2 \<leftarrow> Node_removeChild_document . body;
+ assert_throws(NotFoundError, tmp2 . removeChild(s));
+ tmp3 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp3, doc)
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Calling removeChild on an Element with no children should throw NOT\_FOUND\_ERR."\<close>
+
+lemma "test (do {
+ doc \<leftarrow> createDocument('''');
+ s \<leftarrow> doc . createElement(''div'');
+ tmp0 \<leftarrow> doc . body;
+ tmp0 . appendChild(s);
+ tmp1 \<leftarrow> s . ownerDocument;
+ assert_equals(tmp1, doc);
+ assert_throws(NotFoundError, s . removeChild(doc))
+}) Node_removeChild_heap"
+ by eval
+
+
+text \<open>"Passing a value that is not a Node reference to removeChild should throw TypeError."\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> Node_removeChild_document . body;
+ assert_throws(TypeError, tmp0 . removeChild(None))
+}) Node_removeChild_heap"
+ by eval
+
+
+end
diff --git a/thys/Shadow_SC_DOM/tests/my_get_owner_document.html b/thys/Shadow_SC_DOM/tests/my_get_owner_document.html
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/my_get_owner_document.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ </head>
+ <body>
+ <div id="test">
+ <div id="host">
+ <template data-mode="open">
+ <slot id="s1" name="slot1"></slot>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ </div>
+ </div>
+ </body>
+ <script>
+ test(() => {
+ let n = createTestTree(test);
+
+ assert_equals(n.s1.ownerDocument, document);
+ }, 'ownerDocument inside shadow tree returns the outer document.');
+
+ test(() => {
+ let n = createTestTree(test);
+
+ assert_equals(n.c1.ownerDocument, document);
+ }, 'ownerDocument outside shadow tree returns the outer document.');
+ </script>
+</html>
diff --git a/thys/Shadow_SC_DOM/tests/my_get_owner_document.thy b/thys/Shadow_SC_DOM/tests/my_get_owner_document.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/my_get_owner_document.thy
@@ -0,0 +1,81 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+(* This file is automatically generated, please do not modify! *)
+
+section\<open>Testing my\_get\_owner\_document\<close>
+text\<open>This theory contains the test cases for my\_get\_owner\_document.\<close>
+
+theory my_get_owner_document
+imports
+ "Shadow_DOM_BaseTest"
+begin
+
+definition my_get_owner_document_heap :: "heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l" where
+ "my_get_owner_document_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
+ (cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 3)] fmempty None)),
+ (cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [] fmempty None)),
+ (cast (element_ptr.Ref 3), cast (create_element_obj ''body'' [cast (element_ptr.Ref 4), cast (element_ptr.Ref 8)] fmempty None)),
+ (cast (element_ptr.Ref 4), cast (create_element_obj ''div'' [cast (element_ptr.Ref 5)] (fmap_of_list [(''id'', ''test'')]) None)),
+ (cast (element_ptr.Ref 5), cast (create_element_obj ''div'' [cast (element_ptr.Ref 6)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 1))))),
+ (cast (element_ptr.Ref 6), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (shadow_root_ptr.Ref 1), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 7)])),
+ (cast (element_ptr.Ref 7), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 8), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 1)] fmempty None)),
+ (cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
+
+definition my_get_owner_document_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "my_get_owner_document_document = Some (cast (document_ptr.Ref 1))"
+
+
+text \<open>'ownerDocument inside shadow tree returns the outer document.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> my_get_owner_document_document . getElementById(''test'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''s1'';
+ tmp2 \<leftarrow> tmp1 . ownerDocument;
+ assert_equals(tmp2, my_get_owner_document_document)
+}) my_get_owner_document_heap"
+ by eval
+
+
+text \<open>'ownerDocument outside shadow tree returns the outer document.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> my_get_owner_document_document . getElementById(''test'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''c1'';
+ tmp2 \<leftarrow> tmp1 . ownerDocument;
+ assert_equals(tmp2, my_get_owner_document_document)
+}) my_get_owner_document_heap"
+ by eval
+
+
+end
diff --git a/thys/Shadow_SC_DOM/tests/slots-fallback.html b/thys/Shadow_SC_DOM/tests/slots-fallback.html
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/slots-fallback.html
@@ -0,0 +1,253 @@
+<!DOCTYPE html>
+<title>Shadow DOM: Slots and fallback contents</title>
+<meta name="author" title="Hayato Ito" href="mailto:hayato@google.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/shadow-dom.js"></script>
+
+<div id="test1">
+ <div id="host">
+ <template data-mode="open">
+ <slot id="s1" name="slot1">
+ <div id="f1"></div>
+ </slot>
+ </template>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test1);
+ removeWhiteSpaceOnlyTextNodes(n.test1);
+
+ assert_equals(n.f1.assignedSlot, null);
+
+ assert_array_equals(n.s1.assignedNodes(), []);
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.f1]);
+}, 'Slots fallback: Basic.');
+
+test(() => {
+ let n = createTestTree(test1);
+
+ assert_array_equals(n.s1.assignedElements(), []);
+ assert_array_equals(n.s1.assignedElements({ flatten: true }), [n.f1]);
+}, 'Slots fallback: Basic, elements only.');
+</script>
+
+<div id="test2">
+ <div id="host">
+ <template data-mode="open">
+ <slot id="s1" name="slot1">
+ <slot id="s2" name="slot2">
+ <div id="f1"></div>
+ </slot>
+ </slot>
+ </template>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test2);
+ removeWhiteSpaceOnlyTextNodes(n.test2);
+
+ assert_equals(n.f1.assignedSlot, null);
+
+ assert_array_equals(n.s1.assignedNodes(), []);
+ assert_array_equals(n.s2.assignedNodes(), []);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.f1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.f1]);
+}, 'Slots fallback: Slots in Slots.');
+
+test(() => {
+ let n = createTestTree(test2);
+
+ assert_array_equals(n.s1.assignedElements(), []);
+ assert_array_equals(n.s2.assignedElements(), []);
+
+ assert_array_equals(n.s1.assignedElements({ flatten: true }), [n.f1]);
+ assert_array_equals(n.s2.assignedElements({ flatten: true }), [n.f1]);
+}, 'Slots fallback: Slots in Slots, elements only.');
+</script>
+
+<div id="test3">
+ <div id="host">
+ <template data-mode="open">
+ <slot id="s1" name="slot1">
+ <slot id="s2" name="slot2">
+ <div id="f1"></div>
+ </slot>
+ </slot>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test3);
+ removeWhiteSpaceOnlyTextNodes(n.test3);
+
+ assert_equals(n.c1.assignedSlot, n.s1);
+ assert_equals(n.f1.assignedSlot, null);
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes(), []);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.f1]);
+}, 'Slots fallback: Fallback contents should not be used if a node is assigned.');
+</script>
+
+<div id="test4">
+ <div id="host">
+ <template data-mode="open">
+ <slot id="s1" name="slot1">
+ <slot id="s2" name="slot2">
+ <div id="f1"></div>
+ </slot>
+ </slot>
+ </template>
+ <div id="c1" slot="slot2"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test4);
+ removeWhiteSpaceOnlyTextNodes(n.test4);
+
+ assert_equals(n.c1.assignedSlot, n.s2);
+ assert_equals(n.f1.assignedSlot, null);
+
+ assert_array_equals(n.s1.assignedNodes(), []);
+ assert_array_equals(n.s2.assignedNodes(), [n.c1]);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
+}, 'Slots fallback: Slots in Slots: Assigned nodes should be used as fallback contents of another slot');
+</script>
+
+<div id="test5">
+ <div id="host1">
+ <template data-mode="open">
+ <div id="host2">
+ <template data-mode="open">
+ <slot id="s4" name="slot4">
+ <slot id="s3" name="slot3">
+ <div id="f3"></div>
+ </slot>
+ <div id="f4"></div>
+ </slot>
+ </template>
+ <slot id="s2" name="slot2" slot="slot3">
+ <slot id="s1" name="slot1">
+ <div id="f1"></div>
+ </slot>
+ <div id="f2"></div>
+ </slot>
+ </div>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test5);
+ removeWhiteSpaceOnlyTextNodes(n.test5);
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes(), []);
+ assert_array_equals(n.s3.assignedNodes(), [n.s2]);
+ assert_array_equals(n.s4.assignedNodes(), []);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1, n.f2]);
+ assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.c1, n.f2]);
+ assert_array_equals(n.s4.assignedNodes({ flatten: true }), [n.c1, n.f2, n.f4]);
+}, 'Slots fallback: Complex case.');
+
+test(() => {
+ let n = createTestTree(test5);
+
+ assert_array_equals(n.s1.assignedElements(), [n.c1]);
+ assert_array_equals(n.s2.assignedElements(), []);
+ assert_array_equals(n.s3.assignedElements(), [n.s2]);
+ assert_array_equals(n.s4.assignedElements(), []);
+
+ assert_array_equals(n.s1.assignedElements({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s2.assignedElements({ flatten: true }), [n.c1, n.f2]);
+ assert_array_equals(n.s3.assignedElements({ flatten: true }), [n.c1, n.f2]);
+ assert_array_equals(n.s4.assignedElements({ flatten: true }), [n.c1, n.f2, n.f4]);
+}, 'Slots fallback: Complex case, elements only.');
+
+test(() => {
+ let n = createTestTree(test5);
+ removeWhiteSpaceOnlyTextNodes(n.test5);
+
+ let d1 = document.createElement('div');
+ n.s2.appendChild(d1);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1, n.f2, d1]);
+ assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.c1, n.f2, d1]);
+ assert_array_equals(n.s4.assignedNodes({ flatten: true }), [n.c1, n.f2, d1, n.f4]);
+}, 'Slots fallback: Mutation. Append fallback contents.');
+
+test(() => {
+ let n = createTestTree(test5);
+ removeWhiteSpaceOnlyTextNodes(n.test5);
+
+ n.f2.remove();
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s4.assignedNodes({ flatten: true }), [n.c1, n.f4]);
+}, 'Slots fallback: Mutation. Remove fallback contents.');
+
+test(() => {
+ let n = createTestTree(test5);
+ removeWhiteSpaceOnlyTextNodes(n.test5);
+
+ let d2 = document.createElement('div');
+ d2.setAttribute('slot', 'slot2');
+ n.host1.appendChild(d2);
+
+ assert_array_equals(n.s2.assignedNodes(), [d2]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [d2]);
+ assert_array_equals(n.s3.assignedNodes({ flatten: true }), [d2]);
+ assert_array_equals(n.s4.assignedNodes({ flatten: true }), [d2, n.f4]);
+}, 'Slots fallback: Mutation. Assign a node to a slot so that fallback contens are no longer used.');
+
+test(() => {
+ let n = createTestTree(test5);
+ removeWhiteSpaceOnlyTextNodes(n.test5);
+
+ n.c1.remove();
+
+ assert_array_equals(n.s1.assignedNodes(), []);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.f1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.f1, n.f2]);
+ assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.f1, n.f2]);
+ assert_array_equals(n.s4.assignedNodes({ flatten: true }), [n.f1, n.f2, n.f4]);
+}, 'Slots fallback: Mutation. Remove an assigned node from a slot so that fallback contens will be used.');
+
+test(() => {
+ let n = createTestTree(test5);
+ removeWhiteSpaceOnlyTextNodes(n.test5);
+
+ n.s1.remove();
+
+ assert_array_equals(n.s1.assignedNodes(), []);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [],
+ 'fall back contents should be empty because s1 is not in a shadow tree.');
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.f2]);
+ assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.f2]);
+ assert_array_equals(n.s4.assignedNodes({ flatten: true }), [n.f2, n.f4]);
+}, 'Slots fallback: Mutation. Remove a slot which is a fallback content of another slot.');
+</script>
diff --git a/thys/Shadow_SC_DOM/tests/slots.html b/thys/Shadow_SC_DOM/tests/slots.html
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/slots.html
@@ -0,0 +1,526 @@
+<!DOCTYPE html>
+<title>Shadow DOM: Slots and assignments</title>
+<meta name="author" title="Hayato Ito" href="mailto:hayato@google.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/shadow-dom.js"></script>
+
+<div id="test_basic">
+ <div id="host">
+ <template data-mode="open">
+ <slot id="s1" name="slot1"></slot>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_basic);
+ removeWhiteSpaceOnlyTextNodes(n.test_basic);
+
+ assert_equals(n.c1.assignedSlot, n.s1);
+ assert_array_equals(n.s1.assignedNodes(), [n.c1]);
+}, 'Slots: Basic.');
+
+test(() => {
+ let n = createTestTree(test_basic);
+
+ assert_array_equals(n.s1.assignedElements(), [n.c1]);
+}, 'Slots: Basic, elements only.');
+</script>
+
+<div id="test_basic_closed">
+ <div id="host">
+ <template data-mode="closed">
+ <slot id="s1" name="slot1"></slot>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_basic_closed);
+ removeWhiteSpaceOnlyTextNodes(n.test_basic_closed);
+
+ assert_equals(n.c1.assignedSlot, null);
+ assert_array_equals(n.s1.assignedNodes(), [n.c1]);
+}, 'Slots: Slots in closed.');
+
+test(() => {
+ let n = createTestTree(test_basic_closed);
+
+ assert_array_equals(n.s1.assignedElements(), [n.c1]);
+}, 'Slots: Slots in closed, elements only.');
+</script>
+
+<div id="test_slot_not_in_shadow">
+ <slot id="s1"></slot>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_slot_not_in_shadow);
+ removeWhiteSpaceOnlyTextNodes(n.test_slot_not_in_shadow);
+
+ assert_array_equals(n.s1.assignedNodes(), []);
+}, 'Slots: Slots not in a shadow tree.');
+
+test(() => {
+ let n = createTestTree(test_slot_not_in_shadow);
+
+ assert_array_equals(n.s1.assignedElements(), []);
+}, 'Slots: Slots not in a shadow tree, elements only.');
+</script>
+
+<div id="test_slot_not_in_shadow_2">
+ <slot id="s1">
+ <div id="c1"></div>
+ </slot>
+ <slot id="s2">
+ <div id="c2"></div>
+ <slot id="s3">
+ <div id="c3_1"></div>
+ <div id="c3_2"></div>
+ </slot>
+ </slot>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_slot_not_in_shadow_2);
+ removeWhiteSpaceOnlyTextNodes(n.test_slot_not_in_shadow_2);
+
+ assert_equals(n.c1.assignedSlot, null);
+ assert_equals(n.c2.assignedSlot, null);
+ assert_equals(n.c3_1.assignedSlot, null);
+ assert_equals(n.c3_2.assignedSlot, null);
+
+ assert_array_equals(n.s1.assignedNodes(), []);
+ assert_array_equals(n.s2.assignedNodes(), []);
+ assert_array_equals(n.s3.assignedNodes(), []);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), []);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), []);
+ assert_array_equals(n.s3.assignedNodes({ flatten: true }), []);
+}, 'Slots: Distributed nodes for Slots not in a shadow tree.');
+</script>
+
+<div id="test_slot_name_matching">
+ <div id="host">
+ <template data-mode="open">
+ <slot id="s1" name="slot1"></slot>
+ <slot id="s2" name="slot2"></slot>
+ <slot id="s3" name="xxx"></slot>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ <div id="c2" slot="slot2"></div>
+ <div id="c3" slot="yyy"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_slot_name_matching);
+ removeWhiteSpaceOnlyTextNodes(n.test_slot_name_matching);
+
+ assert_equals(n.c1.assignedSlot, n.s1);
+ assert_equals(n.c2.assignedSlot, n.s2);
+ assert_equals(n.c3.assignedSlot, null);
+}, 'Slots: Name matching');
+</script>
+
+<div id="test_no_direct_host_child">
+ <div id="host">
+ <template data-mode="open">
+ <slot id="s1" name="slot1"></slot>
+ <slot id="s2" name="slot1"></slot>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ <div id="c2" slot="slot1"></div>
+ <div>
+ <div id="c3" slot="slot1"></div>
+ </div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_no_direct_host_child);
+ removeWhiteSpaceOnlyTextNodes(n.test_no_direct_host_child);
+
+ assert_equals(n.c1.assignedSlot, n.s1);
+ assert_equals(n.c2.assignedSlot, n.s1);
+ assert_equals(n.c3.assignedSlot, null);
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c1, n.c2]);
+}, 'Slots: No direct host child.');
+</script>
+
+<div id="test_default_slot">
+ <div id="host">
+ <template data-mode="open">
+ <slot id="s1" name="slot1"></slot>
+ <slot id="s2"></slot>
+ <slot id="s3"></slot>
+ </template>
+ <div id="c1"></div>
+ <div id="c2" slot=""></div>
+ <div id="c3" slot="foo"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_default_slot);
+ removeWhiteSpaceOnlyTextNodes(n.test_default_slot);
+
+ assert_equals(n.c1.assignedSlot, n.s2);
+ assert_equals(n.c2.assignedSlot, n.s2);
+ assert_equals(n.c3.assignedSlot, null);
+}, 'Slots: Default Slot.');
+</script>
+
+<div id="test_slot_in_slot">
+ <div id="host">
+ <template data-mode="open">
+ <slot id="s1" name="slot1">
+ <slot id="s2" name="slot2"></slot>
+ </slot>
+ </template>
+ <div id="c1" slot="slot2"></div>
+ <div id="c2" slot="slot1"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_slot_in_slot);
+ removeWhiteSpaceOnlyTextNodes(n.test_slot_in_slot);
+
+ assert_equals(n.c1.assignedSlot, n.s2);
+ assert_equals(n.c2.assignedSlot, n.s1);
+}, 'Slots: Slot in Slot does not matter in assignment.');
+</script>
+
+<div id="test_slot_is_assigned_to_slot">
+ <div id="host1">
+ <template data-mode="open">
+ <div id="host2">
+ <template data-mode="open">
+ <slot id="s2" name="slot2"></slot>
+ </template>
+ <slot id="s1" name="slot1" slot="slot2"></slot>
+ </div>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_slot_is_assigned_to_slot);
+ removeWhiteSpaceOnlyTextNodes(n.test_slot_is_assigned_to_slot);
+
+ assert_equals(n.c1.assignedSlot, n.s1);
+ assert_equals(n.s1.assignedSlot, n.s2);
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes(), [n.s1]);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
+}, 'Slots: Slot is assigned to another slot');
+</script>
+
+<div id="test_open_closed">
+ <div id="host1">
+ <template data-mode="open">
+ <div id="host2">
+ <template data-mode="closed">
+ <slot id="s2" name="slot2"></slot>
+ </template>
+ <slot id="s1" name="slot1" slot="slot2"></slot>
+ </div>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_open_closed);
+ removeWhiteSpaceOnlyTextNodes(n.test_open_closed);
+
+ assert_equals(n.c1.assignedSlot, n.s1);
+ assert_equals(n.s1.assignedSlot, null,
+ 'A slot in a closed shadow tree should not be accessed via assignedSlot');
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes(), [n.s1]);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
+}, 'Slots: Open > Closed.');
+</script>
+
+<div id="test_closed_closed">
+ <div id="host1">
+ <template data-mode="closed">
+ <div id="host2">
+ <template data-mode="closed">
+ <slot id="s2" name="slot2"></slot>
+ </template>
+ <slot id="s1" name="slot1" slot="slot2"></slot>
+ </div>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_closed_closed);
+ removeWhiteSpaceOnlyTextNodes(n.test_closed_closed);
+
+ assert_equals(n.c1.assignedSlot, null,
+ 'A slot in a closed shadow tree should not be accessed via assignedSlot');
+ assert_equals(n.s1.assignedSlot, null,
+ 'A slot in a closed shadow tree should not be accessed via assignedSlot');
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes(), [n.s1]);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
+}, 'Slots: Closed > Closed.');
+</script>
+
+<div id="test_closed_open">
+ <div id="host1">
+ <template data-mode="closed">
+ <div id="host2">
+ <template data-mode="open">
+ <slot id="s2" name="slot2"></slot>
+ </template>
+ <slot id="s1" name="slot1" slot="slot2"></slot>
+ </div>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_closed_open);
+ removeWhiteSpaceOnlyTextNodes(n.test_closed_open);
+
+ assert_equals(n.c1.assignedSlot, null,
+ 'A slot in a closed shadow tree should not be accessed via assignedSlot');
+ assert_equals(n.s1.assignedSlot, n.s2);
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes(), [n.s1]);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c1]);
+}, 'Slots: Closed > Open.');
+</script>
+
+<div id="test_complex">
+ <div id="host1">
+ <template data-mode="open">
+ <div id="host2">
+ <template data-mode="open">
+ <slot id="s5" name="slot5"></slot>
+ <slot id="s6" name="slot6"></slot>
+ <slot id="s7"></slot>
+ <slot id="s8" name="slot8"></slot>
+ </template>
+ <slot id="s1" name="slot1" slot="slot5"></slot>
+ <slot id="s2" name="slot2" slot="slot6"></slot>
+ <slot id="s3"></slot>
+ <slot id="s4" name="slot4" slot="slot-none"></slot>
+ <div id="c5" slot="slot5"></div>
+ <div id="c6" slot="slot6"></div>
+ <div id="c7"></div>
+ <div id="c8" slot="slot-none"></div>
+ </div>
+ </template>
+ <div id="c1" slot="slot1"></div>
+ <div id="c2" slot="slot2"></div>
+ <div id="c3"></div>
+ <div id="c4" slot="slot-none"></div>
+ </div>
+</div>
+
+<script>
+test(() => {
+ let n = createTestTree(test_complex);
+ removeWhiteSpaceOnlyTextNodes(n.test_complex);
+
+ assert_equals(n.c1.assignedSlot, n.s1);
+ assert_equals(n.c2.assignedSlot, n.s2);
+ assert_equals(n.c3.assignedSlot, n.s3);
+ assert_equals(n.c4.assignedSlot, null);
+
+ assert_equals(n.s1.assignedSlot, n.s5);
+ assert_equals(n.s2.assignedSlot, n.s6);
+ assert_equals(n.s3.assignedSlot, n.s7);
+ assert_equals(n.s4.assignedSlot, null);
+
+ assert_equals(n.c5.assignedSlot, n.s5);
+ assert_equals(n.c6.assignedSlot, n.s6);
+ assert_equals(n.c7.assignedSlot, n.s7);
+ assert_equals(n.c8.assignedSlot, null);
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes(), [n.c2]);
+ assert_array_equals(n.s3.assignedNodes(), [n.c3]);
+ assert_array_equals(n.s4.assignedNodes(), []);
+ assert_array_equals(n.s5.assignedNodes(), [n.s1, n.c5]);
+ assert_array_equals(n.s6.assignedNodes(), [n.s2, n.c6]);
+ assert_array_equals(n.s7.assignedNodes(), [n.s3, n.c7]);
+ assert_array_equals(n.s8.assignedNodes(), []);
+
+ assert_array_equals(n.s1.assignedNodes({ flatten: true }), [n.c1]);
+ assert_array_equals(n.s2.assignedNodes({ flatten: true }), [n.c2]);
+ assert_array_equals(n.s3.assignedNodes({ flatten: true }), [n.c3]);
+ assert_array_equals(n.s4.assignedNodes({ flatten: true }), []);
+ assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c1, n.c5]);
+ assert_array_equals(n.s6.assignedNodes({ flatten: true }), [n.c2, n.c6]);
+ assert_array_equals(n.s7.assignedNodes({ flatten: true }), [n.c3, n.c7]);
+ assert_array_equals(n.s8.assignedNodes({ flatten: true }), []);
+}, 'Slots: Complex case: Basi line.');
+
+test(() => {
+ let n = createTestTree(test_complex);
+ removeWhiteSpaceOnlyTextNodes(n.test_complex);
+
+ let d1 = document.createElement('div');
+ d1.setAttribute('slot', 'slot1');
+ n.host1.appendChild(d1);
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c1, d1]);
+ assert_equals(d1.assignedSlot, n.s1);
+
+ assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c1, d1, n.c5]);
+}, 'Slots: Mutation: appendChild.');
+
+test(() => {
+ let n = createTestTree(test_complex);
+ removeWhiteSpaceOnlyTextNodes(n.test_complex);
+
+ n.c1.setAttribute('slot', 'slot-none');
+
+ assert_array_equals(n.s1.assignedNodes(), []);
+ assert_equals(n.c1.assignedSlot, null);
+
+ assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]);
+}, 'Slots: Mutation: Change slot= attribute 1.');
+
+test(() => {
+ let n = createTestTree(test_complex);
+ removeWhiteSpaceOnlyTextNodes(n.test_complex);
+
+ n.c1.setAttribute('slot', 'slot2');
+
+ assert_array_equals(n.s1.assignedNodes(), []);
+ assert_array_equals(n.s2.assignedNodes(), [n.c1, n.c2]);
+ assert_equals(n.c1.assignedSlot, n.s2);
+
+ assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]);
+ assert_array_equals(n.s6.assignedNodes({ flatten: true }), [n.c1, n.c2, n.c6]);
+}, 'Slots: Mutation: Change slot= attribute 2.');
+
+test(() => {
+ let n = createTestTree(test_complex);
+ removeWhiteSpaceOnlyTextNodes(n.test_complex);
+
+ n.c4.setAttribute('slot', 'slot1');
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c1, n.c4]);
+ assert_equals(n.c4.assignedSlot, n.s1);
+
+ assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c1, n.c4, n.c5]);
+}, 'Slots: Mutation: Change slot= attribute 3.');
+
+test(() => {
+ let n = createTestTree(test_complex);
+ removeWhiteSpaceOnlyTextNodes(n.test_complex);
+
+ n.c1.remove();
+
+ assert_array_equals(n.s1.assignedNodes(), []);
+ assert_equals(n.c1.assignedSlot, null);
+
+ assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]);
+}, 'Slots: Mutation: Remove a child.');
+
+test(() => {
+ let n = createTestTree(test_complex);
+ removeWhiteSpaceOnlyTextNodes(n.test_complex);
+
+ let slot = document.createElement('slot');
+ slot.setAttribute('name', 'slot1');
+ n.host2.appendChild(slot);
+
+ assert_array_equals(slot.assignedNodes(), []);
+}, 'Slots: Mutation: Add a slot: after.');
+
+test(() => {
+ let n = createTestTree(test_complex);
+ removeWhiteSpaceOnlyTextNodes(n.test_complex);
+
+ let slot = document.createElement('slot');
+ slot.setAttribute('name', 'slot1');
+ n.host2.insertBefore(slot, n.s1);
+
+ assert_array_equals(slot.assignedNodes(), [n.c1]);
+ assert_equals(n.c1.assignedSlot, slot);
+
+ assert_array_equals(n.s7.assignedNodes(), [slot, n.s3, n.c7]);
+ assert_array_equals(n.s7.assignedNodes({ flatten: true }), [n.c1, n.c3, n.c7]);
+}, 'Slots: Mutation: Add a slot: before.');
+
+test(() => {
+ let n = createTestTree(test_complex);
+ removeWhiteSpaceOnlyTextNodes(n.test_complex);
+
+ n.s1.remove();
+
+ assert_array_equals(n.s1.assignedNodes(), []);
+ assert_equals(n.c1.assignedSlot, null);
+
+ assert_array_equals(n.s5.assignedNodes(), [n.c5]);
+ assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c5]);
+}, 'Slots: Mutation: Remove a slot.');
+
+test(() => {
+ let n = createTestTree(test_complex);
+ removeWhiteSpaceOnlyTextNodes(n.test_complex);
+
+ n.s1.setAttribute('name', 'slot2');
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c2]);
+ assert_equals(n.c1.assignedSlot, null);
+ assert_equals(n.c2.assignedSlot, n.s1);
+
+ assert_array_equals(n.s5.assignedNodes(), [n.s1, n.c5]);
+ assert_array_equals(n.s5.assignedNodes({ flatten: true }), [n.c2, n.c5]);
+}, 'Slots: Mutation: Change slot name= attribute.');
+
+test(() => {
+ let n = createTestTree(test_complex);
+ removeWhiteSpaceOnlyTextNodes(n.test_complex);
+
+ n.s1.setAttribute('slot', 'slot6');
+
+ assert_array_equals(n.s1.assignedNodes(), [n.c1]);
+
+ assert_array_equals(n.s5.assignedNodes(), [n.c5]);
+ assert_array_equals(n.s6.assignedNodes(), [n.s1, n.s2, n.c6]);
+ assert_array_equals(n.s6.assignedNodes({ flatten: true }), [n.c1, n.c2, n.c6]);
+}, 'Slots: Mutation: Change slot slot= attribute.');
+</script>
diff --git a/thys/Shadow_SC_DOM/tests/slots.thy b/thys/Shadow_SC_DOM/tests/slots.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/slots.thy
@@ -0,0 +1,947 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+(* This file is automatically generated, please do not modify! *)
+
+section\<open>Testing slots\<close>
+text\<open>This theory contains the test cases for slots.\<close>
+
+theory slots
+imports
+ "Shadow_DOM_BaseTest"
+begin
+
+definition slots_heap :: "heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l" where
+ "slots_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
+ (cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 8)] fmempty None)),
+ (cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6), cast (element_ptr.Ref 7)] fmempty None)),
+ (cast (element_ptr.Ref 3), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
+ (cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Shadow%20DOM%3A%20Slots%20and%20assignments'')),
+ (cast (element_ptr.Ref 4), cast (create_element_obj ''meta'' [] (fmap_of_list [(''name'', ''author''), (''title'', ''Hayato Ito''), (''href'', ''mailto:hayato@google.com'')]) None)),
+ (cast (element_ptr.Ref 5), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
+ (cast (element_ptr.Ref 6), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
+ (cast (element_ptr.Ref 7), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''resources/shadow-dom.js'')]) None)),
+ (cast (element_ptr.Ref 8), cast (create_element_obj ''body'' [cast (element_ptr.Ref 9), cast (element_ptr.Ref 13), cast (element_ptr.Ref 14), cast (element_ptr.Ref 18), cast (element_ptr.Ref 19), cast (element_ptr.Ref 21), cast (element_ptr.Ref 22), cast (element_ptr.Ref 30), cast (element_ptr.Ref 31), cast (element_ptr.Ref 39), cast (element_ptr.Ref 40), cast (element_ptr.Ref 48), cast (element_ptr.Ref 49), cast (element_ptr.Ref 57), cast (element_ptr.Ref 58), cast (element_ptr.Ref 64), cast (element_ptr.Ref 65), cast (element_ptr.Ref 71), cast (element_ptr.Ref 72), cast (element_ptr.Ref 78), cast (element_ptr.Ref 79), cast (element_ptr.Ref 85), cast (element_ptr.Ref 86), cast (element_ptr.Ref 92), cast (element_ptr.Ref 93), cast (element_ptr.Ref 112)] fmempty None)),
+ (cast (element_ptr.Ref 9), cast (create_element_obj ''div'' [cast (element_ptr.Ref 10)] (fmap_of_list [(''id'', ''test_basic'')]) None)),
+ (cast (element_ptr.Ref 10), cast (create_element_obj ''div'' [cast (element_ptr.Ref 11)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 1))))),
+ (cast (element_ptr.Ref 11), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (shadow_root_ptr.Ref 1), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 12)])),
+ (cast (element_ptr.Ref 12), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 13), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 2)] fmempty None)),
+ (cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 14), cast (create_element_obj ''div'' [cast (element_ptr.Ref 15)] (fmap_of_list [(''id'', ''test_basic_closed'')]) None)),
+ (cast (element_ptr.Ref 15), cast (create_element_obj ''div'' [cast (element_ptr.Ref 16)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 2))))),
+ (cast (element_ptr.Ref 16), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (shadow_root_ptr.Ref 2), cast (create_shadow_root_obj Closed [cast (element_ptr.Ref 17)])),
+ (cast (element_ptr.Ref 17), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 18), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 3)] fmempty None)),
+ (cast (character_data_ptr.Ref 3), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 19), cast (create_element_obj ''div'' [cast (element_ptr.Ref 20)] (fmap_of_list [(''id'', ''test_slot_not_in_shadow'')]) None)),
+ (cast (element_ptr.Ref 20), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1'')]) None)),
+ (cast (element_ptr.Ref 21), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 4)] fmempty None)),
+ (cast (character_data_ptr.Ref 4), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 22), cast (create_element_obj ''div'' [cast (element_ptr.Ref 23), cast (element_ptr.Ref 25)] (fmap_of_list [(''id'', ''test_slot_not_in_shadow_2'')]) None)),
+ (cast (element_ptr.Ref 23), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 24)] (fmap_of_list [(''id'', ''s1'')]) None)),
+ (cast (element_ptr.Ref 24), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1'')]) None)),
+ (cast (element_ptr.Ref 25), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 26), cast (element_ptr.Ref 27)] (fmap_of_list [(''id'', ''s2'')]) None)),
+ (cast (element_ptr.Ref 26), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2'')]) None)),
+ (cast (element_ptr.Ref 27), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 28), cast (element_ptr.Ref 29)] (fmap_of_list [(''id'', ''s3'')]) None)),
+ (cast (element_ptr.Ref 28), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3_1'')]) None)),
+ (cast (element_ptr.Ref 29), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3_2'')]) None)),
+ (cast (element_ptr.Ref 30), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 5)] fmempty None)),
+ (cast (character_data_ptr.Ref 5), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 31), cast (create_element_obj ''div'' [cast (element_ptr.Ref 32)] (fmap_of_list [(''id'', ''test_slot_name_matching'')]) None)),
+ (cast (element_ptr.Ref 32), cast (create_element_obj ''div'' [cast (element_ptr.Ref 33), cast (element_ptr.Ref 34), cast (element_ptr.Ref 35)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 3))))),
+ (cast (element_ptr.Ref 33), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 34), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2''), (''slot'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 35), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3''), (''slot'', ''yyy'')]) None)),
+ (cast (shadow_root_ptr.Ref 3), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 36), cast (element_ptr.Ref 37), cast (element_ptr.Ref 38)])),
+ (cast (element_ptr.Ref 36), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 37), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 38), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s3''), (''name'', ''xxx'')]) None)),
+ (cast (element_ptr.Ref 39), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 6)] fmempty None)),
+ (cast (character_data_ptr.Ref 6), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 40), cast (create_element_obj ''div'' [cast (element_ptr.Ref 41)] (fmap_of_list [(''id'', ''test_no_direct_host_child'')]) None)),
+ (cast (element_ptr.Ref 41), cast (create_element_obj ''div'' [cast (element_ptr.Ref 42), cast (element_ptr.Ref 43), cast (element_ptr.Ref 44)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 4))))),
+ (cast (element_ptr.Ref 42), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 43), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2''), (''slot'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 44), cast (create_element_obj ''div'' [cast (element_ptr.Ref 45)] fmempty None)),
+ (cast (element_ptr.Ref 45), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3''), (''slot'', ''slot1'')]) None)),
+ (cast (shadow_root_ptr.Ref 4), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 46), cast (element_ptr.Ref 47)])),
+ (cast (element_ptr.Ref 46), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 47), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 48), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 7)] fmempty None)),
+ (cast (character_data_ptr.Ref 7), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 49), cast (create_element_obj ''div'' [cast (element_ptr.Ref 50)] (fmap_of_list [(''id'', ''test_default_slot'')]) None)),
+ (cast (element_ptr.Ref 50), cast (create_element_obj ''div'' [cast (element_ptr.Ref 51), cast (element_ptr.Ref 52), cast (element_ptr.Ref 53)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 5))))),
+ (cast (element_ptr.Ref 51), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1'')]) None)),
+ (cast (element_ptr.Ref 52), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2''), (''slot'', '''')]) None)),
+ (cast (element_ptr.Ref 53), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3''), (''slot'', ''foo'')]) None)),
+ (cast (shadow_root_ptr.Ref 5), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 54), cast (element_ptr.Ref 55), cast (element_ptr.Ref 56)])),
+ (cast (element_ptr.Ref 54), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 55), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2'')]) None)),
+ (cast (element_ptr.Ref 56), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s3'')]) None)),
+ (cast (element_ptr.Ref 57), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 8)] fmempty None)),
+ (cast (character_data_ptr.Ref 8), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 58), cast (create_element_obj ''div'' [cast (element_ptr.Ref 59)] (fmap_of_list [(''id'', ''test_slot_in_slot'')]) None)),
+ (cast (element_ptr.Ref 59), cast (create_element_obj ''div'' [cast (element_ptr.Ref 60), cast (element_ptr.Ref 61)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 6))))),
+ (cast (element_ptr.Ref 60), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 61), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2''), (''slot'', ''slot1'')]) None)),
+ (cast (shadow_root_ptr.Ref 6), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 62)])),
+ (cast (element_ptr.Ref 62), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 63)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 63), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 64), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 9)] fmempty None)),
+ (cast (character_data_ptr.Ref 9), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 65), cast (create_element_obj ''div'' [cast (element_ptr.Ref 66)] (fmap_of_list [(''id'', ''test_slot_is_assigned_to_slot'')]) None)),
+ (cast (element_ptr.Ref 66), cast (create_element_obj ''div'' [cast (element_ptr.Ref 67)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 7))))),
+ (cast (element_ptr.Ref 67), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (shadow_root_ptr.Ref 7), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 68)])),
+ (cast (element_ptr.Ref 68), cast (create_element_obj ''div'' [cast (element_ptr.Ref 69)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 8))))),
+ (cast (element_ptr.Ref 69), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1''), (''slot'', ''slot2'')]) None)),
+ (cast (shadow_root_ptr.Ref 8), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 70)])),
+ (cast (element_ptr.Ref 70), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 71), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 10)] fmempty None)),
+ (cast (character_data_ptr.Ref 10), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 72), cast (create_element_obj ''div'' [cast (element_ptr.Ref 73)] (fmap_of_list [(''id'', ''test_open_closed'')]) None)),
+ (cast (element_ptr.Ref 73), cast (create_element_obj ''div'' [cast (element_ptr.Ref 74)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 9))))),
+ (cast (element_ptr.Ref 74), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (shadow_root_ptr.Ref 9), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 75)])),
+ (cast (element_ptr.Ref 75), cast (create_element_obj ''div'' [cast (element_ptr.Ref 76)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 10))))),
+ (cast (element_ptr.Ref 76), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1''), (''slot'', ''slot2'')]) None)),
+ (cast (shadow_root_ptr.Ref 10), cast (create_shadow_root_obj Closed [cast (element_ptr.Ref 77)])),
+ (cast (element_ptr.Ref 77), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 78), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 11)] fmempty None)),
+ (cast (character_data_ptr.Ref 11), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 79), cast (create_element_obj ''div'' [cast (element_ptr.Ref 80)] (fmap_of_list [(''id'', ''test_closed_closed'')]) None)),
+ (cast (element_ptr.Ref 80), cast (create_element_obj ''div'' [cast (element_ptr.Ref 81)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 11))))),
+ (cast (element_ptr.Ref 81), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (shadow_root_ptr.Ref 11), cast (create_shadow_root_obj Closed [cast (element_ptr.Ref 82)])),
+ (cast (element_ptr.Ref 82), cast (create_element_obj ''div'' [cast (element_ptr.Ref 83)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 12))))),
+ (cast (element_ptr.Ref 83), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1''), (''slot'', ''slot2'')]) None)),
+ (cast (shadow_root_ptr.Ref 12), cast (create_shadow_root_obj Closed [cast (element_ptr.Ref 84)])),
+ (cast (element_ptr.Ref 84), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 85), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 12)] fmempty None)),
+ (cast (character_data_ptr.Ref 12), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 86), cast (create_element_obj ''div'' [cast (element_ptr.Ref 87)] (fmap_of_list [(''id'', ''test_closed_open'')]) None)),
+ (cast (element_ptr.Ref 87), cast (create_element_obj ''div'' [cast (element_ptr.Ref 88)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 13))))),
+ (cast (element_ptr.Ref 88), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (shadow_root_ptr.Ref 13), cast (create_shadow_root_obj Closed [cast (element_ptr.Ref 89)])),
+ (cast (element_ptr.Ref 89), cast (create_element_obj ''div'' [cast (element_ptr.Ref 90)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 14))))),
+ (cast (element_ptr.Ref 90), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1''), (''slot'', ''slot2'')]) None)),
+ (cast (shadow_root_ptr.Ref 14), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 91)])),
+ (cast (element_ptr.Ref 91), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 92), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 13)] fmempty None)),
+ (cast (character_data_ptr.Ref 13), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 93), cast (create_element_obj ''div'' [cast (element_ptr.Ref 94)] (fmap_of_list [(''id'', ''test_complex'')]) None)),
+ (cast (element_ptr.Ref 94), cast (create_element_obj ''div'' [cast (element_ptr.Ref 95), cast (element_ptr.Ref 96), cast (element_ptr.Ref 97), cast (element_ptr.Ref 98)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 15))))),
+ (cast (element_ptr.Ref 95), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 96), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c2''), (''slot'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 97), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c3'')]) None)),
+ (cast (element_ptr.Ref 98), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c4''), (''slot'', ''slot-none'')]) None)),
+ (cast (shadow_root_ptr.Ref 15), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 99)])),
+ (cast (element_ptr.Ref 99), cast (create_element_obj ''div'' [cast (element_ptr.Ref 100), cast (element_ptr.Ref 101), cast (element_ptr.Ref 102), cast (element_ptr.Ref 103), cast (element_ptr.Ref 104), cast (element_ptr.Ref 105), cast (element_ptr.Ref 106), cast (element_ptr.Ref 107)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 16))))),
+ (cast (element_ptr.Ref 100), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1''), (''slot'', ''slot5'')]) None)),
+ (cast (element_ptr.Ref 101), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2''), (''slot'', ''slot6'')]) None)),
+ (cast (element_ptr.Ref 102), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s3'')]) None)),
+ (cast (element_ptr.Ref 103), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s4''), (''name'', ''slot4''), (''slot'', ''slot-none'')]) None)),
+ (cast (element_ptr.Ref 104), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c5''), (''slot'', ''slot5'')]) None)),
+ (cast (element_ptr.Ref 105), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c6''), (''slot'', ''slot6'')]) None)),
+ (cast (element_ptr.Ref 106), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c7'')]) None)),
+ (cast (element_ptr.Ref 107), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c8''), (''slot'', ''slot-none'')]) None)),
+ (cast (shadow_root_ptr.Ref 16), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 108), cast (element_ptr.Ref 109), cast (element_ptr.Ref 110), cast (element_ptr.Ref 111)])),
+ (cast (element_ptr.Ref 108), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s5''), (''name'', ''slot5'')]) None)),
+ (cast (element_ptr.Ref 109), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s6''), (''name'', ''slot6'')]) None)),
+ (cast (element_ptr.Ref 110), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s7'')]) None)),
+ (cast (element_ptr.Ref 111), cast (create_element_obj ''slot'' [] (fmap_of_list [(''id'', ''s8''), (''name'', ''slot8'')]) None)),
+ (cast (element_ptr.Ref 112), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 14)] fmempty None)),
+ (cast (character_data_ptr.Ref 14), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
+
+definition slots_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "slots_document = Some (cast (document_ptr.Ref 1))"
+
+
+text \<open>'Slots: Basic.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_basic'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_basic'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ tmp4 \<leftarrow> n . ''s1'';
+ assert_equals(tmp3, tmp4);
+ tmp5 \<leftarrow> n . ''s1'';
+ tmp6 \<leftarrow> tmp5 . assignedNodes();
+ tmp7 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp6, [tmp7])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Basic, elements only.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_basic'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''s1'';
+ tmp2 \<leftarrow> tmp1 . assignedElements();
+ tmp3 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp2, [tmp3])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Slots in closed.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_basic_closed'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_basic_closed'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ assert_equals(tmp3, None);
+ tmp4 \<leftarrow> n . ''s1'';
+ tmp5 \<leftarrow> tmp4 . assignedNodes();
+ tmp6 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp5, [tmp6])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Slots in closed, elements only.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_basic_closed'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''s1'';
+ tmp2 \<leftarrow> tmp1 . assignedElements();
+ tmp3 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp2, [tmp3])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Slots not in a shadow tree.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_slot_not_in_shadow'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_slot_not_in_shadow'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''s1'';
+ tmp3 \<leftarrow> tmp2 . assignedNodes();
+ assert_array_equals(tmp3, [])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Slots not in a shadow tree, elements only.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_slot_not_in_shadow'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''s1'';
+ tmp2 \<leftarrow> tmp1 . assignedElements();
+ assert_array_equals(tmp2, [])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Distributed nodes for Slots not in a shadow tree.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_slot_not_in_shadow_2'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_slot_not_in_shadow_2'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ assert_equals(tmp3, None);
+ tmp4 \<leftarrow> n . ''c2'';
+ tmp5 \<leftarrow> tmp4 . assignedSlot;
+ assert_equals(tmp5, None);
+ tmp6 \<leftarrow> n . ''c3_1'';
+ tmp7 \<leftarrow> tmp6 . assignedSlot;
+ assert_equals(tmp7, None);
+ tmp8 \<leftarrow> n . ''c3_2'';
+ tmp9 \<leftarrow> tmp8 . assignedSlot;
+ assert_equals(tmp9, None);
+ tmp10 \<leftarrow> n . ''s1'';
+ tmp11 \<leftarrow> tmp10 . assignedNodes();
+ assert_array_equals(tmp11, []);
+ tmp12 \<leftarrow> n . ''s2'';
+ tmp13 \<leftarrow> tmp12 . assignedNodes();
+ assert_array_equals(tmp13, []);
+ tmp14 \<leftarrow> n . ''s3'';
+ tmp15 \<leftarrow> tmp14 . assignedNodes();
+ assert_array_equals(tmp15, []);
+ tmp16 \<leftarrow> n . ''s1'';
+ tmp17 \<leftarrow> tmp16 . assignedNodes(True);
+ assert_array_equals(tmp17, []);
+ tmp18 \<leftarrow> n . ''s2'';
+ tmp19 \<leftarrow> tmp18 . assignedNodes(True);
+ assert_array_equals(tmp19, []);
+ tmp20 \<leftarrow> n . ''s3'';
+ tmp21 \<leftarrow> tmp20 . assignedNodes(True);
+ assert_array_equals(tmp21, [])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Name matching'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_slot_name_matching'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_slot_name_matching'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ tmp4 \<leftarrow> n . ''s1'';
+ assert_equals(tmp3, tmp4);
+ tmp5 \<leftarrow> n . ''c2'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ tmp7 \<leftarrow> n . ''s2'';
+ assert_equals(tmp6, tmp7);
+ tmp8 \<leftarrow> n . ''c3'';
+ tmp9 \<leftarrow> tmp8 . assignedSlot;
+ assert_equals(tmp9, None)
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: No direct host child.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_no_direct_host_child'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_no_direct_host_child'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ tmp4 \<leftarrow> n . ''s1'';
+ assert_equals(tmp3, tmp4);
+ tmp5 \<leftarrow> n . ''c2'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ tmp7 \<leftarrow> n . ''s1'';
+ assert_equals(tmp6, tmp7);
+ tmp8 \<leftarrow> n . ''c3'';
+ tmp9 \<leftarrow> tmp8 . assignedSlot;
+ assert_equals(tmp9, None);
+ tmp10 \<leftarrow> n . ''s1'';
+ tmp11 \<leftarrow> tmp10 . assignedNodes();
+ tmp12 \<leftarrow> n . ''c1'';
+ tmp13 \<leftarrow> n . ''c2'';
+ assert_array_equals(tmp11, [tmp12, tmp13])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Default Slot.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_default_slot'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_default_slot'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ tmp4 \<leftarrow> n . ''s2'';
+ assert_equals(tmp3, tmp4);
+ tmp5 \<leftarrow> n . ''c2'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ tmp7 \<leftarrow> n . ''s2'';
+ assert_equals(tmp6, tmp7);
+ tmp8 \<leftarrow> n . ''c3'';
+ tmp9 \<leftarrow> tmp8 . assignedSlot;
+ assert_equals(tmp9, None)
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Slot in Slot does not matter in assignment.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_slot_in_slot'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_slot_in_slot'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ tmp4 \<leftarrow> n . ''s2'';
+ assert_equals(tmp3, tmp4);
+ tmp5 \<leftarrow> n . ''c2'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ tmp7 \<leftarrow> n . ''s1'';
+ assert_equals(tmp6, tmp7)
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Slot is assigned to another slot'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_slot_is_assigned_to_slot'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_slot_is_assigned_to_slot'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ tmp4 \<leftarrow> n . ''s1'';
+ assert_equals(tmp3, tmp4);
+ tmp5 \<leftarrow> n . ''s1'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ tmp7 \<leftarrow> n . ''s2'';
+ assert_equals(tmp6, tmp7);
+ tmp8 \<leftarrow> n . ''s1'';
+ tmp9 \<leftarrow> tmp8 . assignedNodes();
+ tmp10 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp9, [tmp10]);
+ tmp11 \<leftarrow> n . ''s2'';
+ tmp12 \<leftarrow> tmp11 . assignedNodes();
+ tmp13 \<leftarrow> n . ''s1'';
+ assert_array_equals(tmp12, [tmp13]);
+ tmp14 \<leftarrow> n . ''s1'';
+ tmp15 \<leftarrow> tmp14 . assignedNodes(True);
+ tmp16 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp15, [tmp16]);
+ tmp17 \<leftarrow> n . ''s2'';
+ tmp18 \<leftarrow> tmp17 . assignedNodes(True);
+ tmp19 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp18, [tmp19])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Open > Closed.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_open_closed'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_open_closed'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ tmp4 \<leftarrow> n . ''s1'';
+ assert_equals(tmp3, tmp4);
+ tmp5 \<leftarrow> n . ''s1'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ assert_equals(tmp6, None, ''A slot in a closed shadow tree should not be accessed via assignedSlot'');
+ tmp7 \<leftarrow> n . ''s1'';
+ tmp8 \<leftarrow> tmp7 . assignedNodes();
+ tmp9 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp8, [tmp9]);
+ tmp10 \<leftarrow> n . ''s2'';
+ tmp11 \<leftarrow> tmp10 . assignedNodes();
+ tmp12 \<leftarrow> n . ''s1'';
+ assert_array_equals(tmp11, [tmp12]);
+ tmp13 \<leftarrow> n . ''s1'';
+ tmp14 \<leftarrow> tmp13 . assignedNodes(True);
+ tmp15 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp14, [tmp15]);
+ tmp16 \<leftarrow> n . ''s2'';
+ tmp17 \<leftarrow> tmp16 . assignedNodes(True);
+ tmp18 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp17, [tmp18])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Closed > Closed.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_closed_closed'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_closed_closed'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ assert_equals(tmp3, None, ''A slot in a closed shadow tree should not be accessed via assignedSlot'');
+ tmp4 \<leftarrow> n . ''s1'';
+ tmp5 \<leftarrow> tmp4 . assignedSlot;
+ assert_equals(tmp5, None, ''A slot in a closed shadow tree should not be accessed via assignedSlot'');
+ tmp6 \<leftarrow> n . ''s1'';
+ tmp7 \<leftarrow> tmp6 . assignedNodes();
+ tmp8 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp7, [tmp8]);
+ tmp9 \<leftarrow> n . ''s2'';
+ tmp10 \<leftarrow> tmp9 . assignedNodes();
+ tmp11 \<leftarrow> n . ''s1'';
+ assert_array_equals(tmp10, [tmp11]);
+ tmp12 \<leftarrow> n . ''s1'';
+ tmp13 \<leftarrow> tmp12 . assignedNodes(True);
+ tmp14 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp13, [tmp14]);
+ tmp15 \<leftarrow> n . ''s2'';
+ tmp16 \<leftarrow> tmp15 . assignedNodes(True);
+ tmp17 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp16, [tmp17])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Closed > Open.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_closed_open'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_closed_open'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ assert_equals(tmp3, None, ''A slot in a closed shadow tree should not be accessed via assignedSlot'');
+ tmp4 \<leftarrow> n . ''s1'';
+ tmp5 \<leftarrow> tmp4 . assignedSlot;
+ tmp6 \<leftarrow> n . ''s2'';
+ assert_equals(tmp5, tmp6);
+ tmp7 \<leftarrow> n . ''s1'';
+ tmp8 \<leftarrow> tmp7 . assignedNodes();
+ tmp9 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp8, [tmp9]);
+ tmp10 \<leftarrow> n . ''s2'';
+ tmp11 \<leftarrow> tmp10 . assignedNodes();
+ tmp12 \<leftarrow> n . ''s1'';
+ assert_array_equals(tmp11, [tmp12]);
+ tmp13 \<leftarrow> n . ''s1'';
+ tmp14 \<leftarrow> tmp13 . assignedNodes(True);
+ tmp15 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp14, [tmp15]);
+ tmp16 \<leftarrow> n . ''s2'';
+ tmp17 \<leftarrow> tmp16 . assignedNodes(True);
+ tmp18 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp17, [tmp18])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Complex case: Basi line.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_complex'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ tmp4 \<leftarrow> n . ''s1'';
+ assert_equals(tmp3, tmp4);
+ tmp5 \<leftarrow> n . ''c2'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ tmp7 \<leftarrow> n . ''s2'';
+ assert_equals(tmp6, tmp7);
+ tmp8 \<leftarrow> n . ''c3'';
+ tmp9 \<leftarrow> tmp8 . assignedSlot;
+ tmp10 \<leftarrow> n . ''s3'';
+ assert_equals(tmp9, tmp10);
+ tmp11 \<leftarrow> n . ''c4'';
+ tmp12 \<leftarrow> tmp11 . assignedSlot;
+ assert_equals(tmp12, None);
+ tmp13 \<leftarrow> n . ''s1'';
+ tmp14 \<leftarrow> tmp13 . assignedSlot;
+ tmp15 \<leftarrow> n . ''s5'';
+ assert_equals(tmp14, tmp15);
+ tmp16 \<leftarrow> n . ''s2'';
+ tmp17 \<leftarrow> tmp16 . assignedSlot;
+ tmp18 \<leftarrow> n . ''s6'';
+ assert_equals(tmp17, tmp18);
+ tmp19 \<leftarrow> n . ''s3'';
+ tmp20 \<leftarrow> tmp19 . assignedSlot;
+ tmp21 \<leftarrow> n . ''s7'';
+ assert_equals(tmp20, tmp21);
+ tmp22 \<leftarrow> n . ''s4'';
+ tmp23 \<leftarrow> tmp22 . assignedSlot;
+ assert_equals(tmp23, None);
+ tmp24 \<leftarrow> n . ''c5'';
+ tmp25 \<leftarrow> tmp24 . assignedSlot;
+ tmp26 \<leftarrow> n . ''s5'';
+ assert_equals(tmp25, tmp26);
+ tmp27 \<leftarrow> n . ''c6'';
+ tmp28 \<leftarrow> tmp27 . assignedSlot;
+ tmp29 \<leftarrow> n . ''s6'';
+ assert_equals(tmp28, tmp29);
+ tmp30 \<leftarrow> n . ''c7'';
+ tmp31 \<leftarrow> tmp30 . assignedSlot;
+ tmp32 \<leftarrow> n . ''s7'';
+ assert_equals(tmp31, tmp32);
+ tmp33 \<leftarrow> n . ''c8'';
+ tmp34 \<leftarrow> tmp33 . assignedSlot;
+ assert_equals(tmp34, None);
+ tmp35 \<leftarrow> n . ''s1'';
+ tmp36 \<leftarrow> tmp35 . assignedNodes();
+ tmp37 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp36, [tmp37]);
+ tmp38 \<leftarrow> n . ''s2'';
+ tmp39 \<leftarrow> tmp38 . assignedNodes();
+ tmp40 \<leftarrow> n . ''c2'';
+ assert_array_equals(tmp39, [tmp40]);
+ tmp41 \<leftarrow> n . ''s3'';
+ tmp42 \<leftarrow> tmp41 . assignedNodes();
+ tmp43 \<leftarrow> n . ''c3'';
+ assert_array_equals(tmp42, [tmp43]);
+ tmp44 \<leftarrow> n . ''s4'';
+ tmp45 \<leftarrow> tmp44 . assignedNodes();
+ assert_array_equals(tmp45, []);
+ tmp46 \<leftarrow> n . ''s5'';
+ tmp47 \<leftarrow> tmp46 . assignedNodes();
+ tmp48 \<leftarrow> n . ''s1'';
+ tmp49 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp47, [tmp48, tmp49]);
+ tmp50 \<leftarrow> n . ''s6'';
+ tmp51 \<leftarrow> tmp50 . assignedNodes();
+ tmp52 \<leftarrow> n . ''s2'';
+ tmp53 \<leftarrow> n . ''c6'';
+ assert_array_equals(tmp51, [tmp52, tmp53]);
+ tmp54 \<leftarrow> n . ''s7'';
+ tmp55 \<leftarrow> tmp54 . assignedNodes();
+ tmp56 \<leftarrow> n . ''s3'';
+ tmp57 \<leftarrow> n . ''c7'';
+ assert_array_equals(tmp55, [tmp56, tmp57]);
+ tmp58 \<leftarrow> n . ''s8'';
+ tmp59 \<leftarrow> tmp58 . assignedNodes();
+ assert_array_equals(tmp59, []);
+ tmp60 \<leftarrow> n . ''s1'';
+ tmp61 \<leftarrow> tmp60 . assignedNodes(True);
+ tmp62 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp61, [tmp62]);
+ tmp63 \<leftarrow> n . ''s2'';
+ tmp64 \<leftarrow> tmp63 . assignedNodes(True);
+ tmp65 \<leftarrow> n . ''c2'';
+ assert_array_equals(tmp64, [tmp65]);
+ tmp66 \<leftarrow> n . ''s3'';
+ tmp67 \<leftarrow> tmp66 . assignedNodes(True);
+ tmp68 \<leftarrow> n . ''c3'';
+ assert_array_equals(tmp67, [tmp68]);
+ tmp69 \<leftarrow> n . ''s4'';
+ tmp70 \<leftarrow> tmp69 . assignedNodes(True);
+ assert_array_equals(tmp70, []);
+ tmp71 \<leftarrow> n . ''s5'';
+ tmp72 \<leftarrow> tmp71 . assignedNodes(True);
+ tmp73 \<leftarrow> n . ''c1'';
+ tmp74 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp72, [tmp73, tmp74]);
+ tmp75 \<leftarrow> n . ''s6'';
+ tmp76 \<leftarrow> tmp75 . assignedNodes(True);
+ tmp77 \<leftarrow> n . ''c2'';
+ tmp78 \<leftarrow> n . ''c6'';
+ assert_array_equals(tmp76, [tmp77, tmp78]);
+ tmp79 \<leftarrow> n . ''s7'';
+ tmp80 \<leftarrow> tmp79 . assignedNodes(True);
+ tmp81 \<leftarrow> n . ''c3'';
+ tmp82 \<leftarrow> n . ''c7'';
+ assert_array_equals(tmp80, [tmp81, tmp82]);
+ tmp83 \<leftarrow> n . ''s8'';
+ tmp84 \<leftarrow> tmp83 . assignedNodes(True);
+ assert_array_equals(tmp84, [])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Mutation: appendChild.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_complex'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ d1 \<leftarrow> slots_document . createElement(''div'');
+ d1 . setAttribute(''slot'', ''slot1'');
+ tmp2 \<leftarrow> n . ''host1'';
+ tmp2 . appendChild(d1);
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes();
+ tmp5 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp4, [tmp5, d1]);
+ tmp6 \<leftarrow> d1 . assignedSlot;
+ tmp7 \<leftarrow> n . ''s1'';
+ assert_equals(tmp6, tmp7);
+ tmp8 \<leftarrow> n . ''s5'';
+ tmp9 \<leftarrow> tmp8 . assignedNodes(True);
+ tmp10 \<leftarrow> n . ''c1'';
+ tmp11 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp9, [tmp10, d1, tmp11])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Mutation: Change slot= attribute 1.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_complex'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp2 . setAttribute(''slot'', ''slot-none'');
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes();
+ assert_array_equals(tmp4, []);
+ tmp5 \<leftarrow> n . ''c1'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ assert_equals(tmp6, None);
+ tmp7 \<leftarrow> n . ''s5'';
+ tmp8 \<leftarrow> tmp7 . assignedNodes(True);
+ tmp9 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp8, [tmp9])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Mutation: Change slot= attribute 2.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_complex'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp2 . setAttribute(''slot'', ''slot2'');
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes();
+ assert_array_equals(tmp4, []);
+ tmp5 \<leftarrow> n . ''s2'';
+ tmp6 \<leftarrow> tmp5 . assignedNodes();
+ tmp7 \<leftarrow> n . ''c1'';
+ tmp8 \<leftarrow> n . ''c2'';
+ assert_array_equals(tmp6, [tmp7, tmp8]);
+ tmp9 \<leftarrow> n . ''c1'';
+ tmp10 \<leftarrow> tmp9 . assignedSlot;
+ tmp11 \<leftarrow> n . ''s2'';
+ assert_equals(tmp10, tmp11);
+ tmp12 \<leftarrow> n . ''s5'';
+ tmp13 \<leftarrow> tmp12 . assignedNodes(True);
+ tmp14 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp13, [tmp14]);
+ tmp15 \<leftarrow> n . ''s6'';
+ tmp16 \<leftarrow> tmp15 . assignedNodes(True);
+ tmp17 \<leftarrow> n . ''c1'';
+ tmp18 \<leftarrow> n . ''c2'';
+ tmp19 \<leftarrow> n . ''c6'';
+ assert_array_equals(tmp16, [tmp17, tmp18, tmp19])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Mutation: Change slot= attribute 3.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_complex'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c4'';
+ tmp2 . setAttribute(''slot'', ''slot1'');
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes();
+ tmp5 \<leftarrow> n . ''c1'';
+ tmp6 \<leftarrow> n . ''c4'';
+ assert_array_equals(tmp4, [tmp5, tmp6]);
+ tmp7 \<leftarrow> n . ''c4'';
+ tmp8 \<leftarrow> tmp7 . assignedSlot;
+ tmp9 \<leftarrow> n . ''s1'';
+ assert_equals(tmp8, tmp9);
+ tmp10 \<leftarrow> n . ''s5'';
+ tmp11 \<leftarrow> tmp10 . assignedNodes(True);
+ tmp12 \<leftarrow> n . ''c1'';
+ tmp13 \<leftarrow> n . ''c4'';
+ tmp14 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp11, [tmp12, tmp13, tmp14])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Mutation: Remove a child.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_complex'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp2 . remove();
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes();
+ assert_array_equals(tmp4, []);
+ tmp5 \<leftarrow> n . ''c1'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ assert_equals(tmp6, None);
+ tmp7 \<leftarrow> n . ''s5'';
+ tmp8 \<leftarrow> tmp7 . assignedNodes(True);
+ tmp9 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp8, [tmp9])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Mutation: Add a slot: after.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_complex'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ slot \<leftarrow> slots_document . createElement(''slot'');
+ slot . setAttribute(''name'', ''slot1'');
+ tmp2 \<leftarrow> n . ''host2'';
+ tmp2 . appendChild(slot);
+ tmp3 \<leftarrow> slot . assignedNodes();
+ assert_array_equals(tmp3, [])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Mutation: Add a slot: before.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_complex'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ slot \<leftarrow> slots_document . createElement(''slot'');
+ slot . setAttribute(''name'', ''slot1'');
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp2 \<leftarrow> n . ''host2'';
+ tmp2 . insertBefore(slot, tmp3);
+ tmp4 \<leftarrow> slot . assignedNodes();
+ tmp5 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp4, [tmp5]);
+ tmp6 \<leftarrow> n . ''c1'';
+ tmp7 \<leftarrow> tmp6 . assignedSlot;
+ assert_equals(tmp7, slot);
+ tmp8 \<leftarrow> n . ''s7'';
+ tmp9 \<leftarrow> tmp8 . assignedNodes();
+ tmp10 \<leftarrow> n . ''s3'';
+ tmp11 \<leftarrow> n . ''c7'';
+ assert_array_equals(tmp9, [slot, tmp10, tmp11]);
+ tmp12 \<leftarrow> n . ''s7'';
+ tmp13 \<leftarrow> tmp12 . assignedNodes(True);
+ tmp14 \<leftarrow> n . ''c1'';
+ tmp15 \<leftarrow> n . ''c3'';
+ tmp16 \<leftarrow> n . ''c7'';
+ assert_array_equals(tmp13, [tmp14, tmp15, tmp16])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Mutation: Remove a slot.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_complex'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''s1'';
+ tmp2 . remove();
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes();
+ assert_array_equals(tmp4, []);
+ tmp5 \<leftarrow> n . ''c1'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ assert_equals(tmp6, None);
+ tmp7 \<leftarrow> n . ''s5'';
+ tmp8 \<leftarrow> tmp7 . assignedNodes();
+ tmp9 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp8, [tmp9]);
+ tmp10 \<leftarrow> n . ''s5'';
+ tmp11 \<leftarrow> tmp10 . assignedNodes(True);
+ tmp12 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp11, [tmp12])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Mutation: Change slot name= attribute.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_complex'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''s1'';
+ tmp2 . setAttribute(''name'', ''slot2'');
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes();
+ tmp5 \<leftarrow> n . ''c2'';
+ assert_array_equals(tmp4, [tmp5]);
+ tmp6 \<leftarrow> n . ''c1'';
+ tmp7 \<leftarrow> tmp6 . assignedSlot;
+ assert_equals(tmp7, None);
+ tmp8 \<leftarrow> n . ''c2'';
+ tmp9 \<leftarrow> tmp8 . assignedSlot;
+ tmp10 \<leftarrow> n . ''s1'';
+ assert_equals(tmp9, tmp10);
+ tmp11 \<leftarrow> n . ''s5'';
+ tmp12 \<leftarrow> tmp11 . assignedNodes();
+ tmp13 \<leftarrow> n . ''s1'';
+ tmp14 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp12, [tmp13, tmp14]);
+ tmp15 \<leftarrow> n . ''s5'';
+ tmp16 \<leftarrow> tmp15 . assignedNodes(True);
+ tmp17 \<leftarrow> n . ''c2'';
+ tmp18 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp16, [tmp17, tmp18])
+}) slots_heap"
+ by eval
+
+
+text \<open>'Slots: Mutation: Change slot slot= attribute.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_document . getElementById(''test_complex'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test_complex'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''s1'';
+ tmp2 . setAttribute(''slot'', ''slot6'');
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes();
+ tmp5 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp4, [tmp5]);
+ tmp6 \<leftarrow> n . ''s5'';
+ tmp7 \<leftarrow> tmp6 . assignedNodes();
+ tmp8 \<leftarrow> n . ''c5'';
+ assert_array_equals(tmp7, [tmp8]);
+ tmp9 \<leftarrow> n . ''s6'';
+ tmp10 \<leftarrow> tmp9 . assignedNodes();
+ tmp11 \<leftarrow> n . ''s1'';
+ tmp12 \<leftarrow> n . ''s2'';
+ tmp13 \<leftarrow> n . ''c6'';
+ assert_array_equals(tmp10, [tmp11, tmp12, tmp13]);
+ tmp14 \<leftarrow> n . ''s6'';
+ tmp15 \<leftarrow> tmp14 . assignedNodes(True);
+ tmp16 \<leftarrow> n . ''c1'';
+ tmp17 \<leftarrow> n . ''c2'';
+ tmp18 \<leftarrow> n . ''c6'';
+ assert_array_equals(tmp15, [tmp16, tmp17, tmp18])
+}) slots_heap"
+ by eval
+
+
+end
diff --git a/thys/Shadow_SC_DOM/tests/slots_fallback.thy b/thys/Shadow_SC_DOM/tests/slots_fallback.thy
new file mode 100644
--- /dev/null
+++ b/thys/Shadow_SC_DOM/tests/slots_fallback.thy
@@ -0,0 +1,507 @@
+(***********************************************************************************
+ * Copyright (c) 2016-2020 The University of Sheffield, UK
+ * 2019-2020 University of Exeter, UK
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ ***********************************************************************************)
+
+(* This file is automatically generated, please do not modify! *)
+
+section\<open>Testing slots\_fallback\<close>
+text\<open>This theory contains the test cases for slots\_fallback.\<close>
+
+theory slots_fallback
+imports
+ "Shadow_DOM_BaseTest"
+begin
+
+definition slots_fallback_heap :: "heap\<^sub>f\<^sub>i\<^sub>n\<^sub>a\<^sub>l" where
+ "slots_fallback_heap = create_heap [(cast (document_ptr.Ref 1), cast (create_document_obj html (Some (cast (element_ptr.Ref 1))) [])),
+ (cast (element_ptr.Ref 1), cast (create_element_obj ''html'' [cast (element_ptr.Ref 2), cast (element_ptr.Ref 8)] fmempty None)),
+ (cast (element_ptr.Ref 2), cast (create_element_obj ''head'' [cast (element_ptr.Ref 3), cast (element_ptr.Ref 4), cast (element_ptr.Ref 5), cast (element_ptr.Ref 6), cast (element_ptr.Ref 7)] fmempty None)),
+ (cast (element_ptr.Ref 3), cast (create_element_obj ''title'' [cast (character_data_ptr.Ref 1)] fmempty None)),
+ (cast (character_data_ptr.Ref 1), cast (create_character_data_obj ''Shadow%20DOM%3A%20Slots%20and%20fallback%20contents'')),
+ (cast (element_ptr.Ref 4), cast (create_element_obj ''meta'' [] (fmap_of_list [(''name'', ''author''), (''title'', ''Hayato Ito''), (''href'', ''mailto:hayato@google.com'')]) None)),
+ (cast (element_ptr.Ref 5), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharness.js'')]) None)),
+ (cast (element_ptr.Ref 6), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''/resources/testharnessreport.js'')]) None)),
+ (cast (element_ptr.Ref 7), cast (create_element_obj ''script'' [] (fmap_of_list [(''src'', ''resources/shadow-dom.js'')]) None)),
+ (cast (element_ptr.Ref 8), cast (create_element_obj ''body'' [cast (element_ptr.Ref 9), cast (element_ptr.Ref 13), cast (element_ptr.Ref 14), cast (element_ptr.Ref 19), cast (element_ptr.Ref 20), cast (element_ptr.Ref 26), cast (element_ptr.Ref 27), cast (element_ptr.Ref 33), cast (element_ptr.Ref 34), cast (element_ptr.Ref 46)] fmempty None)),
+ (cast (element_ptr.Ref 9), cast (create_element_obj ''div'' [cast (element_ptr.Ref 10)] (fmap_of_list [(''id'', ''test1'')]) None)),
+ (cast (element_ptr.Ref 10), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 1))))),
+ (cast (shadow_root_ptr.Ref 1), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 11)])),
+ (cast (element_ptr.Ref 11), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 12)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 12), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f1'')]) None)),
+ (cast (element_ptr.Ref 13), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 2)] fmempty None)),
+ (cast (character_data_ptr.Ref 2), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 14), cast (create_element_obj ''div'' [cast (element_ptr.Ref 15)] (fmap_of_list [(''id'', ''test2'')]) None)),
+ (cast (element_ptr.Ref 15), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 2))))),
+ (cast (shadow_root_ptr.Ref 2), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 16)])),
+ (cast (element_ptr.Ref 16), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 17)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 17), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 18)] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 18), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f1'')]) None)),
+ (cast (element_ptr.Ref 19), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 3)] fmempty None)),
+ (cast (character_data_ptr.Ref 3), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 20), cast (create_element_obj ''div'' [cast (element_ptr.Ref 21)] (fmap_of_list [(''id'', ''test3'')]) None)),
+ (cast (element_ptr.Ref 21), cast (create_element_obj ''div'' [cast (element_ptr.Ref 22)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 3))))),
+ (cast (element_ptr.Ref 22), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (shadow_root_ptr.Ref 3), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 23)])),
+ (cast (element_ptr.Ref 23), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 24)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 24), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 25)] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 25), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f1'')]) None)),
+ (cast (element_ptr.Ref 26), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 4)] fmempty None)),
+ (cast (character_data_ptr.Ref 4), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 27), cast (create_element_obj ''div'' [cast (element_ptr.Ref 28)] (fmap_of_list [(''id'', ''test4'')]) None)),
+ (cast (element_ptr.Ref 28), cast (create_element_obj ''div'' [cast (element_ptr.Ref 29)] (fmap_of_list [(''id'', ''host'')]) (Some (cast (shadow_root_ptr.Ref 4))))),
+ (cast (element_ptr.Ref 29), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot2'')]) None)),
+ (cast (shadow_root_ptr.Ref 4), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 30)])),
+ (cast (element_ptr.Ref 30), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 31)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 31), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 32)] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2'')]) None)),
+ (cast (element_ptr.Ref 32), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f1'')]) None)),
+ (cast (element_ptr.Ref 33), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 5)] fmempty None)),
+ (cast (character_data_ptr.Ref 5), cast (create_character_data_obj ''%3C%3Cscript%3E%3E'')),
+ (cast (element_ptr.Ref 34), cast (create_element_obj ''div'' [cast (element_ptr.Ref 35)] (fmap_of_list [(''id'', ''test5'')]) None)),
+ (cast (element_ptr.Ref 35), cast (create_element_obj ''div'' [cast (element_ptr.Ref 36)] (fmap_of_list [(''id'', ''host1'')]) (Some (cast (shadow_root_ptr.Ref 5))))),
+ (cast (element_ptr.Ref 36), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''c1''), (''slot'', ''slot1'')]) None)),
+ (cast (shadow_root_ptr.Ref 5), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 37)])),
+ (cast (element_ptr.Ref 37), cast (create_element_obj ''div'' [cast (element_ptr.Ref 38)] (fmap_of_list [(''id'', ''host2'')]) (Some (cast (shadow_root_ptr.Ref 6))))),
+ (cast (element_ptr.Ref 38), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 39), cast (element_ptr.Ref 41)] (fmap_of_list [(''id'', ''s2''), (''name'', ''slot2''), (''slot'', ''slot3'')]) None)),
+ (cast (element_ptr.Ref 39), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 40)] (fmap_of_list [(''id'', ''s1''), (''name'', ''slot1'')]) None)),
+ (cast (element_ptr.Ref 40), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f1'')]) None)),
+ (cast (element_ptr.Ref 41), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f2'')]) None)),
+ (cast (shadow_root_ptr.Ref 6), cast (create_shadow_root_obj Open [cast (element_ptr.Ref 42)])),
+ (cast (element_ptr.Ref 42), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 43), cast (element_ptr.Ref 45)] (fmap_of_list [(''id'', ''s4''), (''name'', ''slot4'')]) None)),
+ (cast (element_ptr.Ref 43), cast (create_element_obj ''slot'' [cast (element_ptr.Ref 44)] (fmap_of_list [(''id'', ''s3''), (''name'', ''slot3'')]) None)),
+ (cast (element_ptr.Ref 44), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f3'')]) None)),
+ (cast (element_ptr.Ref 45), cast (create_element_obj ''div'' [] (fmap_of_list [(''id'', ''f4'')]) None)),
+ (cast (element_ptr.Ref 46), cast (create_element_obj ''script'' [cast (character_data_ptr.Ref 6)] fmempty None)),
+ (cast (character_data_ptr.Ref 6), cast (create_character_data_obj ''%3C%3Cscript%3E%3E''))]"
+
+definition slots_fallback_document :: "(unit, unit, unit, unit, unit, unit) object_ptr option" where "slots_fallback_document = Some (cast (document_ptr.Ref 1))"
+
+
+text \<open>'Slots fallback: Basic.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test1'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test1'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''f1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ assert_equals(tmp3, None);
+ tmp4 \<leftarrow> n . ''s1'';
+ tmp5 \<leftarrow> tmp4 . assignedNodes();
+ assert_array_equals(tmp5, []);
+ tmp6 \<leftarrow> n . ''s1'';
+ tmp7 \<leftarrow> tmp6 . assignedNodes(True);
+ tmp8 \<leftarrow> n . ''f1'';
+ assert_array_equals(tmp7, [tmp8])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Basic, elements only.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test1'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''s1'';
+ tmp2 \<leftarrow> tmp1 . assignedElements();
+ assert_array_equals(tmp2, []);
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedElements(True);
+ tmp5 \<leftarrow> n . ''f1'';
+ assert_array_equals(tmp4, [tmp5])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Slots in Slots.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test2'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test2'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''f1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ assert_equals(tmp3, None);
+ tmp4 \<leftarrow> n . ''s1'';
+ tmp5 \<leftarrow> tmp4 . assignedNodes();
+ assert_array_equals(tmp5, []);
+ tmp6 \<leftarrow> n . ''s2'';
+ tmp7 \<leftarrow> tmp6 . assignedNodes();
+ assert_array_equals(tmp7, []);
+ tmp8 \<leftarrow> n . ''s1'';
+ tmp9 \<leftarrow> tmp8 . assignedNodes(True);
+ tmp10 \<leftarrow> n . ''f1'';
+ assert_array_equals(tmp9, [tmp10]);
+ tmp11 \<leftarrow> n . ''s2'';
+ tmp12 \<leftarrow> tmp11 . assignedNodes(True);
+ tmp13 \<leftarrow> n . ''f1'';
+ assert_array_equals(tmp12, [tmp13])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Slots in Slots, elements only.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test2'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''s1'';
+ tmp2 \<leftarrow> tmp1 . assignedElements();
+ assert_array_equals(tmp2, []);
+ tmp3 \<leftarrow> n . ''s2'';
+ tmp4 \<leftarrow> tmp3 . assignedElements();
+ assert_array_equals(tmp4, []);
+ tmp5 \<leftarrow> n . ''s1'';
+ tmp6 \<leftarrow> tmp5 . assignedElements(True);
+ tmp7 \<leftarrow> n . ''f1'';
+ assert_array_equals(tmp6, [tmp7]);
+ tmp8 \<leftarrow> n . ''s2'';
+ tmp9 \<leftarrow> tmp8 . assignedElements(True);
+ tmp10 \<leftarrow> n . ''f1'';
+ assert_array_equals(tmp9, [tmp10])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Fallback contents should not be used if a node is assigned.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test3'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test3'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ tmp4 \<leftarrow> n . ''s1'';
+ assert_equals(tmp3, tmp4);
+ tmp5 \<leftarrow> n . ''f1'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ assert_equals(tmp6, None);
+ tmp7 \<leftarrow> n . ''s1'';
+ tmp8 \<leftarrow> tmp7 . assignedNodes();
+ tmp9 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp8, [tmp9]);
+ tmp10 \<leftarrow> n . ''s2'';
+ tmp11 \<leftarrow> tmp10 . assignedNodes();
+ assert_array_equals(tmp11, []);
+ tmp12 \<leftarrow> n . ''s1'';
+ tmp13 \<leftarrow> tmp12 . assignedNodes(True);
+ tmp14 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp13, [tmp14]);
+ tmp15 \<leftarrow> n . ''s2'';
+ tmp16 \<leftarrow> tmp15 . assignedNodes(True);
+ tmp17 \<leftarrow> n . ''f1'';
+ assert_array_equals(tmp16, [tmp17])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Slots in Slots: Assigned nodes should be used as fallback contents of another slot'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test4'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test4'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp3 \<leftarrow> tmp2 . assignedSlot;
+ tmp4 \<leftarrow> n . ''s2'';
+ assert_equals(tmp3, tmp4);
+ tmp5 \<leftarrow> n . ''f1'';
+ tmp6 \<leftarrow> tmp5 . assignedSlot;
+ assert_equals(tmp6, None);
+ tmp7 \<leftarrow> n . ''s1'';
+ tmp8 \<leftarrow> tmp7 . assignedNodes();
+ assert_array_equals(tmp8, []);
+ tmp9 \<leftarrow> n . ''s2'';
+ tmp10 \<leftarrow> tmp9 . assignedNodes();
+ tmp11 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp10, [tmp11]);
+ tmp12 \<leftarrow> n . ''s1'';
+ tmp13 \<leftarrow> tmp12 . assignedNodes(True);
+ tmp14 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp13, [tmp14]);
+ tmp15 \<leftarrow> n . ''s2'';
+ tmp16 \<leftarrow> tmp15 . assignedNodes(True);
+ tmp17 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp16, [tmp17])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Complex case.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test5'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''s1'';
+ tmp3 \<leftarrow> tmp2 . assignedNodes();
+ tmp4 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp3, [tmp4]);
+ tmp5 \<leftarrow> n . ''s2'';
+ tmp6 \<leftarrow> tmp5 . assignedNodes();
+ assert_array_equals(tmp6, []);
+ tmp7 \<leftarrow> n . ''s3'';
+ tmp8 \<leftarrow> tmp7 . assignedNodes();
+ tmp9 \<leftarrow> n . ''s2'';
+ assert_array_equals(tmp8, [tmp9]);
+ tmp10 \<leftarrow> n . ''s4'';
+ tmp11 \<leftarrow> tmp10 . assignedNodes();
+ assert_array_equals(tmp11, []);
+ tmp12 \<leftarrow> n . ''s1'';
+ tmp13 \<leftarrow> tmp12 . assignedNodes(True);
+ tmp14 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp13, [tmp14]);
+ tmp15 \<leftarrow> n . ''s2'';
+ tmp16 \<leftarrow> tmp15 . assignedNodes(True);
+ tmp17 \<leftarrow> n . ''c1'';
+ tmp18 \<leftarrow> n . ''f2'';
+ assert_array_equals(tmp16, [tmp17, tmp18]);
+ tmp19 \<leftarrow> n . ''s3'';
+ tmp20 \<leftarrow> tmp19 . assignedNodes(True);
+ tmp21 \<leftarrow> n . ''c1'';
+ tmp22 \<leftarrow> n . ''f2'';
+ assert_array_equals(tmp20, [tmp21, tmp22]);
+ tmp23 \<leftarrow> n . ''s4'';
+ tmp24 \<leftarrow> tmp23 . assignedNodes(True);
+ tmp25 \<leftarrow> n . ''c1'';
+ tmp26 \<leftarrow> n . ''f2'';
+ tmp27 \<leftarrow> n . ''f4'';
+ assert_array_equals(tmp24, [tmp25, tmp26, tmp27])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Complex case, elements only.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''s1'';
+ tmp2 \<leftarrow> tmp1 . assignedElements();
+ tmp3 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp2, [tmp3]);
+ tmp4 \<leftarrow> n . ''s2'';
+ tmp5 \<leftarrow> tmp4 . assignedElements();
+ assert_array_equals(tmp5, []);
+ tmp6 \<leftarrow> n . ''s3'';
+ tmp7 \<leftarrow> tmp6 . assignedElements();
+ tmp8 \<leftarrow> n . ''s2'';
+ assert_array_equals(tmp7, [tmp8]);
+ tmp9 \<leftarrow> n . ''s4'';
+ tmp10 \<leftarrow> tmp9 . assignedElements();
+ assert_array_equals(tmp10, []);
+ tmp11 \<leftarrow> n . ''s1'';
+ tmp12 \<leftarrow> tmp11 . assignedElements(True);
+ tmp13 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp12, [tmp13]);
+ tmp14 \<leftarrow> n . ''s2'';
+ tmp15 \<leftarrow> tmp14 . assignedElements(True);
+ tmp16 \<leftarrow> n . ''c1'';
+ tmp17 \<leftarrow> n . ''f2'';
+ assert_array_equals(tmp15, [tmp16, tmp17]);
+ tmp18 \<leftarrow> n . ''s3'';
+ tmp19 \<leftarrow> tmp18 . assignedElements(True);
+ tmp20 \<leftarrow> n . ''c1'';
+ tmp21 \<leftarrow> n . ''f2'';
+ assert_array_equals(tmp19, [tmp20, tmp21]);
+ tmp22 \<leftarrow> n . ''s4'';
+ tmp23 \<leftarrow> tmp22 . assignedElements(True);
+ tmp24 \<leftarrow> n . ''c1'';
+ tmp25 \<leftarrow> n . ''f2'';
+ tmp26 \<leftarrow> n . ''f4'';
+ assert_array_equals(tmp23, [tmp24, tmp25, tmp26])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Mutation. Append fallback contents.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test5'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ d1 \<leftarrow> slots_fallback_document . createElement(''div'');
+ tmp2 \<leftarrow> n . ''s2'';
+ tmp2 . appendChild(d1);
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes(True);
+ tmp5 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp4, [tmp5]);
+ tmp6 \<leftarrow> n . ''s2'';
+ tmp7 \<leftarrow> tmp6 . assignedNodes(True);
+ tmp8 \<leftarrow> n . ''c1'';
+ tmp9 \<leftarrow> n . ''f2'';
+ assert_array_equals(tmp7, [tmp8, tmp9, d1]);
+ tmp10 \<leftarrow> n . ''s3'';
+ tmp11 \<leftarrow> tmp10 . assignedNodes(True);
+ tmp12 \<leftarrow> n . ''c1'';
+ tmp13 \<leftarrow> n . ''f2'';
+ assert_array_equals(tmp11, [tmp12, tmp13, d1]);
+ tmp14 \<leftarrow> n . ''s4'';
+ tmp15 \<leftarrow> tmp14 . assignedNodes(True);
+ tmp16 \<leftarrow> n . ''c1'';
+ tmp17 \<leftarrow> n . ''f2'';
+ tmp18 \<leftarrow> n . ''f4'';
+ assert_array_equals(tmp15, [tmp16, tmp17, d1, tmp18])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Mutation. Remove fallback contents.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test5'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''f2'';
+ tmp2 . remove();
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes(True);
+ tmp5 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp4, [tmp5]);
+ tmp6 \<leftarrow> n . ''s2'';
+ tmp7 \<leftarrow> tmp6 . assignedNodes(True);
+ tmp8 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp7, [tmp8]);
+ tmp9 \<leftarrow> n . ''s3'';
+ tmp10 \<leftarrow> tmp9 . assignedNodes(True);
+ tmp11 \<leftarrow> n . ''c1'';
+ assert_array_equals(tmp10, [tmp11]);
+ tmp12 \<leftarrow> n . ''s4'';
+ tmp13 \<leftarrow> tmp12 . assignedNodes(True);
+ tmp14 \<leftarrow> n . ''c1'';
+ tmp15 \<leftarrow> n . ''f4'';
+ assert_array_equals(tmp13, [tmp14, tmp15])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Mutation. Assign a node to a slot so that fallback contens are no longer used.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test5'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ d2 \<leftarrow> slots_fallback_document . createElement(''div'');
+ d2 . setAttribute(''slot'', ''slot2'');
+ tmp2 \<leftarrow> n . ''host1'';
+ tmp2 . appendChild(d2);
+ tmp3 \<leftarrow> n . ''s2'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes();
+ assert_array_equals(tmp4, [d2]);
+ tmp5 \<leftarrow> n . ''s2'';
+ tmp6 \<leftarrow> tmp5 . assignedNodes(True);
+ assert_array_equals(tmp6, [d2]);
+ tmp7 \<leftarrow> n . ''s3'';
+ tmp8 \<leftarrow> tmp7 . assignedNodes(True);
+ assert_array_equals(tmp8, [d2]);
+ tmp9 \<leftarrow> n . ''s4'';
+ tmp10 \<leftarrow> tmp9 . assignedNodes(True);
+ tmp11 \<leftarrow> n . ''f4'';
+ assert_array_equals(tmp10, [d2, tmp11])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Mutation. Remove an assigned node from a slot so that fallback contens will be used.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test5'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''c1'';
+ tmp2 . remove();
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes();
+ assert_array_equals(tmp4, []);
+ tmp5 \<leftarrow> n . ''s1'';
+ tmp6 \<leftarrow> tmp5 . assignedNodes(True);
+ tmp7 \<leftarrow> n . ''f1'';
+ assert_array_equals(tmp6, [tmp7]);
+ tmp8 \<leftarrow> n . ''s2'';
+ tmp9 \<leftarrow> tmp8 . assignedNodes(True);
+ tmp10 \<leftarrow> n . ''f1'';
+ tmp11 \<leftarrow> n . ''f2'';
+ assert_array_equals(tmp9, [tmp10, tmp11]);
+ tmp12 \<leftarrow> n . ''s3'';
+ tmp13 \<leftarrow> tmp12 . assignedNodes(True);
+ tmp14 \<leftarrow> n . ''f1'';
+ tmp15 \<leftarrow> n . ''f2'';
+ assert_array_equals(tmp13, [tmp14, tmp15]);
+ tmp16 \<leftarrow> n . ''s4'';
+ tmp17 \<leftarrow> tmp16 . assignedNodes(True);
+ tmp18 \<leftarrow> n . ''f1'';
+ tmp19 \<leftarrow> n . ''f2'';
+ tmp20 \<leftarrow> n . ''f4'';
+ assert_array_equals(tmp17, [tmp18, tmp19, tmp20])
+}) slots_fallback_heap"
+ by eval
+
+
+text \<open>'Slots fallback: Mutation. Remove a slot which is a fallback content of another slot.'\<close>
+
+lemma "test (do {
+ tmp0 \<leftarrow> slots_fallback_document . getElementById(''test5'');
+ n \<leftarrow> createTestTree(tmp0);
+ tmp1 \<leftarrow> n . ''test5'';
+ removeWhiteSpaceOnlyTextNodes(tmp1);
+ tmp2 \<leftarrow> n . ''s1'';
+ tmp2 . remove();
+ tmp3 \<leftarrow> n . ''s1'';
+ tmp4 \<leftarrow> tmp3 . assignedNodes();
+ assert_array_equals(tmp4, []);
+ tmp5 \<leftarrow> n . ''s1'';
+ tmp6 \<leftarrow> tmp5 . assignedNodes(True);
+ assert_array_equals(tmp6, [], ''fall back contents should be empty because s1 is not in a shadow tree.'');
+ tmp7 \<leftarrow> n . ''s2'';
+ tmp8 \<leftarrow> tmp7 . assignedNodes(True);
+ tmp9 \<leftarrow> n . ''f2'';
+ assert_array_equals(tmp8, [tmp9]);
+ tmp10 \<leftarrow> n . ''s3'';
+ tmp11 \<leftarrow> tmp10 . assignedNodes(True);
+ tmp12 \<leftarrow> n . ''f2'';
+ assert_array_equals(tmp11, [tmp12]);
+ tmp13 \<leftarrow> n . ''s4'';
+ tmp14 \<leftarrow> tmp13 . assignedNodes(True);
+ tmp15 \<leftarrow> n . ''f2'';
+ tmp16 \<leftarrow> n . ''f4'';
+ assert_array_equals(tmp14, [tmp15, tmp16])
+}) slots_fallback_heap"
+ by eval
+
+
+end
diff --git a/thys/Verified_SAT_Based_AI_Planning/AST_SAS_Plus_Equivalence.thy b/thys/Verified_SAT_Based_AI_Planning/AST_SAS_Plus_Equivalence.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/AST_SAS_Plus_Equivalence.thy
@@ -0,0 +1,967 @@
+(*
+ Author: Mohammad Abdulaziz
+*)
+theory AST_SAS_Plus_Equivalence
+ imports "AI_Planning_Languages_Semantics.SASP_Semantics" "SAS_Plus_Semantics" "List-Index.List_Index"
+begin
+
+section \<open>Proving Equivalence of SAS+ representation and Fast-Downward's Multi-Valued Problem
+ Representation\<close>
+
+subsection \<open>Translating Fast-Downward's represnetation to SAS+\<close>
+
+
+type_synonym nat_sas_plus_problem = "(nat, nat) sas_plus_problem"
+type_synonym nat_sas_plus_operator = "(nat, nat) sas_plus_operator"
+type_synonym nat_sas_plus_plan = "(nat, nat) sas_plus_plan"
+type_synonym nat_sas_plus_state = "(nat, nat) state"
+
+
+definition is_standard_effect :: "ast_effect \<Rightarrow> bool"
+ where "is_standard_effect \<equiv> \<lambda>(pre, _, _, _). pre = []"
+
+definition is_standard_operator :: "ast_operator \<Rightarrow> bool"
+ where "is_standard_operator \<equiv> \<lambda>(_, _, effects, _). list_all is_standard_effect effects"
+
+fun rem_effect_implicit_pres:: "ast_effect \<Rightarrow> ast_effect" where
+ "rem_effect_implicit_pres (preconds, v, implicit_pre, eff) = (preconds, v, None, eff)"
+
+fun rem_implicit_pres :: "ast_operator \<Rightarrow> ast_operator" where
+ "rem_implicit_pres (name, preconds, effects, cost) =
+ (name, (implicit_pres effects) @ preconds, map rem_effect_implicit_pres effects, cost)"
+
+fun rem_implicit_pres_ops :: "ast_problem \<Rightarrow> ast_problem" where
+ "rem_implicit_pres_ops (vars, init, goal, ops) = (vars, init, goal, map rem_implicit_pres ops)"
+
+definition "consistent_map_lists xs1 xs2 \<equiv> (\<forall>(x1,x2) \<in> set xs1. \<forall>(y1,y2)\<in> set xs2. x1 = y1 \<longrightarrow> x1 = y2)"
+
+lemma map_add_comm: "(\<And>x. x \<in> dom m1 \<and> x \<in> dom m2 \<Longrightarrow> m1 x = m2 x) \<Longrightarrow> m1 ++ m2 = m2 ++ m1"
+ by (fastforce simp add: map_add_def split: option.splits)
+
+lemma first_map_add_submap: "(\<And>x. x \<in> dom m1 \<and> x \<in> dom m2 \<Longrightarrow> m1 x = m2 x) \<Longrightarrow>
+ m1 ++ m2 \<subseteq>\<^sub>m x \<Longrightarrow> m1 \<subseteq>\<^sub>m x"
+ using map_add_le_mapE map_add_comm
+ by force
+
+lemma subsuming_states_map_add:
+ "(\<And>x. x \<in> dom m1 \<inter> dom m2 \<Longrightarrow> m1 x = m2 x) \<Longrightarrow>
+ m1 ++ m2 \<subseteq>\<^sub>m s \<longleftrightarrow> (m1 \<subseteq>\<^sub>m s \<and> m2 \<subseteq>\<^sub>m s)"
+ by(auto simp: map_add_le_mapI intro: first_map_add_submap map_add_le_mapE)
+
+lemma consistent_map_lists:
+ "\<lbrakk>distinct (map fst (xs1 @ xs2)); x \<in> dom (map_of xs1) \<inter> dom (map_of xs2)\<rbrakk> \<Longrightarrow>
+ (map_of xs1) x = (map_of xs2) x"
+ apply(induction xs1)
+ apply (simp_all add: consistent_map_lists_def image_def)
+ using map_of_SomeD
+ by fastforce
+
+lemma subsuming_states_append:
+ "distinct (map fst (xs @ ys)) \<Longrightarrow>
+ (map_of (xs @ ys)) \<subseteq>\<^sub>m s \<longleftrightarrow> ((map_of ys) \<subseteq>\<^sub>m s \<and> (map_of xs) \<subseteq>\<^sub>m s)"
+ unfolding map_of_append
+ apply(intro subsuming_states_map_add)
+ apply (auto simp add: image_def)
+ by (metis (mono_tags, lifting) IntI empty_iff fst_conv mem_Collect_eq)
+
+definition consistent_pres_op where
+ "consistent_pres_op op \<equiv> (case op of (name, pres, effs, cost) \<Rightarrow>
+ distinct (map fst (pres @ (implicit_pres effs)))
+ \<and> consistent_map_lists pres (implicit_pres effs))"
+
+definition consistent_pres_op' where
+ "consistent_pres_op' op \<equiv> (case op of (name, pres, effs, cost) \<Rightarrow>
+ consistent_map_lists pres (implicit_pres effs))"
+
+lemma consistent_pres_op_then': "consistent_pres_op op \<Longrightarrow> consistent_pres_op' op"
+ by(auto simp add: consistent_pres_op'_def consistent_pres_op_def)
+
+lemma rem_implicit_pres_ops_valid_states:
+ "ast_problem.valid_states (rem_implicit_pres_ops prob) = ast_problem.valid_states prob"
+ apply(cases prob)
+ by(auto simp add: ast_problem.valid_states_def ast_problem.Dom_def
+ ast_problem.numVars_def ast_problem.astDom_def
+ ast_problem.range_of_var_def ast_problem.numVals_def)
+
+lemma rem_implicit_pres_ops_lookup_op_None:
+ "ast_problem.lookup_operator (vars, init, goal, ops) name = None \<longleftrightarrow>
+ ast_problem.lookup_operator (rem_implicit_pres_ops (vars, init, goal, ops)) name = None"
+ by (induction ops) (auto simp: ast_problem.lookup_operator_def ast_problem.ast\<delta>_def)
+
+lemma rem_implicit_pres_ops_lookup_op_Some_1:
+ "ast_problem.lookup_operator (vars, init, goal, ops) name = Some (n,p,vp,e) \<Longrightarrow>
+ ast_problem.lookup_operator (rem_implicit_pres_ops (vars, init, goal, ops)) name =
+ Some (rem_implicit_pres (n,p,vp,e))"
+ by (induction ops) (fastforce simp: ast_problem.lookup_operator_def ast_problem.ast\<delta>_def)+
+
+lemma rem_implicit_pres_ops_lookup_op_Some_1':
+ "ast_problem.lookup_operator prob name = Some (n,p,vp,e) \<Longrightarrow>
+ ast_problem.lookup_operator (rem_implicit_pres_ops prob) name =
+ Some (rem_implicit_pres (n,p,vp,e))"
+ apply(cases prob)
+ using rem_implicit_pres_ops_lookup_op_Some_1
+ by simp
+
+lemma implicit_pres_empty: "implicit_pres (map rem_effect_implicit_pres effs) = []"
+ by (induction effs) (auto simp: implicit_pres_def)
+
+lemma rem_implicit_pres_ops_lookup_op_Some_2:
+ "ast_problem.lookup_operator (rem_implicit_pres_ops (vars, init, goal, ops)) name = Some op
+ \<Longrightarrow> \<exists>op'. ast_problem.lookup_operator (vars, init, goal, ops) name = Some op' \<and>
+ (op = rem_implicit_pres op')"
+ by (induction ops) (auto simp: ast_problem.lookup_operator_def ast_problem.ast\<delta>_def implicit_pres_empty image_def)
+
+lemma rem_implicit_pres_ops_lookup_op_Some_2':
+ "ast_problem.lookup_operator (rem_implicit_pres_ops prob) name = Some (n,p,e,c)
+ \<Longrightarrow> \<exists>op'. ast_problem.lookup_operator prob name = Some op' \<and>
+ ((n,p,e,c) = rem_implicit_pres op')"
+ apply(cases prob)
+ using rem_implicit_pres_ops_lookup_op_Some_2
+ by auto
+
+lemma subsuming_states_def':
+ "s \<in> ast_problem.subsuming_states prob ps = (s \<in> (ast_problem.valid_states prob) \<and> ps \<subseteq>\<^sub>m s)"
+ by (auto simp add: ast_problem.subsuming_states_def)
+
+lemma rem_implicit_pres_ops_enabled_1:
+ "\<lbrakk>(\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> consistent_pres_op op);
+ ast_problem.enabled prob name s\<rbrakk> \<Longrightarrow>
+ ast_problem.enabled (rem_implicit_pres_ops prob) name s"
+ by (fastforce simp: ast_problem.enabled_def rem_implicit_pres_ops_valid_states subsuming_states_def'
+ implicit_pres_empty
+ intro!: map_add_le_mapI
+ dest: rem_implicit_pres_ops_lookup_op_Some_1'
+ split: option.splits)+
+
+context ast_problem
+begin
+
+lemma lookup_Some_in\<delta>: "lookup_operator \<pi> = Some op \<Longrightarrow> op\<in>set ast\<delta>"
+ by(auto simp: find_Some_iff in_set_conv_nth lookup_operator_def)
+
+end
+
+lemma rem_implicit_pres_ops_enabled_2:
+ assumes "(\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> consistent_pres_op op)"
+ shows "ast_problem.enabled (rem_implicit_pres_ops prob) name s \<Longrightarrow>
+ ast_problem.enabled prob name s"
+ using assms[OF ast_problem.lookup_Some_in\<delta>, unfolded consistent_pres_op_def]
+ apply(auto simp: subsuming_states_append rem_implicit_pres_ops_valid_states subsuming_states_def'
+ ast_problem.enabled_def
+ dest!: rem_implicit_pres_ops_lookup_op_Some_2'
+ split: option.splits)
+ using subsuming_states_map_add consistent_map_lists
+ apply (metis Map.map_add_comm dom_map_of_conv_image_fst map_add_le_mapE)
+ using map_add_le_mapE by blast
+
+lemma rem_implicit_pres_ops_enabled:
+ "(\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> consistent_pres_op op) \<Longrightarrow>
+ ast_problem.enabled (rem_implicit_pres_ops prob) name s = ast_problem.enabled prob name s"
+ using rem_implicit_pres_ops_enabled_1 rem_implicit_pres_ops_enabled_2
+ by blast
+
+context ast_problem
+begin
+
+lemma std_eff_enabled[simp]:
+ "is_standard_operator (name, pres, effs, layer) \<Longrightarrow> s \<in> valid_states \<Longrightarrow> (filter (eff_enabled s) effs) = effs"
+ by (induction effs) (auto simp: is_standard_operator_def is_standard_effect_def eff_enabled_def subsuming_states_def)
+
+end
+
+lemma is_standard_operator_rem_implicit: "is_standard_operator (n,p,vp,v) \<Longrightarrow>
+ is_standard_operator (rem_implicit_pres (n,p,vp,v))"
+ by (induction vp) (auto simp: is_standard_operator_def is_standard_effect_def)
+
+lemma is_standard_operator_rem_implicit_pres_ops:
+ "\<lbrakk>(\<And>op. op \<in> set (ast_problem.ast\<delta> (a,b,c,d)) \<Longrightarrow> is_standard_operator op);
+ op \<in> set (ast_problem.ast\<delta> (rem_implicit_pres_ops (a,b,c,d)))\<rbrakk>
+ \<Longrightarrow> is_standard_operator op"
+ by (induction d) (fastforce simp add: ast_problem.ast\<delta>_def image_def dest!: is_standard_operator_rem_implicit)+
+
+lemma is_standard_operator_rem_implicit_pres_ops':
+ "\<lbrakk>op \<in> set (ast_problem.ast\<delta> (rem_implicit_pres_ops prob));
+ (\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> is_standard_operator op)\<rbrakk>
+ \<Longrightarrow> is_standard_operator op"
+ apply(cases prob)
+ using is_standard_operator_rem_implicit_pres_ops
+ by blast
+
+lemma in_rem_implicit_pres_\<delta>:
+ "op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow>
+ rem_implicit_pres op \<in> set (ast_problem.ast\<delta> (rem_implicit_pres_ops prob))"
+ by(auto simp add: ast_problem.ast\<delta>_def)
+
+lemma rem_implicit_pres_ops_execute:
+ assumes
+ "(\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> is_standard_operator op)" and
+ "s \<in> ast_problem.valid_states prob"
+ shows "ast_problem.execute (rem_implicit_pres_ops prob) name s = ast_problem.execute prob name s"
+proof-
+ have "(n,ps,es,c) \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow>
+ (filter (ast_problem.eff_enabled prob s) es) = es" for n ps es c
+ using assms(2)
+ by (auto simp add: ast_problem.std_eff_enabled dest!: assms(1))
+ moreover have "(n,ps,es,c) \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow>
+ (filter (ast_problem.eff_enabled (rem_implicit_pres_ops prob) s) (map rem_effect_implicit_pres es))
+ = map rem_effect_implicit_pres es" for n ps es c
+ using assms
+ by (fastforce simp add: ast_problem.std_eff_enabled rem_implicit_pres_ops_valid_states
+ dest!: is_standard_operator_rem_implicit_pres_ops'
+ dest: in_rem_implicit_pres_\<delta>)
+ moreover have "map_of (map ((\<lambda>(_,x,_,v). (x,v)) o rem_effect_implicit_pres) effs) =
+ map_of (map (\<lambda>(_,x,_,v). (x,v)) effs)" for effs
+ by (induction effs) auto
+ ultimately show ?thesis
+ by(auto simp add: ast_problem.execute_def rem_implicit_pres_ops_lookup_op_Some_1'
+ split: option.splits
+ dest: rem_implicit_pres_ops_lookup_op_Some_2' ast_problem.lookup_Some_in\<delta>)
+qed
+
+lemma rem_implicit_pres_ops_path_to:
+ "wf_ast_problem prob \<Longrightarrow>
+ (\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> consistent_pres_op op) \<Longrightarrow>
+ (\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> is_standard_operator op) \<Longrightarrow>
+ s \<in> ast_problem.valid_states prob \<Longrightarrow>
+ ast_problem.path_to (rem_implicit_pres_ops prob) s \<pi>s s' = ast_problem.path_to prob s \<pi>s s'"
+ by (induction \<pi>s arbitrary: s)
+ (auto simp: rem_implicit_pres_ops_execute rem_implicit_pres_ops_enabled
+ ast_problem.path_to.simps wf_ast_problem.execute_preserves_valid)
+
+lemma rem_implicit_pres_ops_astG[simp]: "ast_problem.astG (rem_implicit_pres_ops prob) =
+ ast_problem.astG prob"
+ apply(cases prob)
+ by (auto simp add: ast_problem.astG_def)
+
+lemma rem_implicit_pres_ops_goal[simp]: "ast_problem.G (rem_implicit_pres_ops prob) = ast_problem.G prob"
+ apply(cases prob)
+ using rem_implicit_pres_ops_valid_states
+ by (auto simp add: ast_problem.G_def ast_problem.astG_def subsuming_states_def')
+
+lemma rem_implicit_pres_ops_astI[simp]:
+ "ast_problem.astI (rem_implicit_pres_ops prob) = ast_problem.astI prob"
+ apply(cases prob)
+ by (auto simp add: ast_problem.I_def ast_problem.astI_def subsuming_states_def')
+
+lemma rem_implicit_pres_ops_init[simp]: "ast_problem.I (rem_implicit_pres_ops prob) = ast_problem.I prob"
+ apply(cases prob)
+ by (auto simp add: ast_problem.I_def ast_problem.astI_def)
+
+lemma rem_implicit_pres_ops_valid_plan:
+ assumes "wf_ast_problem prob"
+ "(\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> consistent_pres_op op)"
+ "(\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> is_standard_operator op)"
+ shows "ast_problem.valid_plan (rem_implicit_pres_ops prob) \<pi>s = ast_problem.valid_plan prob \<pi>s"
+ using wf_ast_problem.I_valid[OF assms(1)] rem_implicit_pres_ops_path_to[OF assms]
+ by (simp add: ast_problem.valid_plan_def rem_implicit_pres_ops_goal rem_implicit_pres_ops_init)
+
+lemma rem_implicit_pres_ops_numVars[simp]:
+ "ast_problem.numVars (rem_implicit_pres_ops prob) = ast_problem.numVars prob"
+ by (cases prob) (simp add: ast_problem.numVars_def ast_problem.astDom_def)
+
+lemma rem_implicit_pres_ops_numVals[simp]:
+ "ast_problem.numVals (rem_implicit_pres_ops prob) x = ast_problem.numVals prob x"
+ by (cases prob) (simp add: ast_problem.numVals_def ast_problem.astDom_def)
+
+lemma in_implicit_pres:
+ "(x, a) \<in> set (implicit_pres effs) \<Longrightarrow> (\<exists>epres v vp. (epres,x,vp,v)\<in> set effs \<and> vp = Some a)"
+ by (induction effs) (fastforce simp: implicit_pres_def image_def split: if_splits)+
+
+lemma pair4_eqD: "(a1,a2,a3,a4) = (b1,b2,b3,b4) \<Longrightarrow> a3 = b3"
+ by simp
+
+lemma rem_implicit_pres_ops_wf_partial_state:
+ "ast_problem.wf_partial_state (rem_implicit_pres_ops prob) s =
+ ast_problem.wf_partial_state prob s"
+ by (auto simp: ast_problem.wf_partial_state_def)
+
+lemma rem_implicit_pres_wf_operator:
+ assumes "consistent_pres_op op"
+ "ast_problem.wf_operator prob op"
+ shows
+ "ast_problem.wf_operator (rem_implicit_pres_ops prob) (rem_implicit_pres op)"
+proof-
+ obtain name pres effs cost where op: "op = (name, pres, effs, cost)"
+ by (cases op)
+ hence asses: "consistent_pres_op (name, pres, effs, cost)"
+ "ast_problem.wf_operator prob (name, pres, effs, cost)"
+ using assms
+ by auto
+ hence "distinct (map fst ((implicit_pres effs) @ pres))"
+ by (simp only: consistent_pres_op_def) auto
+ moreover have "x < ast_problem.numVars (rem_implicit_pres_ops prob)"
+ "v < ast_problem.numVals (rem_implicit_pres_ops prob) x"
+ if "(x,v) \<in> set ((implicit_pres effs) @ pres)" for x v
+ using that asses
+ by (auto dest!: in_implicit_pres simp: ast_problem.wf_partial_state_def ast_problem.wf_operator_def)
+ ultimately have "ast_problem.wf_partial_state (rem_implicit_pres_ops prob) ((implicit_pres effs) @ pres)"
+ by (auto simp only: ast_problem.wf_partial_state_def)
+ moreover have "(map (\<lambda>(_, v, _, _). v) effs) =
+ (map (\<lambda>(_, v, _, _). v) (map rem_effect_implicit_pres effs))"
+ by auto
+ hence "distinct (map (\<lambda>(_, v, _, _). v) (map rem_effect_implicit_pres effs))"
+ using assms(2)
+ by (auto simp only: op ast_problem.wf_operator_def rem_implicit_pres.simps dest!: pair4_eqD)
+ moreover have "(\<exists>vp. (epres,x,vp,v)\<in>set effs) \<longleftrightarrow> (epres,x,None,v)\<in>set (map rem_effect_implicit_pres effs)"
+ for epres x v
+ by force
+ ultimately show ?thesis
+ using assms(2)
+ by (auto simp: op ast_problem.wf_operator_def rem_implicit_pres_ops_wf_partial_state
+ split: prod.splits)
+qed
+
+lemma rem_implicit_pres_ops_in\<delta>D: "op \<in> set (ast_problem.ast\<delta> (rem_implicit_pres_ops prob))
+ \<Longrightarrow> (\<exists>op'. op' \<in> set (ast_problem.ast\<delta> prob) \<and> op = rem_implicit_pres op')"
+ by (cases prob) (force simp: ast_problem.ast\<delta>_def)
+
+lemma rem_implicit_pres_ops_well_formed:
+ assumes "(\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> consistent_pres_op op)"
+ "ast_problem.well_formed prob"
+ shows "ast_problem.well_formed (rem_implicit_pres_ops prob)"
+proof-
+ have "map fst (ast_problem.ast\<delta> (rem_implicit_pres_ops prob)) = map fst (ast_problem.ast\<delta> prob)"
+ by (cases prob) (auto simp: ast_problem.ast\<delta>_def)
+ thus ?thesis
+ using assms
+ by(auto simp add: ast_problem.well_formed_def rem_implicit_pres_ops_wf_partial_state
+ simp del: rem_implicit_pres.simps
+ dest!: rem_implicit_pres_ops_in\<delta>D
+ intro!: rem_implicit_pres_wf_operator)
+qed
+
+definition is_standard_effect'
+ :: "ast_effect \<Rightarrow> bool"
+ where "is_standard_effect' \<equiv> \<lambda>(pre, _, vpre, _). pre = [] \<and> vpre = None"
+
+definition is_standard_operator'
+ :: "ast_operator \<Rightarrow> bool"
+ where "is_standard_operator' \<equiv> \<lambda>(_, _, effects, _). list_all is_standard_effect' effects"
+
+lemma rem_implicit_pres_is_standard_operator':
+ "is_standard_operator (n,p,es,c) \<Longrightarrow> is_standard_operator' (rem_implicit_pres (n,p,es,c))"
+ by (induction es) (auto simp: is_standard_operator'_def is_standard_operator_def is_standard_effect_def
+ is_standard_effect'_def)
+
+lemma rem_implicit_pres_ops_is_standard_operator':
+ "(\<And>op. op \<in> set (ast_problem.ast\<delta> (vs, I, G, ops)) \<Longrightarrow> is_standard_operator op) \<Longrightarrow>
+ \<pi>\<in>set (ast_problem.ast\<delta> (rem_implicit_pres_ops (vs, I, G, ops))) \<Longrightarrow> is_standard_operator' \<pi>"
+ by (cases ops) (auto simp: ast_problem.ast\<delta>_def dest!: rem_implicit_pres_is_standard_operator')
+
+locale abs_ast_prob = wf_ast_problem +
+ assumes no_cond_effs: "\<forall>\<pi>\<in>set ast\<delta>. is_standard_operator' \<pi>"
+
+context ast_problem
+begin
+
+definition "abs_ast_variable_section = [0..<(length astDom)]"
+
+definition abs_range_map
+ :: "(nat \<rightharpoonup> nat list)"
+ where "abs_range_map \<equiv>
+ map_of (zip abs_ast_variable_section
+ (map ((\<lambda>vals. [0..<length vals]) o snd o snd)
+ astDom))"
+
+end
+
+context abs_ast_prob
+begin
+
+lemma is_valid_vars_1: "astDom \<noteq> [] \<Longrightarrow> abs_ast_variable_section \<noteq> []"
+ by(simp add: abs_ast_variable_section_def)
+
+end
+
+lemma upt_eq_Nil_conv'[simp]: "([] = [i..<j]) = (j = 0 \<or> j \<le> i)"
+ by(induct j)simp_all
+
+lemma map_of_zip_map_Some:
+ "v < length xs
+ \<Longrightarrow> (map_of (zip [0..<length xs] (map f xs)) v) = Some (f (xs ! v))"
+ by (induction xs rule: rev_induct) (auto simp add: nth_append map_add_Some_iff)
+
+lemma map_of_zip_Some:
+ "v < length xs
+ \<Longrightarrow> (map_of (zip [0..<length xs] xs) v) = Some (xs ! v)"
+ by (induction xs rule: rev_induct) (auto simp add: nth_append map_add_Some_iff)
+
+lemma in_set_zip_lengthE:
+ "(x,y) \<in> set(zip [0..<length xs] xs) \<Longrightarrow> (\<lbrakk> x < length xs; xs ! x =y \<rbrakk> \<Longrightarrow> R) \<Longrightarrow> R"
+ by (induction xs rule: rev_induct) (auto simp add: nth_append map_add_Some_iff)
+
+context abs_ast_prob
+begin
+
+lemma is_valid_vars_2:
+ shows "list_all (\<lambda>v. abs_range_map v \<noteq> None) abs_ast_variable_section"
+ by (auto simp add: abs_range_map_def abs_ast_variable_section_def list.pred_set)
+end
+
+context ast_problem
+begin
+
+definition abs_ast_initial_state
+ :: "nat_sas_plus_state"
+ where "abs_ast_initial_state \<equiv> map_of (zip [0..<length astI] astI)"
+
+end
+
+context abs_ast_prob
+begin
+
+lemma valid_abs_init_1: "abs_ast_initial_state v \<noteq> None \<longleftrightarrow> v \<in> set abs_ast_variable_section"
+ by (simp add: abs_ast_variable_section_def numVars_def wf_initial(1) abs_ast_initial_state_def)
+
+lemma abs_range_map_Some:
+ shows "v \<in> set abs_ast_variable_section \<Longrightarrow>
+ (abs_range_map v) = Some [0..<length (snd (snd (astDom ! v)))]"
+ by (simp add: numVars_def abs_range_map_def o_def abs_ast_variable_section_def map_of_zip_map_Some)
+
+lemma in_abs_v_sec_length: "v \<in> set abs_ast_variable_section \<longleftrightarrow> v < length astDom"
+ by (simp add: abs_ast_variable_section_def)
+
+lemma [simp]: "v < length astDom \<Longrightarrow> (abs_ast_initial_state v) = Some (astI ! v)"
+ using wf_initial(1)[simplified numVars_def, symmetric]
+ by (auto simp add: map_of_zip_Some abs_ast_initial_state_def split: prod.splits)
+
+lemma [simp]: "v < length astDom \<Longrightarrow> astI ! v < length (snd (snd (astDom ! v)))"
+ using wf_initial(1)[simplified numVars_def, symmetric] wf_initial
+ by (auto simp add: numVals_def abs_ast_initial_state_def
+ split: prod.splits)
+
+lemma [intro!]: "v \<in> set abs_ast_variable_section \<Longrightarrow> x < length (snd (snd (astDom ! v))) \<Longrightarrow>
+ x \<in> set (the (abs_range_map v))"
+ using abs_range_map_Some
+ by (auto simp add: )
+
+lemma [intro!]: "x<length astDom \<Longrightarrow> astI ! x < length (snd (snd (astDom ! x)))"
+ using wf_initial[unfolded numVars_def numVals_def]
+ by auto
+
+lemma [simp]: "abs_ast_initial_state v = Some a \<Longrightarrow> a < length (snd (snd (astDom ! v)))"
+ by(auto simp add: abs_ast_initial_state_def
+ wf_initial(1)[unfolded numVars_def numVals_def, symmetric]
+ elim!: in_set_zip_lengthE)
+
+lemma valid_abs_init_2:
+ "abs_ast_initial_state v \<noteq> None \<Longrightarrow> (the (abs_ast_initial_state v)) \<in> set (the (abs_range_map v))"
+ using valid_abs_init_1
+ by auto
+
+end
+
+context ast_problem
+begin
+
+definition abs_ast_goal
+ :: "nat_sas_plus_state"
+ where "abs_ast_goal \<equiv> map_of astG"
+
+end
+
+context abs_ast_prob
+begin
+
+lemma [simp]: "wf_partial_state s \<Longrightarrow> (v, a) \<in> set s \<Longrightarrow> v \<in> set abs_ast_variable_section"
+ by (auto simp add: wf_partial_state_def abs_ast_variable_section_def numVars_def
+ split: prod.splits)
+
+lemma valid_abs_goal_1: "abs_ast_goal v \<noteq> None \<Longrightarrow> v \<in> set abs_ast_variable_section"
+ using wf_goal
+ by (auto simp add: abs_ast_goal_def dest!: map_of_SomeD)
+
+lemma in_abs_rangeI: "wf_partial_state s \<Longrightarrow> (v, a) \<in> set s \<Longrightarrow> (a \<in> set (the (abs_range_map v)))"
+ by (auto simp add: abs_range_map_Some wf_partial_state_def numVals_def split: prod.splits)
+
+lemma valid_abs_goal_2:
+ "abs_ast_goal v \<noteq> None \<Longrightarrow> (the (abs_ast_goal v)) \<in> set (the (abs_range_map v))"
+ using wf_goal
+ by (auto simp add: map_of_SomeD weak_map_of_SomeI abs_ast_goal_def intro!: in_abs_rangeI)
+
+end
+
+context ast_problem
+begin
+
+definition abs_ast_operator
+ :: "ast_operator \<Rightarrow> nat_sas_plus_operator"
+ where "abs_ast_operator \<equiv> \<lambda>(name, preconditions, effects, cost).
+ \<lparr> precondition_of = preconditions,
+ effect_of = [(v, x). (_, v, _, x) \<leftarrow> effects] \<rparr>"
+
+end
+
+context abs_ast_prob
+begin
+
+lemma abs_rangeI: "wf_partial_state s \<Longrightarrow> (v, a) \<in> set s \<Longrightarrow> (abs_range_map v \<noteq> None)"
+ by (auto simp add: wf_partial_state_def abs_range_map_def abs_ast_variable_section_def list.pred_set
+ numVars_def
+ split: prod.splits)
+
+lemma abs_valid_operator_1[intro!]:
+ "wf_operator op \<Longrightarrow> list_all (\<lambda>(v, a). ListMem v abs_ast_variable_section)
+ (precondition_of (abs_ast_operator op))"
+ by (cases op; auto simp add: abs_ast_operator_def wf_operator_def list.pred_set ListMem_iff)
+
+lemma wf_operator_preD: "wf_operator (name, pres, effs, cost) \<Longrightarrow> wf_partial_state pres"
+ by (simp add: wf_operator_def)
+
+lemma abs_valid_operator_2[intro!]:
+ "wf_operator op \<Longrightarrow>
+ list_all (\<lambda>(v, a). (\<exists>y. abs_range_map v = Some y) \<and> ListMem a (the (abs_range_map v)))
+ (precondition_of (abs_ast_operator op))"
+ by(cases op,
+ auto dest!: wf_operator_preD simp: list.pred_set ListMem_iff abs_ast_operator_def
+ intro!: abs_rangeI[simplified not_None_eq] in_abs_rangeI)
+
+lemma wf_operator_effE: "wf_operator (name, pres, effs, cost) \<Longrightarrow>
+ (\<lbrakk>distinct (map (\<lambda>(_, v, _, _). v) effs);
+ \<And>epres x vp v. (epres,x,vp,v)\<in>set effs \<Longrightarrow> wf_partial_state epres;
+ \<And>epres x vp v.(epres,x,vp,v)\<in>set effs \<Longrightarrow> x < numVars;
+ \<And>epres x vp v. (epres,x,vp,v)\<in>set effs \<Longrightarrow> v < numVals x;
+ \<And>epres x vp v. (epres,x,vp,v)\<in>set effs \<Longrightarrow>
+ case vp of None \<Rightarrow> True | Some v \<Rightarrow> v<numVals x\<rbrakk>
+ \<Longrightarrow> P)
+ \<Longrightarrow> P"
+ unfolding wf_operator_def
+ by (auto split: prod.splits)
+
+lemma abs_valid_operator_3':
+ "wf_operator (name, pre, eff, cost) \<Longrightarrow>
+ list_all (\<lambda>(v, a). ListMem v abs_ast_variable_section) (map (\<lambda>(_, v, _, a). (v, a)) eff)"
+ by (fastforce simp add: list.pred_set ListMem_iff abs_ast_variable_section_def image_def numVars_def
+ elim!: wf_operator_effE split: prod.splits)
+
+lemma abs_valid_operator_3[intro!]:
+ "wf_operator op \<Longrightarrow>
+ list_all (\<lambda>(v, a). ListMem v abs_ast_variable_section) (effect_of (abs_ast_operator op))"
+ by (cases op, simp add: abs_ast_operator_def abs_valid_operator_3')
+
+lemma wf_abs_eff: "wf_operator (name, pre, eff, cost) \<Longrightarrow> wf_partial_state (map (\<lambda>(_, v, _, a). (v, a)) eff)"
+ by (elim wf_operator_effE, induction eff)
+ (fastforce simp: wf_partial_state_def image_def o_def split: prod.split_asm)+
+
+lemma abs_valid_operator_4':
+ "wf_operator (name, pre, eff, cost) \<Longrightarrow>
+ list_all (\<lambda>(v, a). (abs_range_map v \<noteq> None) \<and> ListMem a (the (abs_range_map v))) (map (\<lambda>(_, v, _, a). (v, a)) eff)"
+ apply(subst list.pred_set ListMem_iff)+
+ apply(drule wf_abs_eff)
+ by (metis (mono_tags, lifting) abs_rangeI case_prodI2 in_abs_rangeI)
+
+lemma abs_valid_operator_4[intro!]:
+ "wf_operator op \<Longrightarrow>
+ list_all (\<lambda>(v, a). (\<exists>y. abs_range_map v = Some y) \<and> ListMem a (the (abs_range_map v)))
+ (effect_of (abs_ast_operator op))"
+ using abs_valid_operator_4'
+ by (cases op, simp add: abs_ast_operator_def)
+
+lemma consistent_list_set: "wf_partial_state s \<Longrightarrow>
+ list_all (\<lambda>(v, a). list_all (\<lambda>(v', a'). v \<noteq> v' \<or> a = a') s) s"
+ by (auto simp add: list.pred_set wf_partial_state_def eq_key_imp_eq_value split: prod.splits)
+
+lemma abs_valid_operator_5':
+ "wf_operator (name, pre, eff, cost) \<Longrightarrow>
+ list_all (\<lambda>(v, a). list_all (\<lambda>(v', a'). v \<noteq> v' \<or> a = a') pre) pre"
+ apply(drule wf_operator_preD)
+ by (intro consistent_list_set)
+
+lemma abs_valid_operator_5[intro!]:
+ "wf_operator op \<Longrightarrow>
+ list_all (\<lambda>(v, a). list_all (\<lambda>(v', a'). v \<noteq> v' \<or> a = a') (precondition_of (abs_ast_operator op)))
+ (precondition_of (abs_ast_operator op))"
+ using abs_valid_operator_5'
+ by (cases op, simp add: abs_ast_operator_def)
+
+lemma consistent_list_set_2: "distinct (map fst s) \<Longrightarrow>
+ list_all (\<lambda>(v, a). list_all (\<lambda>(v', a'). v \<noteq> v' \<or> a = a') s) s"
+ by (auto simp add: list.pred_set wf_partial_state_def eq_key_imp_eq_value split: prod.splits)
+
+lemma abs_valid_operator_6':
+ assumes "wf_operator (name, pre, eff, cost)"
+ shows "list_all (\<lambda>(v, a). list_all (\<lambda>(v', a'). v \<noteq> v' \<or> a = a') (map (\<lambda>(_, v, _, a). (v, a)) eff))
+ (map (\<lambda>(_, v, _, a). (v, a)) eff)"
+proof-
+ have *: "map fst (map (\<lambda>(_, v, _, a). (v, a)) eff) = (map (\<lambda>(_, v,_,_). v) eff)"
+ by (induction eff) auto
+ show ?thesis
+ using assms
+ apply(elim wf_operator_effE)
+ apply(intro consistent_list_set_2)
+ by (subst *)
+qed
+
+lemma abs_valid_operator_6[intro!]:
+ "wf_operator op \<Longrightarrow>
+ list_all (\<lambda>(v, a). list_all (\<lambda>(v', a'). v \<noteq> v' \<or> a = a') (effect_of (abs_ast_operator op)))
+ (effect_of (abs_ast_operator op))"
+ using abs_valid_operator_6'
+ by (cases op, simp add: abs_ast_operator_def)
+
+end
+
+context ast_problem
+begin
+
+definition abs_ast_operator_section
+ :: "nat_sas_plus_operator list"
+ where "abs_ast_operator_section \<equiv> [abs_ast_operator op. op \<leftarrow> ast\<delta>]"
+
+definition abs_prob :: "nat_sas_plus_problem"
+ where "abs_prob = \<lparr>
+ variables_of = abs_ast_variable_section,
+ operators_of = abs_ast_operator_section,
+ initial_of = abs_ast_initial_state,
+ goal_of = abs_ast_goal,
+ range_of = abs_range_map
+ \<rparr>"
+
+end
+
+context abs_ast_prob
+begin
+
+lemma [simp]: "op \<in> set ast\<delta> \<Longrightarrow> (is_valid_operator_sas_plus abs_prob) (abs_ast_operator op)"
+ apply(cases op)
+ apply(subst is_valid_operator_sas_plus_def Let_def)+
+ using wf_operators(2)
+ by(fastforce simp add: abs_prob_def)+
+
+lemma abs_ast_operator_section_valid:
+ "list_all (is_valid_operator_sas_plus abs_prob) abs_ast_operator_section"
+ by (auto simp: abs_ast_operator_section_def list.pred_set)
+
+lemma abs_prob_valid: "is_valid_problem_sas_plus abs_prob"
+ using valid_abs_goal_1 valid_abs_goal_2 valid_abs_init_1 is_valid_vars_2
+ abs_ast_operator_section_valid[unfolded abs_prob_def]
+ by (auto simp add: is_valid_problem_sas_plus_def Let_def ListMem_iff abs_prob_def)
+
+definition abs_ast_plan
+ :: " SASP_Semantics.plan \<Rightarrow> nat_sas_plus_plan"
+ where "abs_ast_plan \<pi>s
+ \<equiv> map (abs_ast_operator o the o lookup_operator) \<pi>s"
+
+lemma std_then_implici_effs[simp]: "is_standard_operator' (name, pres, effs, layer) \<Longrightarrow> implicit_pres effs = []"
+ apply(induction effs)
+ by (auto simp add: is_standard_operator'_def implicit_pres_def is_standard_effect'_def)
+
+lemma [simp]: "enabled \<pi> s \<Longrightarrow> lookup_operator \<pi> = Some (name, pres, effs, layer) \<Longrightarrow>
+ is_standard_operator' (name, pres, effs, layer) \<Longrightarrow>
+ (filter (eff_enabled s) effs) = effs"
+ by(auto simp add: enabled_def is_standard_operator'_def eff_enabled_def is_standard_effect'_def filter_id_conv list.pred_set)
+
+lemma effs_eq_abs_effs: "(effect_of (abs_ast_operator (name, pres, effs, layer))) =
+ (map (\<lambda>(_,x,_,v). (x,v)) effs)"
+ by (auto simp add: abs_ast_operator_def
+ split: option.splits prod.splits)
+
+lemma exect_eq_abs_execute:
+ "\<lbrakk>enabled \<pi> s; lookup_operator \<pi> = Some (name, preconds, effs, layer);
+ is_standard_operator'(name, preconds, effs, layer)\<rbrakk> \<Longrightarrow>
+ execute \<pi> s = (execute_operator_sas_plus s ((abs_ast_operator o the o lookup_operator) \<pi>))"
+ using effs_eq_abs_effs
+ by (auto simp add: execute_def execute_operator_sas_plus_def)
+
+lemma enabled_then_sas_applicable:
+ "enabled \<pi> s \<Longrightarrow> SAS_Plus_Representation.is_operator_applicable_in s ((abs_ast_operator o the o lookup_operator) \<pi>)"
+ by (auto simp add: subsuming_states_def enabled_def lookup_operator_def
+ SAS_Plus_Representation.is_operator_applicable_in_def abs_ast_operator_def
+ split: option.splits prod.splits)
+
+lemma path_to_then_exec_serial: "\<forall>\<pi>\<in>set \<pi>s. lookup_operator \<pi> \<noteq> None \<Longrightarrow>
+ path_to s \<pi>s s' \<Longrightarrow>
+ s' \<subseteq>\<^sub>m execute_serial_plan_sas_plus s (abs_ast_plan \<pi>s)"
+proof(induction \<pi>s arbitrary: s s')
+ case (Cons a \<pi>s)
+ then show ?case
+ by (force simp: exect_eq_abs_execute abs_ast_plan_def lookup_Some_in\<delta> no_cond_effs
+ dest: enabled_then_sas_applicable)
+qed (auto simp: execute_serial_plan_sas_plus_def abs_ast_plan_def)
+
+lemma map_of_eq_None_iff:
+ "(None = map_of xys x) = (x \<notin> fst ` (set xys))"
+by (induct xys) simp_all
+
+lemma [simp]: "I = abs_ast_initial_state"
+ apply(intro HOL.ext)
+ by (auto simp: map_of_eq_None_iff set_map[symmetric] I_def abs_ast_initial_state_def map_of_zip_Some
+ dest: map_of_SomeD)
+
+lemma [simp]: "\<forall>\<pi> \<in> set \<pi>s. lookup_operator \<pi> \<noteq> None \<Longrightarrow>
+ op\<in>set (abs_ast_plan \<pi>s) \<Longrightarrow> op \<in> set abs_ast_operator_section"
+ by (induction \<pi>s) (auto simp: abs_ast_plan_def abs_ast_operator_section_def lookup_Some_in\<delta>)
+
+end
+
+context ast_problem
+begin
+
+lemma path_to_then_lookup_Some: "(\<exists>s'\<in>G. path_to s \<pi>s s') \<Longrightarrow> (\<forall>\<pi> \<in> set \<pi>s. lookup_operator \<pi> \<noteq> None)"
+ by (induction \<pi>s arbitrary: s) (force simp add: enabled_def split: option.splits)+
+
+lemma valid_plan_then_lookup_Some: "valid_plan \<pi>s \<Longrightarrow> (\<forall>\<pi> \<in> set \<pi>s. lookup_operator \<pi> \<noteq> None)"
+ using path_to_then_lookup_Some
+ by(simp add: valid_plan_def)
+
+end
+
+context abs_ast_prob
+begin
+
+theorem valid_plan_then_is_serial_sol:
+ assumes "valid_plan \<pi>s"
+ shows "is_serial_solution_for_problem abs_prob (abs_ast_plan \<pi>s)"
+ using valid_plan_then_lookup_Some[OF assms] assms
+ by (auto simp add: is_serial_solution_for_problem_def valid_plan_def initial_of_def
+ abs_prob_def abs_ast_goal_def G_def subsuming_states_def list_all_iff
+ ListMem_iff map_le_trans path_to_then_exec_serial
+ simp del: sas_plus_problem.select_defs)
+
+end
+
+subsection \<open>Translating SAS+ represnetation to Fast-Downward's\<close>
+
+context ast_problem
+begin
+
+definition lookup_action:: "nat_sas_plus_operator \<Rightarrow> ast_operator option" where
+ "lookup_action op \<equiv>
+ find (\<lambda>(_, pres, effs, _). precondition_of op = pres \<and>
+ map (\<lambda>(v,a). ([], v, None, a)) (effect_of op) = effs)
+ ast\<delta>"
+
+end
+
+context abs_ast_prob
+begin
+
+lemma find_Some: "find P xs = Some x \<Longrightarrow> x \<in> set xs \<and> P x"
+ by (auto simp add: find_Some_iff)
+
+lemma distinct_find: "distinct (map f xs) \<Longrightarrow> x \<in> set xs \<Longrightarrow> find (\<lambda>x'. f x' = f x) xs = Some x"
+ by (induction xs) (auto simp: image_def)
+
+lemma lookup_operator_find: "lookup_operator nme = find (\<lambda>op. fst op = nme) ast\<delta>"
+ by (auto simp: lookup_operator_def intro!: arg_cong[where f = "(\<lambda>x. find x ast\<delta>)"])
+
+lemma lookup_operator_works_1: "lookup_action op = Some \<pi>' \<Longrightarrow> lookup_operator (fst \<pi>') = Some \<pi>'"
+ by (auto simp: wf_operators(1) lookup_operator_find lookup_action_def dest: find_Some intro: distinct_find)
+
+lemma lookup_operator_works_2:
+ "lookup_action (abs_ast_operator (name, pres, effs, layer)) = Some (name', pres', effs', layer')
+ \<Longrightarrow> pres = pres'"
+ by (auto simp: lookup_action_def abs_ast_operator_def dest!: find_Some)
+
+lemma [simp]: "is_standard_operator' (name, pres, effs, layer) \<Longrightarrow>
+ map (\<lambda>(v,a). ([], v, None, a)) (effect_of (abs_ast_operator (name, pres, effs, layer))) = effs"
+ by (induction effs) (auto simp: is_standard_operator'_def abs_ast_operator_def is_standard_effect'_def)
+
+lemma lookup_operator_works_3:
+ "is_standard_operator' (name, pres, effs, layer) \<Longrightarrow> (name, pres, effs, layer) \<in> set ast\<delta> \<Longrightarrow>
+ lookup_action (abs_ast_operator (name, pres, effs, layer)) = Some (name', pres', effs', layer')
+ \<Longrightarrow> effs = effs'"
+ by(auto simp: is_standard_operator'_def lookup_action_def dest!: find_Some)
+
+lemma mem_find_Some: "x \<in> set xs \<Longrightarrow> P x \<Longrightarrow> \<exists>x'. find P xs = Some x'"
+ by (induction xs) auto
+
+lemma [simp]: "precondition_of (abs_ast_operator (x1, a, aa, b)) = a"
+ by(simp add: abs_ast_operator_def)
+
+lemma std_lookup_action: "is_standard_operator' ast_op \<Longrightarrow> ast_op \<in> set ast\<delta> \<Longrightarrow>
+ \<exists>ast_op'. lookup_action (abs_ast_operator ast_op) = Some ast_op'"
+ unfolding lookup_action_def
+ apply(intro mem_find_Some)
+ by (auto split: prod.splits simp: o_def)
+
+lemma is_applicable_then_enabled_1:
+ "ast_op \<in> set ast\<delta> \<Longrightarrow>
+ \<exists>ast_op'. lookup_operator ((fst o the o lookup_action o abs_ast_operator) ast_op) = Some ast_op'"
+ using lookup_operator_works_1 std_lookup_action no_cond_effs
+ by auto
+
+lemma lookup_action_Some_in_\<delta>: "lookup_action op = Some ast_op \<Longrightarrow> ast_op \<in> set ast\<delta>"
+ using lookup_operator_works_1 lookup_Some_in\<delta> by fastforce
+
+lemma lookup_operator_eq_name: "lookup_operator name = Some (name', pres, effs, layer) \<Longrightarrow> name = name'"
+ using lookup_operator_wf(2)
+ by fastforce
+
+lemma eq_name_eq_pres: "(name, pres, effs, layer) \<in> set ast\<delta> \<Longrightarrow> (name, pres', effs', layer') \<in> set ast\<delta>
+ \<Longrightarrow> pres = pres'"
+ using eq_key_imp_eq_value[OF wf_operators(1)]
+ by auto
+
+lemma eq_name_eq_effs:
+ "name = name' \<Longrightarrow> (name, pres, effs, layer) \<in> set ast\<delta> \<Longrightarrow> (name', pres', effs', layer') \<in> set ast\<delta>
+ \<Longrightarrow> effs = effs'"
+ using eq_key_imp_eq_value[OF wf_operators(1)]
+ by auto
+
+lemma is_applicable_then_subsumes:
+ "s \<in> valid_states \<Longrightarrow>
+ SAS_Plus_Representation.is_operator_applicable_in s (abs_ast_operator (name, pres, effs, layer)) \<Longrightarrow>
+ s \<in> subsuming_states (map_of pres)"
+ by (simp add: subsuming_states_def SAS_Plus_Representation.is_operator_applicable_in_def
+ abs_ast_operator_def)
+
+lemma eq_name_eq_pres':
+ "\<lbrakk>s \<in> valid_states ; is_standard_operator' (name, pres, effs, layer); (name, pres, effs, layer) \<in> set ast\<delta> ;
+ lookup_operator ((fst o the o lookup_action o abs_ast_operator) (name, pres, effs, layer)) = Some (name', pres', effs', layer')\<rbrakk>
+ \<Longrightarrow> pres = pres'"
+ using lookup_operator_eq_name lookup_operator_works_2
+ by (fastforce dest!: std_lookup_action
+ simp: eq_name_eq_pres[OF lookup_action_Some_in_\<delta> lookup_Some_in\<delta>])
+
+lemma is_applicable_then_enabled_2:
+ "\<lbrakk>s \<in> valid_states ; ast_op \<in> set ast\<delta> ;
+ SAS_Plus_Representation.is_operator_applicable_in s (abs_ast_operator ast_op);
+ lookup_operator ((fst o the o lookup_action o abs_ast_operator) ast_op) = Some (name, pres, effs, layer)\<rbrakk>
+ \<Longrightarrow> s\<in>subsuming_states (map_of pres)"
+ apply(cases ast_op)
+ using eq_name_eq_pres' is_applicable_then_subsumes no_cond_effs
+ by fastforce
+
+lemma is_applicable_then_enabled_3:
+ "\<lbrakk>s \<in> valid_states;
+ lookup_operator ((fst o the o lookup_action o abs_ast_operator) ast_op) = Some (name, pres, effs, layer)\<rbrakk>
+ \<Longrightarrow> s\<in>subsuming_states (map_of (implicit_pres effs))"
+ apply(cases ast_op)
+ using no_cond_effs
+ by (auto dest!: std_then_implici_effs std_lookup_action lookup_Some_in\<delta>
+ simp: subsuming_states_def)
+
+lemma is_applicable_then_enabled:
+ "\<lbrakk>s \<in> valid_states; ast_op \<in> set ast\<delta>;
+ SAS_Plus_Representation.is_operator_applicable_in s (abs_ast_operator ast_op)\<rbrakk>
+ \<Longrightarrow> enabled ((fst o the o lookup_action o abs_ast_operator) ast_op) s"
+ using is_applicable_then_enabled_1 is_applicable_then_enabled_2 is_applicable_then_enabled_3
+ by(simp add: enabled_def split: option.splits)
+
+lemma eq_name_eq_effs':
+ assumes "lookup_operator ((fst o the o lookup_action o abs_ast_operator) (name, pres, effs, layer)) =
+ Some (name', pres', effs', layer')"
+ "is_standard_operator' (name, pres, effs, layer)" "(name, pres, effs, layer) \<in> set ast\<delta>"
+ "s \<in> valid_states"
+ shows "effs = effs'"
+ using std_lookup_action[OF assms(2,3)] assms
+ by (auto simp: lookup_operator_works_3[OF assms(2,3)]
+ eq_name_eq_effs[OF lookup_operator_eq_name lookup_action_Some_in_\<delta> lookup_Some_in\<delta>])
+
+lemma std_eff_enabled'[simp]:
+ "is_standard_operator' (name, pres, effs, layer) \<Longrightarrow> s \<in> valid_states \<Longrightarrow> (filter (eff_enabled s) effs) = effs"
+ by (induction effs) (auto simp: is_standard_operator'_def is_standard_effect'_def eff_enabled_def subsuming_states_def)
+
+lemma execute_abs:
+ "\<lbrakk>s \<in> valid_states; ast_op \<in> set ast\<delta>;
+ SAS_Plus_Representation.is_operator_applicable_in s (abs_ast_operator ast_op)\<rbrakk> \<Longrightarrow>
+ execute ((fst o the o lookup_action o abs_ast_operator) ast_op) s =
+ execute_operator_sas_plus s (abs_ast_operator ast_op)"
+ using no_cond_effs
+ by(cases ast_op)
+ (fastforce simp add: execute_def execute_operator_sas_plus_def effs_eq_abs_effs
+ dest: is_applicable_then_enabled_1 eq_name_eq_effs'[unfolded o_def]
+ split: option.splits)+
+
+fun sat_preconds_as where
+ "sat_preconds_as s [] = True"
+| "sat_preconds_as s (op#ops) =
+ (SAS_Plus_Representation.is_operator_applicable_in s op \<and>
+ sat_preconds_as (execute_operator_sas_plus s op) ops)"
+
+lemma exec_serial_then_path_to':
+ "\<lbrakk>s \<in> valid_states;
+ \<forall>op\<in>set ops. \<exists>ast_op\<in> set ast\<delta>. op = abs_ast_operator ast_op;
+ (sat_preconds_as s ops)\<rbrakk> \<Longrightarrow>
+ path_to s (map (fst o the o lookup_action) ops) (execute_serial_plan_sas_plus s ops)"
+proof(induction ops arbitrary: s)
+ case (Cons a ops)
+ then show ?case
+ using execute_abs is_applicable_then_enabled execute_preserves_valid
+ apply simp
+ by metis
+qed auto
+
+end
+
+fun rem_condless_ops where
+ "rem_condless_ops s [] = []"
+| "rem_condless_ops s (op#ops) =
+ (if SAS_Plus_Representation.is_operator_applicable_in s op then
+ op # (rem_condless_ops (execute_operator_sas_plus s op) ops)
+ else [])"
+
+context abs_ast_prob
+begin
+
+lemma exec_rem_consdless: "execute_serial_plan_sas_plus s (rem_condless_ops s ops) = execute_serial_plan_sas_plus s ops"
+ by (induction ops arbitrary: s) auto
+
+lemma rem_conless_sat: "sat_preconds_as s (rem_condless_ops s ops)"
+ by (induction ops arbitrary: s) auto
+
+lemma set_rem_condlessD: "x \<in> set (rem_condless_ops s ops) \<Longrightarrow> x \<in> set ops"
+ by (induction ops arbitrary: s) auto
+
+lemma exec_serial_then_path_to:
+ "\<lbrakk>s \<in> valid_states;
+ \<forall>op\<in>set ops. \<exists>ast_op\<in> set ast\<delta>. op = abs_ast_operator ast_op\<rbrakk> \<Longrightarrow>
+ path_to s (((map (fst o the o lookup_action)) o rem_condless_ops s) ops)
+ (execute_serial_plan_sas_plus s ops)"
+ using rem_conless_sat
+ by (fastforce dest!: set_rem_condlessD
+ intro!: exec_serial_then_path_to'
+ [where s = s and ops = "rem_condless_ops s ops",
+ unfolded exec_rem_consdless])
+
+lemma is_serial_solution_then_abstracted:
+ "is_serial_solution_for_problem abs_prob ops
+ \<Longrightarrow> \<forall>op\<in>set ops. \<exists>ast_op\<in> set ast\<delta>. op = abs_ast_operator ast_op"
+ by(auto simp: is_serial_solution_for_problem_def abs_prob_def Let_def list.pred_set
+ ListMem_iff abs_ast_operator_section_def
+ split: if_splits)
+
+lemma lookup_operator_works_1': "lookup_action op = Some \<pi>' \<Longrightarrow> \<exists>op. lookup_operator (fst \<pi>') = op"
+ using lookup_operator_works_1 by auto
+
+lemma is_serial_sol_then_valid_plan_1:
+ "\<lbrakk>is_serial_solution_for_problem abs_prob ops;
+ \<pi> \<in> set ((map (fst o the o lookup_action) o rem_condless_ops I) ops)\<rbrakk> \<Longrightarrow>
+ lookup_operator \<pi> \<noteq> None"
+ using std_lookup_action lookup_operator_works_1 no_cond_effs
+ by (fastforce dest!: set_rem_condlessD is_serial_solution_then_abstracted
+ simp: valid_plan_def list.pred_set ListMem_iff)
+
+lemma is_serial_sol_then_valid_plan_2:
+ "\<lbrakk>is_serial_solution_for_problem abs_prob ops\<rbrakk> \<Longrightarrow>
+ (\<exists>s'\<in>G. path_to I ((map (fst o the o lookup_action) o rem_condless_ops I) ops) s')"
+ using I_valid
+ by (fastforce intro: path_to_pres_valid exec_serial_then_path_to
+ intro!: bexI[where x = "execute_serial_plan_sas_plus I ops"]
+ dest: is_serial_solution_then_abstracted
+ simp: list.pred_set ListMem_iff abs_ast_operator_section_def
+ G_def subsuming_states_def is_serial_solution_for_problem_def
+ abs_prob_def abs_ast_goal_def)+
+
+end
+
+context ast_problem
+begin
+
+definition "decode_abs_plan \<equiv> (map (fst o the o lookup_action) o rem_condless_ops I)"
+
+end
+
+context abs_ast_prob
+begin
+
+theorem is_serial_sol_then_valid_plan:
+ "\<lbrakk>is_serial_solution_for_problem abs_prob ops\<rbrakk> \<Longrightarrow>
+ valid_plan (decode_abs_plan ops)"
+ using is_serial_sol_then_valid_plan_1 is_serial_sol_then_valid_plan_2
+ by(simp add: valid_plan_def decode_abs_plan_def)
+
+end
+
+end
\ No newline at end of file
diff --git a/thys/Verified_SAT_Based_AI_Planning/CNF_Semantics_Supplement.thy b/thys/Verified_SAT_Based_AI_Planning/CNF_Semantics_Supplement.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/CNF_Semantics_Supplement.thy
@@ -0,0 +1,117 @@
+(*
+ Author: Fred Kurz
+*)
+theory CNF_Semantics_Supplement
+ imports "Propositional_Proof_Systems.CNF_Formulas_Sema" "CNF_Supplement"
+begin
+
+lemma not_model_if_exists_unmodeled_singleton_clause:
+ assumes "is_cnf F"
+ and "{L} \<in> cnf F"
+ and "\<not>lit_semantics \<nu> L"
+ shows "\<not>\<nu> \<Turnstile> F"
+proof (rule ccontr)
+ assume "\<not>\<not>\<nu> \<Turnstile> F"
+ then have a: "\<nu> \<Turnstile> F"
+ by blast
+ moreover have "is_nnf F"
+ using is_nnf_cnf[OF assms(1)]
+ by simp
+ moreover {
+ let ?C = "{L}"
+ have "\<not>(\<exists>L'. L' \<in> ?C \<and> lit_semantics \<nu> L')"
+ using assms(3)
+ by fast
+ then have "\<not>(\<forall>C \<in> cnf F. \<exists>L. L \<in> C \<and> lit_semantics \<nu> L)"
+ using assms(2)
+ by blast
+ hence "\<not>cnf_semantics \<nu> (cnf F)"
+ unfolding cnf_semantics_def clause_semantics_def
+ by fast
+ }
+ ultimately have "\<not> \<nu> \<Turnstile> F"
+ using cnf_semantics
+ by blast
+ thus False
+ using a
+ by blast
+qed
+
+\<comment> \<open> NOTE This follows by contraposition from the previous lemma
+\<open>not_model_if_exists_unmodeled_singleton_clause\<close>. \<close>
+corollary model_then_all_singleton_clauses_modelled:
+ assumes "is_cnf F"
+ and "{L} \<in> cnf F"
+ and "\<nu> \<Turnstile> F"
+ shows "lit_semantics \<nu> L"
+ using not_model_if_exists_unmodeled_singleton_clause[OF assms(1, 2)] assms(3)
+ by blast
+
+\<comment> \<open> NOTE This is essentially the \<open>\<Rightarrow>\<close> direction of the compactness theorem when treating CNFs as sets
+of formulas (sets of disjunctions in this case). \<close>
+lemma model_for_cnf_is_model_of_all_subsets:
+ assumes "cnf_semantics \<nu> \<F>"
+ and "\<F>' \<subseteq> \<F>"
+ shows "cnf_semantics \<nu> \<F>'"
+proof -
+ {
+ fix C
+ assume "C \<in> \<F>'"
+ then have "C \<in> \<F>"
+ using assms(2)
+ by blast
+ then have "clause_semantics \<nu> C"
+ using assms(1)
+ unfolding cnf_semantics_def
+ by blast
+ }
+ thus ?thesis
+ unfolding cnf_semantics_def
+ by blast
+qed
+
+lemma cnf_semantics_monotonous_in_cnf_subsets_if:
+ assumes "\<A> \<Turnstile> \<Phi>"
+ and "is_cnf \<Phi>"
+ and "cnf \<Phi>' \<subseteq> cnf \<Phi>"
+ shows "cnf_semantics \<A> (cnf \<Phi>')"
+proof -
+ {
+ have "is_nnf \<Phi>"
+ using is_nnf_cnf[OF assms(2)].
+ hence "cnf_semantics \<A> (cnf \<Phi>)"
+ using cnf_semantics assms(1)
+ by blast
+ }
+ thus ?thesis
+ using model_for_cnf_is_model_of_all_subsets[OF _ assms(3)]
+ by simp
+qed
+
+corollary modelling_relation_monotonous_in_cnf_subsets_if:
+ assumes "\<A> \<Turnstile> \<Phi>"
+ and "is_cnf \<Phi>"
+ and "is_cnf \<Phi>'"
+ and "cnf \<Phi>' \<subseteq> cnf \<Phi>"
+ shows "\<A> \<Turnstile> \<Phi>'"
+proof -
+ have "cnf_semantics \<A> (cnf \<Phi>')"
+ using cnf_semantics_monotonous_in_cnf_subsets_if[OF assms(1, 2, 4)].
+ thus ?thesis
+ using cnf_semantics is_nnf_cnf[OF assms(3)]
+ by blast
+qed
+
+\<comment> \<open> NOTE Show that any clause \<open>C\<close> containing a subset \<open>C\<close> for which all literals
+ \<open>L\<close> evaluate to \<open>False\<close> for the given valuation \<open>\<A>\<close>, then the clause
+ semantics evaluation can be reduced to the set \<open>C - C'\<close> where all literals of
+ \<open>C'\<close> have been removed. \<close>
+lemma lit_semantics_reducible_to_subset_if:
+ assumes "C' \<subseteq> C"
+ and "\<forall>L \<in> C'. \<not>lit_semantics \<A> L"
+ shows "clause_semantics \<A> C = clause_semantics \<A> (C - C')"
+ unfolding clause_semantics_def
+ using assms
+ by fast
+
+end
diff --git a/thys/Verified_SAT_Based_AI_Planning/CNF_Supplement.thy b/thys/Verified_SAT_Based_AI_Planning/CNF_Supplement.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/CNF_Supplement.thy
@@ -0,0 +1,104 @@
+(*
+ Author: Fred Kurz
+*)
+theory CNF_Supplement
+ imports "Propositional_Proof_Systems.CNF_Formulas_Sema"
+begin
+
+(* TODO fix warnings *)
+
+fun is_literal_formula
+ where "is_literal_formula (Atom _) = True"
+ | "is_literal_formula (\<^bold>\<not>(Atom _)) = True"
+ | "is_literal_formula _ = False"
+
+fun literal_formula_to_literal :: "'a formula \<Rightarrow> 'a literal"
+ where "literal_formula_to_literal (Atom a) = a\<^sup>+"
+ | "literal_formula_to_literal (\<^bold>\<not>(Atom a)) = a\<inverse>"
+
+lemma is_literal_formula_then_cnf_is_singleton_clause:
+ assumes "is_literal_formula f"
+ obtains C where "cnf f = { C }"
+proof -
+ consider (f_is_positive_literal) "\<exists>a. f = Atom a"
+ | (f_is_negative_literal) "\<exists>a. f = \<^bold>\<not>(Atom a)"
+ using assms is_literal_formula.elims(2)[of f]
+ by meson
+ then have "\<exists>C. cnf f = { C }"
+ proof (cases)
+ case f_is_positive_literal
+ then obtain a where "f = Atom a"
+ by force
+ then have "cnf f = {{ a\<^sup>+ }}"
+ by force
+ thus ?thesis
+ by simp
+ next
+ case f_is_negative_literal
+ then obtain a where "f = \<^bold>\<not>(Atom a)"
+ by force
+ then have "cnf f = {{ a\<inverse> }}"
+ by force
+ thus ?thesis
+ by simp
+ qed
+ thus ?thesis
+ using that
+ by presburger
+qed
+
+lemma literal_formula_to_literal_is_inverse_of_form_of_lit:
+ "literal_formula_to_literal (form_of_lit L) = L"
+ by (cases L, simp+)
+
+lemma is_nnf_cnf:
+ assumes "is_cnf F"
+ shows "is_nnf F"
+ using assms
+proof (induction F)
+ case (Or F1 F2)
+ have "is_disj (F1 \<^bold>\<or> F2)"
+ using Or.prems is_cnf.simps(5)
+ by simp
+ thus ?case
+ using disj_is_nnf
+ by blast
+qed simp+
+
+lemma cnf_of_literal_formula:
+ assumes "is_literal_formula f"
+ shows "cnf f = {{ literal_formula_to_literal f }}"
+proof -
+ consider (f_is_positive_literal) "\<exists>a. f = Atom a"
+ | (f_is_negative_literal) "\<exists>a. f = (\<^bold>\<not>(Atom a))"
+ using assms is_literal_formula.elims(2)[of f "\<exists>a. f = Atom a"]
+ is_literal_formula.elims(2)[of f "\<exists>a. f = (\<^bold>\<not>(Atom a))"]
+ by blast
+ thus ?thesis
+ by(cases, force+)
+qed
+
+lemma is_cnf_foldr_and_if:
+ assumes "\<forall>f \<in> set fs. is_cnf f"
+ shows "is_cnf (foldr (\<^bold>\<and>) fs (\<^bold>\<not>\<bottom>))"
+ using assms
+proof (induction fs)
+ case (Cons f fs)
+ have "foldr (\<^bold>\<and>) (f # fs) (\<^bold>\<not>\<bottom>) = f \<^bold>\<and> (foldr (\<^bold>\<and>) fs (\<^bold>\<not>\<bottom>))"
+ by simp
+ moreover {
+ have "\<forall>f \<in> set fs. is_cnf f"
+ using Cons.prems
+ by force
+ hence "is_cnf (foldr (\<^bold>\<and>) fs (\<^bold>\<not>\<bottom>))"
+ using Cons.IH
+ by blast
+ }
+ moreover have "is_cnf f"
+ using Cons.prems
+ by simp
+ ultimately show ?case
+ by simp
+qed simp
+
+end
\ No newline at end of file
diff --git a/thys/Verified_SAT_Based_AI_Planning/List_Supplement.thy b/thys/Verified_SAT_Based_AI_Planning/List_Supplement.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/List_Supplement.thy
@@ -0,0 +1,154 @@
+(*
+ Author: Fred Kurz
+*)
+theory List_Supplement
+imports Main
+begin
+
+lemma list_foot:
+ assumes "l \<noteq> []"
+ obtains y ys where "l = ys @ [y]"
+proof -
+ {
+ assume a: "l \<noteq> []"
+ have "\<exists>y ys. l = ys @ [y]"
+ using a
+ proof (induction l)
+ case (Cons a l)
+ then show ?case
+ proof (cases "l = []")
+ case True
+ have "[] @ [a] = a # l"
+ using True
+ by simp
+ thus ?thesis
+ using Cons.prems(1)
+ by simp
+ next
+ case False
+ thm Cons
+ then obtain y ys where "l = ys @ [y]"
+ using Cons.IH
+ by blast
+ then have "a # l = a # ys @ [y]"
+ by blast
+ thus ?thesis
+ by fastforce
+ qed
+ qed simp
+ }
+ thus ?thesis
+ using assms that
+ by blast
+qed
+
+lemma list_ex_intersection: "list_ex (\<lambda>v. list_ex ((=) v) ys) xs \<longleftrightarrow> set xs \<inter> set ys \<noteq> {}"
+proof -
+ {
+ assume "list_ex (\<lambda>v. list_ex ((=) v) ys) xs"
+ then have "\<exists>v \<in> set xs. list_ex ((=) v) ys"
+ using list_ex_iff
+ by fast
+ moreover have "\<forall>v. list_ex ((=) v) ys = (\<exists>v' \<in> set ys. v = v')"
+ using list_ex_iff
+ by blast
+ ultimately have "\<exists>v \<in> set xs. (\<exists>v' \<in> set ys. v = v')"
+ by blast
+ then obtain v v' where "v \<in> set xs" and "v' \<in> set ys" and "v = v'"
+ by blast
+ then have "set xs \<inter> set ys \<noteq> {}"
+ by blast
+ } moreover {
+ assume "set xs \<inter> set ys \<noteq> {}"
+ then obtain v v' where "v \<in> set xs" and "v' \<in> set ys" and "v = v'"
+ by blast
+ then have "list_ex (\<lambda>v. \<exists>v' \<in> set ys. v = v') xs"
+ using list_ex_iff
+ by fast
+ moreover have "\<forall>v. (\<exists>v' \<in> set ys. v = v') = list_ex ((=) v) ys"
+ using list_ex_iff
+ by blast
+ ultimately have "list_ex (\<lambda>v. list_ex ((=) v) ys) xs"
+ by force
+ } ultimately show ?thesis
+ by blast
+qed
+
+lemma length_map_upt: "length (map f [a..<b]) = b - a"
+proof -
+ have "length [a..<b] = b - a"
+ using length_upt
+ by blast
+ moreover have "length (map f [a..<b]) = length [a..<b]"
+ by simp
+ ultimately show ?thesis
+ by argo
+qed
+
+lemma not_list_ex_equals_list_all_not: "(\<not>list_ex P xs) = list_all (\<lambda>x. \<not>P x) xs"
+proof -
+ have "(\<not>list_ex P xs) = (\<not>Bex (set xs) P)"
+ using list_ex_iff
+ by blast
+ also have "\<dots> = Ball (set xs) (\<lambda>x. \<not>P x)"
+ by blast
+ finally show ?thesis
+ by (simp add: Ball_set_list_all)
+qed
+
+lemma element_of_subseqs_then_subset:
+ assumes "l \<in> set (subseqs l')"
+ shows"set l \<subseteq> set l'"
+ using assms
+proof (induction l' arbitrary: l)
+ case (Cons x l')
+ have "set (subseqs (x # l')) = (Cons x) ` set (subseqs l') \<union> set (subseqs l')"
+ unfolding subseqs.simps(2) Let_def set_map set_append..
+ then consider (A) "l \<in> (Cons x) ` set (subseqs l')"
+ | (B) "l \<in> set (subseqs l')"
+ using Cons.prems
+ by blast
+ thus ?case
+ proof (cases)
+ case A
+ then obtain l'' where "l'' \<in> set (subseqs l')" and "l = x # l''"
+ by blast
+ moreover have "set l'' \<subseteq> set l'"
+ using Cons.IH[of l'', OF calculation(1)].
+ ultimately show ?thesis
+ by auto
+ next
+ case B
+ then show ?thesis
+ using Cons.IH
+ by auto
+ qed
+qed simp
+
+(* TODO rewrite using list comprehension \<open>embed xs = [[x]. x \<leftarrow> xs]\<close> *)
+text \<open> Embed a list into a list of singleton lists. \<close>
+primrec embed :: "'a list \<Rightarrow> 'a list list"
+ where "embed [] = []"
+ | "embed (x # xs) = [x] # embed xs"
+
+lemma set_of_embed_is: "set (embed xs) = { [x] | x. x \<in> set xs }"
+ by (induction xs; force+)
+
+lemma concat_is_inverse_of_embed:
+ "concat (embed xs) = xs"
+ by (induction xs; simp)
+
+lemma embed_append[simp]: "embed (xs @ ys) = embed xs @ embed ys"
+proof (induction xs)
+ case (Cons x xs)
+ have "embed (x # xs @ ys) = [x] # embed (xs @ ys)"
+ try0
+ by simp
+ also have "\<dots> = [x] # (embed xs @ embed ys)"
+ using Cons.IH
+ by simp
+ finally show ?case
+ by fastforce
+qed simp
+
+end
diff --git a/thys/Verified_SAT_Based_AI_Planning/Map_Supplement.thy b/thys/Verified_SAT_Based_AI_Planning/Map_Supplement.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/Map_Supplement.thy
@@ -0,0 +1,146 @@
+(*
+ Author: Fred Kurz
+*)
+theory Map_Supplement
+imports Main
+begin
+
+lemma map_of_defined_if_constructed_from_list_of_constant_assignments:
+ "l = map (\<lambda>x. (x, a)) xs \<Longrightarrow> \<forall>x \<in> set xs. (map_of l) x = Some a"
+proof (induction xs arbitrary: l)
+ case (Cons x xs)
+ let ?l' = "map (\<lambda>v. (v, a)) xs"
+ from Cons.prems(1) have "l = (x, a) # map (\<lambda>v. (v, a)) xs"
+ by force
+ moreover have "\<forall>v \<in> set xs. (map_of ?l') v = Some a"
+ using Cons.IH[where l="?l'"]
+ by blast
+ ultimately show ?case
+ by auto
+qed auto
+
+\<comment> \<open> NOTE Function graph is the set of pairs (x, f x) for a (total) function f. \<close>
+\<comment> \<open> TODO Remove the first premise (follows from the second). \<close>
+lemma map_of_from_function_graph_is_some_if:
+ fixes f :: "'a \<Rightarrow> 'b"
+ assumes "set xs \<noteq> {}"
+ and "x \<in> set xs"
+ shows "(map_of (map (\<lambda>x. (x, f x)) xs)) x = Some (f x)"
+ using assms
+proof (induction xs arbitrary: f x)
+ \<comment> \<open> NOTE Base case follows trivially from violation of assumption \<open>set xs \<noteq> {}\<close>. \<close>
+ case (Cons a xs)
+ thm Cons
+ let ?m = "map_of (map (\<lambda>x. (x, f x)) xs)"
+ have a: "map_of (map (\<lambda>x. (x, f x)) (Cons a xs)) = ?m(a \<mapsto> f a)"
+ unfolding map_of_def
+ by simp
+ thus ?case
+ proof(cases "x = a")
+ case False
+ thus ?thesis
+ proof (cases "set xs = {}")
+ \<comment> \<open> NOTE Follows from contradiction (\<open>x \<in> set (Cons a xs) \<and> set xs = {} \<and> x \<noteq> a \<equiv> \<bottom>\<close>)\<close>
+ case True
+ thus ?thesis
+ using Cons.prems(2)
+ by fastforce
+ next
+ case False
+ then have "x \<in> set xs"
+ using \<open>x \<noteq> a\<close> Cons.prems(2)
+ by fastforce
+ moreover have "map_of (map (\<lambda>x. (x, f x)) (Cons a xs)) x = ?m x"
+ using \<open>x \<noteq> a\<close>
+ by fastforce
+ ultimately show ?thesis
+ using Cons.IH[OF False]
+ by presburger
+ qed
+ qed force
+ qed blast
+
+lemma foldl_map_append_is_some_if:
+ assumes "b x = Some y \<or> (\<exists>m \<in> set ms. m x = Some y)"
+ and "\<forall>m' \<in> set ms. m' x = Some y \<or> m' x = None"
+ shows "foldl (++) b ms x = Some y"
+using assms
+proof (induction ms arbitrary: b)
+ \<comment> \<open> NOTE Induction base case violates first assumption (we have at least one element in ms
+ and hence \<open>ms \<noteq> []\<close>). \<close>
+ case (Cons a ms)
+ consider (b_is_some_y) "b x = Some y"
+ | (m_is_some_y) "\<exists>m \<in> set (a # ms). m x = Some y"
+ using Cons.prems(1)
+ by blast
+ hence "(b ++ a) x = Some y \<or> (\<exists>m\<in>set ms. m x = Some y)"
+ proof (cases)
+ case b_is_some_y
+ moreover have "a x = Some y \<or> a x = None"
+ using Cons.prems(2)
+ by simp
+ ultimately show ?thesis
+ using map_add_Some_iff[of b a x y]
+ by blast
+ next
+ case m_is_some_y
+ then show ?thesis
+ proof (cases "a x = Some y")
+ case False
+ then obtain m where "m \<in> set ms" and "m x = Some y"
+ using m_is_some_y try0
+ by auto
+ thus ?thesis
+ by blast
+ qed simp
+ qed
+ moreover have "\<forall>m' \<in> set ms. m' x = Some y \<or> m' x = None"
+ using Cons.prems(2)
+ by fastforce
+ ultimately show ?case using Cons.IH[where b="b ++ a"]
+ by simp
+qed auto
+
+(* TODO "\<forall>(v, a) \<in> set l. \<forall>(v', a') \<in> set l. v \<noteq> v' \<or> a = a'" \<leadsto>
+ "\<forall>(v', a') \<in> set l. v \<noteq> v' \<or> a = a'" (this is too strong; we only consider (v, a), i.e. fixed v)
+*)
+(* TODO isn't this the same as map_of_is_SomeI? *)
+lemma map_of_constant_assignments_defined_if:
+ assumes "\<forall>(v, a) \<in> set l. \<forall>(v', a') \<in> set l. v \<noteq> v' \<or> a = a'"
+ and "(v, a) \<in> set l"
+ shows "map_of l v = Some a"
+ using assms
+proof (induction l)
+ case (Cons x l)
+ thm Cons
+ then show ?case
+ proof (cases "x = (v, a)")
+ case False
+ have v_a_in_l: "(v, a) \<in> set l"
+ using Cons.prems(2) False
+ by fastforce
+ {
+ have "\<forall>(v, a) \<in> set l. \<forall>(v', a') \<in> set l. v \<noteq> v' \<or> a = a'"
+ using Cons.prems(1)
+ by auto
+ hence "map_of l v = Some a"
+ using Cons.IH v_a_in_l
+ by linarith
+ } note ih = this
+ {
+ have "x \<in> set (x # l)"
+ by auto
+ hence "fst x \<noteq> v \<or> snd x = a"
+ using Cons.prems(1) v_a_in_l
+ by fastforce
+ } note nb = this
+ \<comment> \<open> NOTE If @{text "fst x = v"} then @{text "snd x = a"} by fact @{text "nb"}; moreover if
+ on the other hand @{text "fst x \<noteq> v"}, then the proposition follows from the induction
+ hypothesis since @{text "map_of (x # l) v = map_of l v"} in that case. \<close>
+ thus ?thesis
+ using ih nb
+ by (cases "fst x = v") fastforce+
+ qed simp
+qed fastforce
+
+end
\ No newline at end of file
diff --git a/thys/Verified_SAT_Based_AI_Planning/ROOT b/thys/Verified_SAT_Based_AI_Planning/ROOT
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/ROOT
@@ -0,0 +1,28 @@
+chapter AFP
+
+session Verified_SAT_Based_AI_Planning (AFP) = HOL +
+ description {* Verified SAT-Based AI Planning *}
+ options [timeout = 600]
+ sessions
+ "HOL-Data_Structures"
+ "AI_Planning_Languages_Semantics"
+ "Propositional_Proof_Systems"
+ "List-Index"
+ theories [document = false]
+ "List_Supplement"
+ "Map_Supplement"
+ "CNF_Supplement"
+ "CNF_Semantics_Supplement"
+ theories
+ "SAS_Plus_STRIPS"
+ "STRIPS_Representation"
+ "STRIPS_Semantics"
+ "SAS_Plus_Representation"
+ "SAS_Plus_Semantics"
+ "SAT_Plan_Base"
+ "SAT_Plan_Extensions"
+ "SAT_Solve_SAS_Plus"
+ "Solve_SASP"
+ document_files
+ "root.tex"
+ "root.bib"
diff --git a/thys/Verified_SAT_Based_AI_Planning/SAS_Plus_Representation.thy b/thys/Verified_SAT_Based_AI_Planning/SAS_Plus_Representation.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/SAS_Plus_Representation.thy
@@ -0,0 +1,267 @@
+(*
+ Author: Mohammad Abdulaziz, Fred Kurz
+*)
+theory SAS_Plus_Representation
+imports State_Variable_Representation
+begin
+
+section "SAS+ Representation"
+
+text \<open> We now continue by defining a concrete implementation of SAS+.\<close>
+
+text \<open> SAS+ operators and SAS+ problems again use records. In contrast to STRIPS, the operator
+effect is contracted into a single list however since we now potentially deal with more than two
+possible values for each problem variable. \<close>
+
+record ('variable, 'domain) sas_plus_operator =
+ precondition_of :: "('variable, 'domain) assignment list"
+ effect_of :: "('variable, 'domain) assignment list"
+
+record ('variable, 'domain) sas_plus_problem =
+ variables_of :: "'variable list" ("(_\<^sub>\<V>\<^sub>+)" [1000] 999)
+ operators_of :: "('variable, 'domain) sas_plus_operator list" ("(_\<^sub>\<O>\<^sub>+)" [1000] 999)
+ initial_of :: "('variable, 'domain) state" ("(_\<^sub>I\<^sub>+)" [1000] 999)
+ goal_of :: "('variable, 'domain) state" ("(_\<^sub>G\<^sub>+)" [1000] 999)
+ range_of :: "'variable \<rightharpoonup> 'domain list"
+
+definition range_of':: "('variable, 'domain) sas_plus_problem \<Rightarrow> 'variable \<Rightarrow> 'domain set" ("\<R>\<^sub>+ _ _" 52)
+ where
+ "range_of' \<Psi> v \<equiv>
+ (case sas_plus_problem.range_of \<Psi> v of None \<Rightarrow> {}
+ | Some as \<Rightarrow> set as)"
+
+definition to_precondition
+ :: "('variable, 'domain) sas_plus_operator \<Rightarrow> ('variable, 'domain) assignment list"
+ where "to_precondition \<equiv> precondition_of"
+
+definition to_effect
+ :: "('variable, 'domain) sas_plus_operator \<Rightarrow> ('variable, 'domain) Effect"
+ where "to_effect op \<equiv> [(v, a) . (v, a) \<leftarrow> effect_of op]"
+
+type_synonym ('variable, 'domain) sas_plus_plan
+ = "('variable, 'domain) sas_plus_operator list"
+
+type_synonym ('variable, 'domain) sas_plus_parallel_plan
+ = "('variable, 'domain) sas_plus_operator list list"
+
+abbreviation empty_operator
+ :: "('variable, 'domain) sas_plus_operator" ("\<rho>")
+ where "empty_operator \<equiv> \<lparr> precondition_of = [], effect_of = [] \<rparr>"
+
+definition is_valid_operator_sas_plus
+ :: "('variable, 'domain) sas_plus_problem \<Rightarrow> ('variable, 'domain) sas_plus_operator \<Rightarrow> bool"
+ where "is_valid_operator_sas_plus \<Psi> op \<equiv> let
+ pre = precondition_of op
+ ; eff = effect_of op
+ ; vs = variables_of \<Psi>
+ ; D = range_of \<Psi>
+ in list_all (\<lambda>(v, a). ListMem v vs) pre
+ \<and> list_all (\<lambda>(v, a). (D v \<noteq> None) \<and> ListMem a (the (D v))) pre
+ \<and> list_all (\<lambda>(v, a). ListMem v vs) eff
+ \<and> list_all (\<lambda>(v, a). (D v \<noteq> None) \<and> ListMem a (the (D v))) eff
+ \<and> list_all (\<lambda>(v, a). list_all (\<lambda>(v', a'). v \<noteq> v' \<or> a = a') pre) pre
+ \<and> list_all (\<lambda>(v, a). list_all (\<lambda>(v', a'). v \<noteq> v' \<or> a = a') eff) eff"
+
+definition "is_valid_problem_sas_plus \<Psi>
+ \<equiv> let ops = operators_of \<Psi>
+ ; vs = variables_of \<Psi>
+ ; I = initial_of \<Psi>
+ ; G = goal_of \<Psi>
+ ; D = range_of \<Psi>
+ in list_all (\<lambda>v. D v \<noteq> None) vs
+ \<and> list_all (is_valid_operator_sas_plus \<Psi>) ops
+ \<and> (\<forall>v. I v \<noteq> None \<longleftrightarrow> ListMem v vs)
+ \<and> (\<forall>v. I v \<noteq> None \<longrightarrow> ListMem (the (I v)) (the (D v)))
+ \<and> (\<forall>v. G v \<noteq> None \<longrightarrow> ListMem v (variables_of \<Psi>))
+ \<and> (\<forall>v. G v \<noteq> None \<longrightarrow> ListMem (the (G v)) (the (D v)))"
+
+definition is_operator_applicable_in
+ :: "('variable, 'domain) state
+ \<Rightarrow> ('variable, 'domain) sas_plus_operator
+ \<Rightarrow> bool"
+ where "is_operator_applicable_in s op
+ \<equiv> map_of (precondition_of op) \<subseteq>\<^sub>m s"
+
+(* TODO rename execute_operator_in *)
+definition execute_operator_sas_plus
+ :: "('variable, 'domain) state
+ \<Rightarrow> ('variable, 'domain) sas_plus_operator
+ \<Rightarrow> ('variable, 'domain) state" (infixl "\<then>\<^sub>+" 52)
+ where "execute_operator_sas_plus s op \<equiv> s ++ map_of (effect_of op)"
+
+\<comment> \<open> Set up simp rules to keep use of local parameters transparent within proofs (i.e.
+automatically substitute definitions). \<close>
+lemma[simp]:
+ "is_operator_applicable_in s op = (map_of (precondition_of op) \<subseteq>\<^sub>m s)"
+ "s \<then>\<^sub>+ op = s ++ map_of (effect_of op)"
+ unfolding initial_of_def goal_of_def variables_of_def range_of_def operators_of_def
+ SAS_Plus_Representation.is_operator_applicable_in_def
+ SAS_Plus_Representation.execute_operator_sas_plus_def
+ by simp+
+
+lemma range_of_not_empty:
+ "(sas_plus_problem.range_of \<Psi> v \<noteq> None \<and> sas_plus_problem.range_of \<Psi> v \<noteq> Some [])
+ \<longleftrightarrow> (\<R>\<^sub>+ \<Psi> v) \<noteq> {}"
+ apply (cases "sas_plus_problem.range_of \<Psi> v")
+ by (auto simp add: SAS_Plus_Representation.range_of'_def)
+
+lemma is_valid_operator_sas_plus_then:
+ fixes \<Psi>::"('v,'d) sas_plus_problem"
+ assumes "is_valid_operator_sas_plus \<Psi> op"
+ shows "\<forall>(v, a) \<in> set (precondition_of op). v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>(v, a) \<in> set (precondition_of op). (\<R>\<^sub>+ \<Psi> v) \<noteq> {} \<and> a \<in> \<R>\<^sub>+ \<Psi> v"
+ and "\<forall>(v, a) \<in> set (effect_of op). v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>(v, a) \<in> set (effect_of op). (\<R>\<^sub>+ \<Psi> v) \<noteq> {} \<and> a \<in> \<R>\<^sub>+ \<Psi> v"
+ and "\<forall>(v, a) \<in> set (precondition_of op). \<forall>(v', a') \<in> set (precondition_of op). v \<noteq> v' \<or> a = a'"
+ and "\<forall>(v, a) \<in> set (effect_of op).
+ \<forall>(v', a') \<in> set (effect_of op). v \<noteq> v' \<or> a = a'"
+proof -
+ let ?vs = "sas_plus_problem.variables_of \<Psi>"
+ and ?pre = "precondition_of op"
+ and ?eff = "effect_of op"
+ and ?D = "sas_plus_problem.range_of \<Psi>"
+ have "\<forall>(v, a)\<in>set ?pre. v \<in> set ?vs"
+ and "\<forall>(v, a)\<in>set ?pre.
+ (?D v \<noteq> None) \<and>
+ a \<in> set (the (?D v))"
+ and "\<forall>(v, a)\<in>set ?eff. v \<in> set ?vs"
+ and "\<forall>(v, a)\<in>set ?eff.
+ (?D v \<noteq> None) \<and>
+ a \<in> set (the (?D v))"
+ and "\<forall>(v, a)\<in>set ?pre.
+ \<forall>(v', a')\<in>set ?pre. v \<noteq> v' \<or> a = a'"
+ and "\<forall>(v, a)\<in>set ?eff.
+ \<forall>(v', a')\<in>set ?eff. v \<noteq> v' \<or> a = a'"
+ using assms
+ unfolding is_valid_operator_sas_plus_def Let_def list_all_iff ListMem_iff
+ by meson+
+ moreover have "\<forall>(v, a) \<in> set ?pre. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>(v, a) \<in> set ?eff. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>(v, a) \<in> set ?pre. \<forall>(v', a') \<in> set ?pre. v \<noteq> v' \<or> a = a'"
+ and "\<forall>(v, a) \<in> set ?eff. \<forall>(v', a') \<in> set ?eff. v \<noteq> v' \<or> a = a'"
+ using calculation
+ unfolding variables_of_def
+ by blast+
+ moreover {
+ have "\<forall>(v, a) \<in> set ?pre. (?D v \<noteq> None) \<and> a \<in> set (the (?D v))"
+ using assms
+ unfolding is_valid_operator_sas_plus_def Let_def list_all_iff ListMem_iff
+ by argo
+ hence "\<forall>(v, a) \<in> set ?pre. ((\<R>\<^sub>+ \<Psi> v) \<noteq> {}) \<and> a \<in> \<R>\<^sub>+ \<Psi> v"
+ using range_of'_def
+ by fastforce
+ }
+ moreover {
+ have "\<forall>(v, a) \<in> set ?eff. (?D v \<noteq> None) \<and> a \<in> set (the (?D v))"
+ using assms
+ unfolding is_valid_operator_sas_plus_def Let_def list_all_iff ListMem_iff
+ by argo
+ hence "\<forall>(v, a) \<in> set ?eff. ((\<R>\<^sub>+ \<Psi> v) \<noteq> {}) \<and> a \<in> \<R>\<^sub>+ \<Psi> v"
+ using range_of'_def
+ by fastforce
+ }
+ ultimately show "\<forall>(v, a) \<in> set (precondition_of op). v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>(v, a) \<in> set (precondition_of op). (\<R>\<^sub>+ \<Psi> v) \<noteq> {} \<and> a \<in> \<R>\<^sub>+ \<Psi> v"
+ and "\<forall>(v, a) \<in> set (effect_of op). v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>(v, a) \<in> set (effect_of op). (\<R>\<^sub>+ \<Psi> v) \<noteq> {} \<and> a \<in> \<R>\<^sub>+ \<Psi> v"
+ and "\<forall>(v, a) \<in> set (precondition_of op). \<forall>(v', a') \<in> set (precondition_of op). v \<noteq> v' \<or> a = a'"
+ and "\<forall>(v, a) \<in> set (effect_of op).
+ \<forall>(v', a') \<in> set (effect_of op). v \<noteq> v' \<or> a = a'"
+ by blast+
+qed
+
+(* TODO can be replaced by proof for sublocale? *)
+lemma is_valid_problem_sas_plus_then:
+ fixes \<Psi>::"('v,'d) sas_plus_problem"
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "\<forall>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). (\<R>\<^sub>+ \<Psi> v) \<noteq> {}"
+ and "\<forall>op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+). is_valid_operator_sas_plus \<Psi> op"
+ and "dom ((\<Psi>)\<^sub>I\<^sub>+) = set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom ((\<Psi>)\<^sub>I\<^sub>+). the (((\<Psi>)\<^sub>I\<^sub>+) v) \<in> \<R>\<^sub>+ \<Psi> v"
+ and "dom ((\<Psi>)\<^sub>G\<^sub>+) \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom ((\<Psi>)\<^sub>G\<^sub>+). the (((\<Psi>)\<^sub>G\<^sub>+) v) \<in> \<R>\<^sub>+ \<Psi> v"
+proof -
+ let ?vs = "sas_plus_problem.variables_of \<Psi>"
+ and ?ops = "sas_plus_problem.operators_of \<Psi>"
+ and ?I = "sas_plus_problem.initial_of \<Psi>"
+ and ?G = "sas_plus_problem.goal_of \<Psi>"
+ and ?D = "sas_plus_problem.range_of \<Psi>"
+ {
+ fix v
+ have "(?D v \<noteq> None \<and> ?D v \<noteq> Some []) \<longleftrightarrow> ((\<R>\<^sub>+ \<Psi> v) \<noteq> {})"
+ by (cases "?D v"; (auto simp: range_of'_def))
+ } note nb = this
+ have nb\<^sub>1: "\<forall>v \<in> set ?vs. ?D v \<noteq> None"
+ and "\<forall>op \<in> set ?ops. is_valid_operator_sas_plus \<Psi> op"
+ and "\<forall>v. (?I v \<noteq> None) = (v \<in> set ?vs)"
+ and nb\<^sub>2: "\<forall>v. ?I v \<noteq> None \<longrightarrow> the (?I v) \<in> set (the (?D v))"
+ and "\<forall>v. ?G v \<noteq> None \<longrightarrow> v \<in> set ?vs"
+ and nb\<^sub>3: "\<forall>v. ?G v \<noteq> None \<longrightarrow> the (?G v) \<in> set (the (?D v))"
+ using assms
+ unfolding SAS_Plus_Representation.is_valid_problem_sas_plus_def Let_def
+ list_all_iff ListMem_iff
+ by argo+
+ then have G3: "\<forall>op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+). is_valid_operator_sas_plus \<Psi> op"
+ and G4: "dom ((\<Psi>)\<^sub>I\<^sub>+) = set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and G5: "dom ((\<Psi>)\<^sub>G\<^sub>+) \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ unfolding variables_of_def operators_of_def
+ by auto+
+ moreover {
+ fix v
+ assume "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ then have "?D v \<noteq> None"
+ using nb\<^sub>1
+ by force+
+ } note G6 = this
+ moreover {
+ fix v
+ assume "v \<in> dom ((\<Psi>)\<^sub>I\<^sub>+)"
+ moreover have "((\<Psi>)\<^sub>I\<^sub>+) v \<noteq> None"
+ using calculation
+ by blast+
+ moreover {
+ have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using G4 calculation(1)
+ by argo
+ then have "sas_plus_problem.range_of \<Psi> v \<noteq> None"
+ using range_of_not_empty
+ unfolding range_of'_def
+ using G6
+ by fast+
+ hence "set (the (?D v)) = \<R>\<^sub>+ \<Psi> v"
+ by (simp add: \<open>sas_plus_problem.range_of \<Psi> v \<noteq> None\<close> option.case_eq_if range_of'_def)
+ }
+ ultimately have "the (((\<Psi>)\<^sub>I\<^sub>+) v) \<in> \<R>\<^sub>+ \<Psi> v"
+ using nb\<^sub>2
+ by force
+ }
+ moreover {
+ fix v
+ assume "v \<in> dom ((\<Psi>)\<^sub>G\<^sub>+)"
+ then have "((\<Psi>)\<^sub>G\<^sub>+) v \<noteq> None"
+ by blast
+ moreover {
+ have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using G5 calculation(1)
+ by fast
+ then have "sas_plus_problem.range_of \<Psi> v \<noteq> None"
+ using range_of_not_empty
+ using G6
+ by fast+
+ hence "set (the (?D v)) = \<R>\<^sub>+ \<Psi> v"
+ by (simp add: \<open>sas_plus_problem.range_of \<Psi> v \<noteq> None\<close> option.case_eq_if range_of'_def)
+ }
+ ultimately have "the (((\<Psi>)\<^sub>G\<^sub>+) v) \<in> \<R>\<^sub>+ \<Psi> v"
+ using nb\<^sub>3
+ by auto
+ }
+ ultimately show "\<forall>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). (\<R>\<^sub>+ \<Psi> v) \<noteq> {}"
+ and "\<forall>op \<in> set((\<Psi>)\<^sub>\<O>\<^sub>+). is_valid_operator_sas_plus \<Psi> op"
+ and "dom ((\<Psi>)\<^sub>I\<^sub>+) = set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom ((\<Psi>)\<^sub>I\<^sub>+). the (((\<Psi>)\<^sub>I\<^sub>+) v) \<in> \<R>\<^sub>+ \<Psi> v"
+ and "dom ((\<Psi>)\<^sub>G\<^sub>+) \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom ((\<Psi>)\<^sub>G\<^sub>+). the (((\<Psi>)\<^sub>G\<^sub>+) v) \<in> \<R>\<^sub>+ \<Psi> v"
+ by blast+
+qed
+
+end
\ No newline at end of file
diff --git a/thys/Verified_SAT_Based_AI_Planning/SAS_Plus_STRIPS.thy b/thys/Verified_SAT_Based_AI_Planning/SAS_Plus_STRIPS.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/SAS_Plus_STRIPS.thy
@@ -0,0 +1,4403 @@
+(*
+ Author: Mohammad Abdulaziz, Fred Kurz
+*)
+theory SAS_Plus_STRIPS
+ imports "STRIPS_Semantics" "SAS_Plus_Semantics"
+ "Map_Supplement"
+begin
+
+section "SAS+/STRIPS Equivalence"
+
+text \<open> The following part is concerned with showing the equivalent expressiveness of SAS+ and
+STRIPS as discussed in \autoref{sub:equivalence-sas-plus-strips}. \<close>
+
+subsection "Translation of SAS+ Problems to STRIPS Problems"
+
+definition possible_assignments_for
+ :: "('variable, 'domain) sas_plus_problem \<Rightarrow> 'variable \<Rightarrow> ('variable \<times> 'domain) list"
+ where "possible_assignments_for \<Psi> v \<equiv> [(v, a). a \<leftarrow> the (range_of \<Psi> v)]"
+
+definition all_possible_assignments_for
+ :: "('variable, 'domain) sas_plus_problem \<Rightarrow> ('variable \<times> 'domain) list"
+ where "all_possible_assignments_for \<Psi>
+ \<equiv> concat [possible_assignments_for \<Psi> v. v \<leftarrow> variables_of \<Psi>]"
+
+definition state_to_strips_state
+ :: "('variable, 'domain) sas_plus_problem
+ \<Rightarrow> ('variable, 'domain) state
+ \<Rightarrow> ('variable, 'domain) assignment strips_state"
+ ("\<phi>\<^sub>S _ _" 99)
+ where "state_to_strips_state \<Psi> s
+ \<equiv> let defined = filter (\<lambda>v. s v \<noteq> None) (variables_of \<Psi>) in
+ map_of (map (\<lambda>(v, a). ((v, a), the (s v) = a))
+ (concat [possible_assignments_for \<Psi> v. v \<leftarrow> defined]))"
+
+definition sasp_op_to_strips
+ :: "('variable, 'domain) sas_plus_problem
+ \<Rightarrow> ('variable, 'domain) sas_plus_operator
+ \<Rightarrow> ('variable, 'domain) assignment strips_operator"
+ ("\<phi>\<^sub>O _ _" 99)
+ where "sasp_op_to_strips \<Psi> op \<equiv> let
+ pre = precondition_of op
+ ; add = effect_of op
+ ; delete = [(v, a'). (v, a) \<leftarrow> effect_of op, a' \<leftarrow> filter ((\<noteq>) a) (the (range_of \<Psi> v))]
+ in STRIPS_Representation.operator_for pre add delete"
+
+definition sas_plus_problem_to_strips_problem
+ :: "('variable, 'domain) sas_plus_problem \<Rightarrow> ('variable, 'domain) assignment strips_problem"
+ ("\<phi> _ " 99)
+ where "sas_plus_problem_to_strips_problem \<Psi> \<equiv> let
+ vs = [as. v \<leftarrow> variables_of \<Psi>, as \<leftarrow> (possible_assignments_for \<Psi>) v]
+ ; ops = map (sasp_op_to_strips \<Psi>) (operators_of \<Psi>)
+ ; I = state_to_strips_state \<Psi> (initial_of \<Psi>)
+ ; G = state_to_strips_state \<Psi> (goal_of \<Psi>)
+ in STRIPS_Representation.problem_for vs ops I G"
+
+definition sas_plus_parallel_plan_to_strips_parallel_plan
+ :: "('variable, 'domain) sas_plus_problem
+ \<Rightarrow> ('variable, 'domain) sas_plus_parallel_plan
+ \<Rightarrow> ('variable \<times> 'domain) strips_parallel_plan"
+ ("\<phi>\<^sub>P _ _" 99)
+ where "sas_plus_parallel_plan_to_strips_parallel_plan \<Psi> \<psi>
+ \<equiv> [[sasp_op_to_strips \<Psi> op. op \<leftarrow> ops]. ops \<leftarrow> \<psi>]"
+
+(* TODO first argument should be ('variable, 'domain) strips_problem *)
+definition strips_state_to_state
+ :: "('variable, 'domain) sas_plus_problem
+ \<Rightarrow> ('variable, 'domain) assignment strips_state
+ \<Rightarrow> ('variable, 'domain) state"
+ ("\<phi>\<^sub>S\<inverse> _ _" 99)
+ where "strips_state_to_state \<Psi> s
+ \<equiv> map_of (filter (\<lambda>(v, a). s (v, a) = Some True) (all_possible_assignments_for \<Psi>))"
+
+(* TODO remove problem argument *)
+definition strips_op_to_sasp
+ :: "('variable, 'domain) sas_plus_problem
+ \<Rightarrow> ('variable \<times> 'domain) strips_operator
+ \<Rightarrow> ('variable, 'domain) sas_plus_operator"
+ ("\<phi>\<^sub>O\<inverse> _ _" 99)
+ where "strips_op_to_sasp \<Psi> op
+ \<equiv> let
+ precondition = strips_operator.precondition_of op
+ ; effect = strips_operator.add_effects_of op
+ in \<lparr> precondition_of = precondition, effect_of = effect \<rparr>"
+
+(* TODO \<open>strips_parallel_plan_to_sas_plus_parallel_plan \<leadsto> \<phi>_P\<inverse>\<close> and
+\<open>strips_op_to_sasp \<leadsto> \<phi>_O\<inverse>\<close> *)
+definition strips_parallel_plan_to_sas_plus_parallel_plan
+ :: "('variable, 'domain) sas_plus_problem
+ \<Rightarrow> ('variable \<times> 'domain) strips_parallel_plan
+ \<Rightarrow> ('variable, 'domain) sas_plus_parallel_plan"
+ ("\<phi>\<^sub>P\<inverse> _ _" 99)
+ where "strips_parallel_plan_to_sas_plus_parallel_plan \<Pi> \<pi>
+ \<equiv> [[strips_op_to_sasp \<Pi> op. op \<leftarrow> ops]. ops \<leftarrow> \<pi>]"
+
+text \<open> To set up the equivalence proof context, we declare a common locale
+\isaname{sas_plus_strips_equivalence} for both the STRIPS and SAS+ formalisms and make it a
+sublocale of both locale \isaname{strips} as well as \isaname{sas_plus}.
+The declaration itself is omitted for brevity since it basically just joins locales
+\isaname{sas_plus} and \isaname{strips} while renaming the locale parameter to avoid name clashes.
+The sublocale proofs are shown below.
+\footnote{We append a suffix identifying the respective formalism to the the parameter names
+passed to the parameter names in the locale. This is necessary to avoid ambiguous names in the
+sublocale declarations. For example, without addition of suffixes the type for \<open>initial_of\<close> is
+ambiguous and will therefore not be bound to either \<open>strips_problem.initial_of\<close> or
+\<open>sas_plus_problem.initial_of\<close>.
+Isabelle in fact considers it to be a a free variable in this case. We also qualify the parent
+locales in the sublocale declarations by adding \texttt{strips:} and \texttt{sas\_plus:} before
+the respective parent locale identifiers. } \<close>
+
+definition "range_of_strips \<Pi> x \<equiv> { True, False }"
+
+context
+begin
+
+\<comment> \<open> Set-up simp rules. \<close>
+lemma[simp]:
+ "(\<phi> \<Psi>) = (let
+ vs = [as. v \<leftarrow> variables_of \<Psi>, as \<leftarrow> (possible_assignments_for \<Psi>) v]
+ ; ops = map (sasp_op_to_strips \<Psi>) (operators_of \<Psi>)
+ ; I = state_to_strips_state \<Psi> (initial_of \<Psi>)
+ ; G = state_to_strips_state \<Psi> (goal_of \<Psi>)
+ in STRIPS_Representation.problem_for vs ops I G)"
+ and "(\<phi>\<^sub>S \<Psi> s)
+ = (let defined = filter (\<lambda>v. s v \<noteq> None) (variables_of \<Psi>) in
+ map_of (map (\<lambda>(v, a). ((v, a), the (s v) = a))
+ (concat [possible_assignments_for \<Psi> v. v \<leftarrow> defined])))"
+ and "(\<phi>\<^sub>O \<Psi> op)
+ = (let
+ pre = precondition_of op
+ ; add = effect_of op
+ ; delete = [(v, a'). (v, a) \<leftarrow> effect_of op, a' \<leftarrow> filter ((\<noteq>) a) (the (range_of \<Psi> v))]
+ in STRIPS_Representation.operator_for pre add delete)"
+ and "(\<phi>\<^sub>P \<Psi> \<psi>) = [[\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]. ops \<leftarrow> \<psi>]"
+ and "(\<phi>\<^sub>S\<inverse> \<Psi> s')= map_of (filter (\<lambda>(v, a). s' (v, a) = Some True)
+ (all_possible_assignments_for \<Psi>))"
+ and "(\<phi>\<^sub>O\<inverse> \<Psi> op') = (let
+ precondition = strips_operator.precondition_of op'
+ ; effect = strips_operator.add_effects_of op'
+ in \<lparr> precondition_of = precondition, effect_of = effect \<rparr>)"
+ and "(\<phi>\<^sub>P\<inverse> \<Psi> \<pi>) = [[\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> ops]. ops \<leftarrow> \<pi>]"
+ unfolding
+ SAS_Plus_STRIPS.sas_plus_problem_to_strips_problem_def
+ sas_plus_problem_to_strips_problem_def
+ SAS_Plus_STRIPS.state_to_strips_state_def
+ state_to_strips_state_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sas_plus_parallel_plan_to_strips_parallel_plan_def
+ sas_plus_parallel_plan_to_strips_parallel_plan_def
+ SAS_Plus_STRIPS.strips_state_to_state_def
+ strips_state_to_state_def
+ SAS_Plus_STRIPS.strips_op_to_sasp_def
+ strips_op_to_sasp_def
+ SAS_Plus_STRIPS.strips_parallel_plan_to_sas_plus_parallel_plan_def
+ strips_parallel_plan_to_sas_plus_parallel_plan_def
+ by blast+
+
+lemmas [simp] = range_of'_def
+
+lemma is_valid_problem_sas_plus_dom_sas_plus_problem_range_of:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "\<forall>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). v \<in> dom (sas_plus_problem.range_of \<Psi>)"
+ using assms(1) is_valid_problem_sas_plus_then(1)
+ unfolding is_valid_problem_sas_plus_def
+ by (meson domIff list.pred_set)
+
+lemma possible_assignments_for_set_is:
+ assumes "v \<in> dom (sas_plus_problem.range_of \<Psi>)"
+ shows "set (possible_assignments_for \<Psi> v)
+ = { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v }"
+proof -
+ have "sas_plus_problem.range_of \<Psi> v \<noteq> None"
+ using assms(1)
+ by auto
+ thus ?thesis
+ unfolding possible_assignments_for_def
+ by fastforce
+qed
+
+lemma all_possible_assignments_for_set_is:
+ assumes "\<forall>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). range_of \<Psi> v \<noteq> None"
+ shows "set (all_possible_assignments_for \<Psi>)
+ = (\<Union>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ have "set (all_possible_assignments_for \<Psi>) =
+ (\<Union>(set ` (\<lambda>v. map (\<lambda>(v, a). (v, a)) (possible_assignments_for \<Psi> v)) ` set ?vs))"
+ unfolding all_possible_assignments_for_def set_concat
+ using set_map
+ by auto
+ also have "\<dots> = (\<Union>((\<lambda>v. set (possible_assignments_for \<Psi> v)) ` set ?vs))"
+ using image_comp set_map
+ by simp
+ (* TODO slow *)
+ also have "\<dots> = (\<Union>((\<lambda>v. { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v }) ` set ?vs))"
+ using possible_assignments_for_set_is assms
+ by fastforce
+ finally show ?thesis
+ by force
+qed
+
+lemma state_to_strips_state_dom_is_i[simp]:
+ assumes "\<forall>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). v \<in> dom (sas_plus_problem.range_of \<Psi>)"
+ shows "set (concat
+ [possible_assignments_for \<Psi> v. v \<leftarrow> filter (\<lambda>v. s v \<noteq> None) (variables_of \<Psi>)])
+ = (\<Union>v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None }.
+ { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ let ?defined = "filter (\<lambda>v. s v \<noteq> None) ?vs"
+ let ?l = "concat [possible_assignments_for \<Psi> v. v \<leftarrow> ?defined]"
+ have nb: "set ?defined = { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None }"
+ unfolding set_filter
+ by force
+ have "set ?l = \<Union>(set ` set (map (possible_assignments_for \<Psi>) ?defined ))"
+ unfolding set_concat image_Union
+ by blast
+ also have "\<dots> = \<Union>(set ` (possible_assignments_for \<Psi>) ` set ?defined)"
+ unfolding set_map
+ by blast
+ also have "\<dots> = (\<Union>v \<in> set ?defined. set (possible_assignments_for \<Psi> v))"
+ by blast
+ also have "\<dots> = (\<Union>v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None }.
+ set (possible_assignments_for \<Psi> v))"
+ using nb
+ by argo
+ finally show ?thesis
+ using possible_assignments_for_set_is
+ is_valid_problem_sas_plus_dom_sas_plus_problem_range_of assms(1)
+ by fastforce
+qed
+
+lemma state_to_strips_state_dom_is:
+ \<comment> \<open> NOTE A transformed state is defined on all possible assignments for all variables defined
+in the original state. \<close>
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "dom (\<phi>\<^sub>S \<Psi> s)
+ = (\<Union>v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None }.
+ { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ let ?l = "concat [possible_assignments_for \<Psi> v. v \<leftarrow> filter (\<lambda>v. s v \<noteq> None) ?vs]"
+ have nb: "\<forall>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). v \<in> dom (sas_plus_problem.range_of \<Psi>)"
+ using is_valid_problem_sas_plus_dom_sas_plus_problem_range_of assms(1)
+ by fastforce
+ have "dom (\<phi>\<^sub>S \<Psi> s) = fst ` set (map (\<lambda>(v, a). ((v, a), the (s v) = a)) ?l)"
+ unfolding state_to_strips_state_def
+ SAS_Plus_STRIPS.state_to_strips_state_def
+ using dom_map_of_conv_image_fst[of "map (\<lambda>(v, a). ((v, a), the (s v) = a)) ?l"]
+ by presburger
+ also have "\<dots> = fst ` (\<lambda>(v, a). ((v, a), the (s v) = a)) ` set ?l"
+ unfolding set_map
+ by blast
+ also have "\<dots> = (\<lambda>(v, a). fst ((v, a), the (s v) = a)) ` set ?l"
+ unfolding image_comp[of fst "\<lambda>(v, a). ((v, a), the (s v) = a)"] comp_apply[of
+ fst "\<lambda>(v, a). ((v, a), the (s v) = a)"] prod.case_distrib
+ by blast
+ finally show ?thesis
+ unfolding state_to_strips_state_dom_is_i[OF nb]
+ by force
+qed
+
+corollary state_to_strips_state_dom_element_iff:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "(v, a) \<in> dom (\<phi>\<^sub>S \<Psi> s) \<longleftrightarrow> v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)
+ \<and> s v \<noteq> None
+ \<and> a \<in> \<R>\<^sub>+ \<Psi> v"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?s' = "\<phi>\<^sub>S \<Psi> s"
+ show ?thesis
+ proof (rule iffI)
+ assume "(v, a) \<in> dom (\<phi>\<^sub>S \<Psi> s)"
+ then have "v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None }"
+ and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ unfolding state_to_strips_state_dom_is[OF assms(1)]
+ by force+
+ moreover have "v \<in> set ?vs" and "s v \<noteq> None"
+ using calculation(1)
+ by fastforce+
+ ultimately show
+ "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None \<and> a \<in> \<R>\<^sub>+ \<Psi> v"
+ by force
+ next
+ assume "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None \<and> a \<in> \<R>\<^sub>+ \<Psi> v"
+ then have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "s v \<noteq> None"
+ and a_in_range_of_v: "a \<in> \<R>\<^sub>+ \<Psi> v"
+ by simp+
+ then have "v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None }"
+ by force
+ thus "(v, a) \<in> dom (\<phi>\<^sub>S \<Psi> s)"
+ unfolding state_to_strips_state_dom_is[OF assms(1)]
+ using a_in_range_of_v
+ by blast
+ qed
+qed
+
+lemma state_to_strips_state_range_is:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "(v, a) \<in> dom (\<phi>\<^sub>S \<Psi> s)"
+ shows "(\<phi>\<^sub>S \<Psi> s) (v, a) = Some (the (s v) = a)"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ let ?s' = "\<phi>\<^sub>S \<Psi> s"
+ and ?defined = "filter (\<lambda>v. s v \<noteq> None) ?vs"
+ let ?l = "concat [possible_assignments_for \<Psi> v. v \<leftarrow> ?defined]"
+ have v_in_set_vs: "v \<in> set ?vs"
+ and s_of_v_is_not_None: "s v \<noteq> None"
+ and a_in_range_of_v: "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using assms(2)
+ unfolding state_to_strips_state_dom_is[OF assms(1)]
+ by fastforce+
+ moreover {
+ have "\<forall>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). v \<in> dom (sas_plus_problem.range_of \<Psi>)"
+ using assms(1) is_valid_problem_sas_plus_then(1)
+ unfolding is_valid_problem_sas_plus_def
+ by fastforce
+ moreover have "(v, a) \<in> set ?l"
+ unfolding state_to_strips_state_dom_is_i[OF calculation(1)]
+ using s_of_v_is_not_None a_in_range_of_v v_in_set_vs
+ by fastforce
+ moreover have "set ?l \<noteq> {}"
+ using calculation
+ by fastforce
+ \<comment> \<open> TODO slow. \<close>
+ ultimately have "(\<phi>\<^sub>S \<Psi> s) (v, a) = Some (the (s v) = a)"
+ using map_of_from_function_graph_is_some_if[of
+ ?l "(v, a)" "\<lambda>(v, a). the (s v) = a"]
+ unfolding SAS_Plus_STRIPS.state_to_strips_state_def
+ state_to_strips_state_def Let_def case_prod_beta'
+ by fastforce
+ }
+ thus ?thesis.
+qed
+
+
+\<comment> \<open> Show that a STRIPS state corresponding to a SAS+ state via transformation is consistent
+w.r.t. to the variable subset with same left component (i.e. the original SAS+ variable). This is
+the consistency notion corresponding to SAS+ consistency: i.e. if no two assignments with different
+values for the same variable exist in the SAS+ state, then assigning the corresponding assignment
+both to @{text "True"} is impossible. Vice versa, if both are assigned to @{text "True"} then the
+assignment variables must be the same SAS+ variable/SAS+ value pair. \<close>
+lemma state_to_strips_state_effect_consistent:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "(v, a) \<in> dom (\<phi>\<^sub>S \<Psi> s)"
+ and "(v, a') \<in> dom (\<phi>\<^sub>S \<Psi> s)"
+ and "(\<phi>\<^sub>S \<Psi> s) (v, a) = Some True"
+ and "(\<phi>\<^sub>S \<Psi> s) (v, a') = Some True"
+ shows "(v, a) = (v, a')"
+proof -
+ have "the (s v) = a" and "the (s v) = a'"
+ using state_to_strips_state_range_is[OF assms(1)] assms(2, 3, 4, 5)
+ by fastforce+
+ thus ?thesis
+ by argo
+qed
+
+
+lemma sasp_op_to_strips_set_delete_effects_is:
+ assumes "is_valid_operator_sas_plus \<Psi> op"
+ shows "set (strips_operator.delete_effects_of (\<phi>\<^sub>O \<Psi> op))
+ = (\<Union>(v, a) \<in> set (effect_of op). { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+proof -
+ let ?D = "range_of \<Psi>"
+ and ?effect = "effect_of op"
+ let ?delete = "[(v, a'). (v, a) \<leftarrow> ?effect, a' \<leftarrow> filter ((\<noteq>) a) (the (?D v))]"
+ {
+ fix v a
+ assume "(v, a) \<in> set ?effect"
+ then have "(\<R>\<^sub>+ \<Psi> v) = set (the (?D v))"
+ using assms
+ using is_valid_operator_sas_plus_then_range_of_sas_plus_op_is_set_range_of_op
+ by fastforce
+ hence "set (filter ((\<noteq>) a) (the (?D v))) = { a' \<in> \<R>\<^sub>+ \<Psi> v. a' \<noteq> a }"
+ unfolding set_filter
+ by blast
+ } note nb = this
+ {
+ \<comment> \<open> TODO slow. \<close>
+ have "set ?delete = \<Union>(set ` (\<lambda>(v, a). map (Pair v) (filter ((\<noteq>) a) (the (?D v))))
+ ` (set ?effect))"
+ using set_concat
+ by simp
+ also have "\<dots> = \<Union>((\<lambda>(v, a). Pair v ` set (filter ((\<noteq>) a) (the (?D v))))
+ ` (set ?effect))"
+ unfolding image_comp[of set] set_map
+ by auto
+ \<comment> \<open> TODO slow. \<close>
+ also have "\<dots> = (\<Union>(v, a) \<in> set ?effect. Pair v ` { a' \<in> \<R>\<^sub>+ \<Psi> v. a' \<noteq> a })"
+ using nb
+ by fast
+ finally have "set ?delete = (\<Union>(v, a) \<in> set ?effect.
+ { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ by blast
+ }
+ thus ?thesis
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def Let_def
+ by force
+qed
+
+lemma sas_plus_problem_to_strips_problem_variable_set_is:
+ \<comment> \<open> The variable set of \<open>\<Pi>\<close> is the set of all possible
+assignments that are possible using the variables of \<open>\<V>\<close> and the corresponding domains. \<close>
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "set ((\<phi> \<Psi>)\<^sub>\<V>) = (\<Union>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ and ?vs = "variables_of \<Psi>"
+ {
+ have "set (strips_problem.variables_of ?\<Pi>)
+ = set [as. v \<leftarrow> ?vs, as \<leftarrow> possible_assignments_for \<Psi> v]"
+ unfolding sas_plus_problem_to_strips_problem_def
+ SAS_Plus_STRIPS.sas_plus_problem_to_strips_problem_def
+ by force
+ also have "\<dots> = (\<Union>(set ` (\<lambda>v. possible_assignments_for \<Psi> v) ` set ?vs))"
+ using set_concat
+ by auto
+ also have "\<dots> = (\<Union>((set \<circ> possible_assignments_for \<Psi>) ` set ?vs))"
+ using image_comp[of set "\<lambda>v. possible_assignments_for \<Psi> v" "set ?vs"]
+ by argo
+ finally have "set (strips_problem.variables_of ?\<Pi>)
+ = (\<Union>v \<in> set ?vs. set (possible_assignments_for \<Psi> v))"
+ unfolding o_apply
+ by blast
+ }
+ moreover have "\<forall>v \<in> set ?vs. v \<in> dom (sas_plus_problem.range_of \<Psi>)"
+ using is_valid_problem_sas_plus_dom_sas_plus_problem_range_of assms
+ by force
+ ultimately show ?thesis
+ using possible_assignments_for_set_is
+ by force
+qed
+
+corollary sas_plus_problem_to_strips_problem_variable_set_element_iff:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "(v, a) \<in> set ((\<phi> \<Psi>)\<^sub>\<V>) \<longleftrightarrow> v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> a \<in> \<R>\<^sub>+ \<Psi> v"
+ unfolding sas_plus_problem_to_strips_problem_variable_set_is[OF assms]
+ by fast
+
+lemma sasp_op_to_strips_effect_consistent:
+ assumes "op = \<phi>\<^sub>O \<Psi> op'"
+ and "op' \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ and "is_valid_operator_sas_plus \<Psi> op'"
+ shows "(v, a) \<in> set (add_effects_of op) \<longrightarrow> (v, a) \<notin> set (delete_effects_of op)"
+ and "(v, a) \<in> set (delete_effects_of op) \<longrightarrow> (v, a) \<notin> set (add_effects_of op)"
+proof -
+ have nb: "(\<forall>(v, a) \<in> set (effect_of op'). \<forall>(v', a') \<in> set (effect_of op'). v \<noteq> v' \<or> a = a')"
+ using assms(3)
+ unfolding is_valid_operator_sas_plus_def
+ SAS_Plus_Representation.is_valid_operator_sas_plus_def list_all_iff ListMem_iff Let_def
+ by argo
+ {
+ fix v a
+ assume v_a_in_add_effects_of_op: "(v, a) \<in> set (add_effects_of op)"
+ have "(v, a) \<notin> set (delete_effects_of op)"
+ proof (rule ccontr)
+ assume "\<not>(v, a) \<notin> set (delete_effects_of op)"
+ moreover have "(v, a) \<in>
+ (\<Union>(v, a') \<in> set (effect_of op'). { (v, a'')
+ | a''. a'' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a'' \<noteq> a' })"
+ using calculation sasp_op_to_strips_set_delete_effects_is
+ assms
+ by blast
+ moreover obtain a' where "(v, a') \<in> set (effect_of op')" and "a \<noteq> a'"
+ using calculation
+ by blast
+ moreover have "(v, a') \<in> set (add_effects_of op)"
+ using assms(1) calculation(3)
+ unfolding sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ Let_def
+ by fastforce
+ moreover have "(v, a) \<in> set (effect_of op')" and "(v, a') \<in> set (effect_of op')"
+ using assms(1) v_a_in_add_effects_of_op calculation(5)
+ unfolding sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ Let_def
+ by force+
+ ultimately show False
+ using nb
+ by fast
+ qed
+ }
+ moreover {
+ fix v a
+ assume v_a_in_delete_effects_of_op: "(v, a) \<in> set (delete_effects_of op)"
+ have "(v, a) \<notin> set (add_effects_of op)"
+ proof (rule ccontr)
+ assume "\<not>(v, a) \<notin> set (add_effects_of op)"
+ moreover have "(v, a) \<in> set (add_effects_of op)"
+ using calculation
+ by blast
+ moreover have "(v, a) \<in>
+ (\<Union>(v, a') \<in> set (effect_of op'). { (v, a'')
+ | a''. a'' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a'' \<noteq> a' })"
+ using sasp_op_to_strips_set_delete_effects_is
+ nb assms(1, 3) v_a_in_delete_effects_of_op
+ by force
+ moreover obtain a' where "(v, a') \<in> set (effect_of op')" and "a \<noteq> a'"
+ using calculation
+ by blast
+ moreover have "(v, a') \<in> set (add_effects_of op)"
+ using assms(1) calculation(4)
+ unfolding sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ Let_def
+ by fastforce
+ moreover have "(v, a) \<in> set (effect_of op')" and "(v, a') \<in> set (effect_of op')"
+ using assms(1) calculation(2, 6)
+ unfolding sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def Let_def
+ by force+
+ ultimately show False
+ using nb
+ by fast
+ qed
+ }
+ ultimately show "(v, a) \<in> set (add_effects_of op)
+ \<longrightarrow> (v, a) \<notin> set (delete_effects_of op)"
+ and "(v, a) \<in> set (delete_effects_of op)
+ \<longrightarrow> (v, a) \<notin> set (add_effects_of op)"
+ by blast+
+ qed
+
+lemma is_valid_problem_sas_plus_then_strips_transformation_too_iii:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "list_all (is_valid_operator_strips (\<phi> \<Psi>))
+ (strips_problem.operators_of (\<phi> \<Psi>))"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?vs = "strips_problem.variables_of ?\<Pi>"
+ {
+ fix op
+ assume "op \<in> set (strips_problem.operators_of ?\<Pi>)"
+ \<comment> \<open> TODO slow. \<close>
+ then obtain op'
+ where op_is: "op = \<phi>\<^sub>O \<Psi> op'"
+ and op'_in_operators: "op' \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ unfolding SAS_Plus_STRIPS.sas_plus_problem_to_strips_problem_def
+ sas_plus_problem_to_strips_problem_def
+ sasp_op_to_strips_def
+ by auto
+ then have is_valid_op': "is_valid_operator_sas_plus \<Psi> op'"
+ using sublocale_sas_plus_finite_domain_representation_ii(2)[OF assms]
+ by blast
+ moreover {
+ fix v a
+ assume "(v, a) \<in> set (strips_operator.precondition_of op)"
+ \<comment> \<open> TODO slow. \<close>
+ then have "(v, a) \<in> set (sas_plus_operator.precondition_of op')"
+ using op_is
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def
+ by force
+ moreover have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using is_valid_op' calculation
+ using is_valid_operator_sas_plus_then(1)
+ by fastforce
+ moreover have "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_op' calculation(1)
+ using is_valid_operator_sas_plus_then(2)
+ by fast
+ ultimately have "(v, a) \<in> set ?vs"
+ using sas_plus_problem_to_strips_problem_variable_set_element_iff[OF assms(1)]
+ by force
+ }
+ moreover {
+ fix v a
+ assume "(v, a) \<in> set (strips_operator.add_effects_of op)"
+ then have "(v, a) \<in> set (effect_of op')"
+ using op_is
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def
+ by force
+ then have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)" and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_operator_sas_plus_then is_valid_op'
+ by fastforce+
+ hence "(v, a) \<in> set ?vs"
+ using sas_plus_problem_to_strips_problem_variable_set_element_iff[OF assms(1)]
+ by force
+ }
+ moreover {
+ fix v a'
+ assume v_a'_in_delete_effects: "(v, a') \<in> set (strips_operator.delete_effects_of op)"
+ moreover have "set (strips_operator.delete_effects_of op)
+ = (\<Union>(v, a) \<in> set (effect_of op').
+ { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ using sasp_op_to_strips_set_delete_effects_is[OF is_valid_op']
+ op_is
+ by simp
+ \<comment> \<open> TODO slow. \<close>
+ ultimately obtain a
+ where "(v, a) \<in> set (effect_of op')"
+ and a'_in: "a' \<in> { a' \<in> \<R>\<^sub>+ \<Psi> v. a' \<noteq> a }"
+ by blast
+ moreover have "is_valid_operator_sas_plus \<Psi> op'"
+ using op'_in_operators assms(1)
+ is_valid_problem_sas_plus_then(2)
+ by blast
+ moreover have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using is_valid_operator_sas_plus_then calculation(1, 3)
+ by fast
+ moreover have "a' \<in> \<R>\<^sub>+ \<Psi> v"
+ using a'_in
+ by blast
+ ultimately have "(v, a') \<in> set ?vs"
+ using sas_plus_problem_to_strips_problem_variable_set_element_iff[OF assms(1)]
+ by force
+ }
+ ultimately have "set (strips_operator.precondition_of op) \<subseteq> set ?vs
+ \<and> set (strips_operator.add_effects_of op) \<subseteq> set ?vs
+ \<and> set (strips_operator.delete_effects_of op) \<subseteq> set ?vs
+ \<and> (\<forall>v\<in>set (add_effects_of op). v \<notin> set (delete_effects_of op))
+ \<and> (\<forall>v\<in>set (delete_effects_of op). v \<notin> set (add_effects_of op))"
+ using sasp_op_to_strips_effect_consistent[OF
+ op_is op'_in_operators is_valid_op']
+ by fast+
+ }
+ thus ?thesis
+ unfolding is_valid_operator_strips_def STRIPS_Representation.is_valid_operator_strips_def
+ list_all_iff ListMem_iff Let_def
+ by blast
+qed
+
+lemma is_valid_problem_sas_plus_then_strips_transformation_too_iv:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "\<forall>x. ((\<phi> \<Psi>)\<^sub>I) x \<noteq> None
+ \<longleftrightarrow> ListMem x (strips_problem.variables_of (\<phi> \<Psi>))"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?I = "initial_of \<Psi>"
+ and ?\<Pi> = "\<phi> \<Psi>"
+ let ?vs' = "strips_problem.variables_of ?\<Pi>"
+ and ?I' = "strips_problem.initial_of ?\<Pi>"
+ {
+ fix x
+ have "?I' x \<noteq> None \<longleftrightarrow> ListMem x ?vs'"
+ proof (rule iffI)
+ assume I'_of_x_is_not_None: "?I' x \<noteq> None"
+ then have "x \<in> dom ?I'"
+ by blast
+ moreover obtain v a where x_is: "x = (v, a)"
+ by fastforce
+ ultimately have "(v, a) \<in> dom ?I'"
+ by blast
+ then have "v \<in> set ?vs"
+ and "?I v \<noteq> None"
+ and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using state_to_strips_state_dom_element_iff[OF assms(1), of v a ?I]
+ unfolding sas_plus_problem_to_strips_problem_def
+ SAS_Plus_STRIPS.sas_plus_problem_to_strips_problem_def
+ state_to_strips_state_def
+ SAS_Plus_STRIPS.state_to_strips_state_def
+ by simp+
+ thus "ListMem x ?vs'"
+ unfolding ListMem_iff
+ using sas_plus_problem_to_strips_problem_variable_set_element_iff[OF assms(1)]
+ x_is
+ by auto
+ next
+ assume list_mem_x_vs': "ListMem x ?vs'"
+ then obtain v a where x_is: "x = (v, a)"
+ by fastforce
+ then have "(v, a) \<in> set ?vs'"
+ using list_mem_x_vs'
+ unfolding ListMem_iff
+ by blast
+ then have "v \<in> set ?vs" and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using sas_plus_problem_to_strips_problem_variable_set_element_iff[OF assms(1)]
+ by force+
+ moreover have "?I v \<noteq> None"
+ using is_valid_problem_sas_plus_then(3) assms(1) calculation(1)
+ by auto
+ ultimately have "(v, a) \<in> dom ?I'"
+ using state_to_strips_state_dom_element_iff[OF assms(1), of v a ?I]
+ unfolding SAS_Plus_STRIPS.sas_plus_problem_to_strips_problem_def
+ sas_plus_problem_to_strips_problem_def
+ SAS_Plus_STRIPS.state_to_strips_state_def
+ state_to_strips_state_def
+ by force
+ thus "?I' x \<noteq> None"
+ using x_is
+ by fastforce
+ qed
+ }
+ thus ?thesis
+ by simp
+qed
+
+private lemma is_valid_problem_sas_plus_then_strips_transformation_too_v:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "\<forall>x. ((\<phi> \<Psi>)\<^sub>G) x \<noteq> None
+ \<longrightarrow> ListMem x (strips_problem.variables_of (\<phi> \<Psi>))"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?D = "range_of \<Psi>"
+ and ?G = "goal_of \<Psi>"
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?vs' = "strips_problem.variables_of ?\<Pi>"
+ and ?G' = "strips_problem.goal_of ?\<Pi>"
+ have nb: "?G' = \<phi>\<^sub>S \<Psi> ?G"
+ by simp
+ {
+ fix x
+ assume "?G' x \<noteq> None"
+ moreover obtain v a where "x = (v, a)"
+ by fastforce
+ moreover have "(v, a) \<in> dom ?G'"
+ using domIff calculation(1, 2)
+ by blast
+ moreover have "v \<in> set ?vs" and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using state_to_strips_state_dom_is[OF assms(1), of ?G] nb calculation(3)
+ by auto+
+ ultimately have "x \<in> set ?vs'"
+ using sas_plus_problem_to_strips_problem_variable_set_element_iff[OF assms(1)]
+ by auto
+ }
+ thus ?thesis
+ unfolding ListMem_iff
+ by simp
+qed
+
+text \<open> We now show that given \<^term>\<open>\<Psi>\<close> is a valid SASPlus problem, then \<^term>\<open>\<Pi> \<equiv> \<phi> \<Psi>\<close> is a valid
+STRIPS problem as well.
+The proof unfolds the definition of \<^term>\<open>is_valid_problem_strips\<close> and then shows each of the conjuncts
+for \<^term>\<open>\<Pi>\<close>. These are:
+\begin{itemize}
+ \item \<^term>\<open>\<Pi>\<close> has at least one variable;
+ \item \<^term>\<open>\<Pi>\<close> has at least one operator;
+ \item all operators are valid STRIPS operators;
+ \item \<^term>\<open>(\<Pi>::'a strips_problem)\<^sub>I\<close> is defined for all variables in \<^term>\<open>(\<Pi>::'a strips_problem)\<^sub>\<V>\<close>; and finally,
+ \item if \<^term>\<open>((\<Pi>::'a strips_problem)\<^sub>G) x\<close> is defined, then \<^term>\<open>x\<close> is in \<^term>\<open>(\<Pi>::'a strips_problem)\<^sub>\<V>\<close>.
+\end{itemize} \<close>
+
+theorem
+ is_valid_problem_sas_plus_then_strips_transformation_too:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "is_valid_problem_strips (\<phi> \<Psi>)"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ have "list_all (is_valid_operator_strips (\<phi> \<Psi>))
+ (strips_problem.operators_of (\<phi> \<Psi>))"
+ using is_valid_problem_sas_plus_then_strips_transformation_too_iii[OF assms].
+ moreover have "\<forall>x. (((\<phi> \<Psi>)\<^sub>I) x \<noteq> None) =
+ ListMem x (strips_problem.variables_of (\<phi> \<Psi>))"
+ using is_valid_problem_sas_plus_then_strips_transformation_too_iv[OF assms].
+ moreover have "\<forall>x. ((\<phi> \<Psi>)\<^sub>G) x \<noteq> None \<longrightarrow>
+ ListMem x (strips_problem.variables_of (\<phi> \<Psi>))"
+ using is_valid_problem_sas_plus_then_strips_transformation_too_v[OF assms].
+ ultimately show ?thesis
+ using is_valid_problem_strips_def
+ unfolding STRIPS_Representation.is_valid_problem_strips_def
+ by fastforce
+qed
+
+lemma set_filter_all_possible_assignments_true_is:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "set (filter (\<lambda>(v, a). s (v, a) = Some True)
+ (all_possible_assignments_for \<Psi>))
+ = (\<Union>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). Pair v ` { a \<in> \<R>\<^sub>+ \<Psi> v. s (v, a) = Some True })"
+proof -
+ let ?vs = "sas_plus_problem.variables_of \<Psi>"
+ and ?P = "(\<lambda>(v, a). s (v, a) = Some True)"
+ let ?l = "filter ?P (all_possible_assignments_for \<Psi>)"
+ have "set ?l = set (concat (map (filter ?P) (map (possible_assignments_for \<Psi>) ?vs)))"
+ unfolding all_possible_assignments_for_def
+ filter_concat[of ?P "map (possible_assignments_for \<Psi>) (sas_plus_problem.variables_of \<Psi>)"]
+ by simp
+ also have "\<dots> = set (concat (map (\<lambda>v. filter ?P (possible_assignments_for \<Psi> v)) ?vs))"
+ unfolding map_map comp_apply
+ by blast
+ also have "\<dots> = set (concat (map (\<lambda>v. map (Pair v)
+ (filter (?P \<circ> Pair v) (the (range_of \<Psi> v)))) ?vs))"
+ unfolding possible_assignments_for_def filter_map
+ by blast
+ also have "\<dots> = set (concat (map (\<lambda>v. map (Pair v) (filter (\<lambda>a. s (v, a) = Some True)
+ (the (range_of \<Psi> v)))) ?vs))"
+ unfolding comp_apply
+ by fast
+ also have "\<dots> = \<Union>(set ` ((\<lambda>v. map (Pair v) (filter (\<lambda>a. s (v, a) = Some True)
+ (the (range_of \<Psi> v)))) ` set ?vs))"
+ unfolding set_concat set_map..
+ also have "\<dots> = (\<Union>v \<in> set ?vs. Pair v ` set (filter (\<lambda>a. s (v, a) = Some True)
+ (the (range_of \<Psi> v))))"
+ unfolding image_comp[of set] comp_apply set_map..
+ also have "\<dots> = (\<Union>v \<in> set ?vs. Pair v
+ ` { a \<in> set (the (range_of \<Psi> v)). s (v, a) = Some True })"
+ unfolding set_filter..
+ finally show ?thesis
+ using set_the_range_of_is_range_of_sas_plus_if[OF assms(1)]
+ by auto
+qed
+
+lemma strips_state_to_state_dom_is:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "dom (\<phi>\<^sub>S\<inverse> \<Psi> s)
+ = (\<Union>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+).
+ { v | a. a \<in> (\<R>\<^sub>+ \<Psi> v) \<and> s (v, a) = Some True })"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?s' = "\<phi>\<^sub>S\<inverse> \<Psi> s"
+ and ?P = "(\<lambda>(v, a). s (v, a) = Some True)"
+ let ?l = "filter ?P (all_possible_assignments_for \<Psi>)"
+ {
+ have "fst ` set ?l = fst ` (\<Union>v \<in> set ?vs. Pair v
+ ` { a \<in> \<R>\<^sub>+ \<Psi> v. s (v, a) = Some True })"
+ unfolding set_filter_all_possible_assignments_true_is[OF assms]
+ by auto
+ also have "\<dots> = (\<Union>v \<in> set ?vs. fst ` Pair v
+ ` { a \<in> \<R>\<^sub>+ \<Psi> v. s (v, a) = Some True })"
+ by blast
+ also have "\<dots> = (\<Union>v \<in> set ?vs. (\<lambda>a. fst (Pair v a)) `
+ { a \<in> \<R>\<^sub>+ \<Psi> v. s (v, a) = Some True })"
+ unfolding image_comp[of fst] comp_apply
+ by blast
+ finally have "fst ` set ?l = (\<Union>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+).
+ { v | a. a \<in> (\<R>\<^sub>+ \<Psi> v) \<and> s (v, a) = Some True })"
+ unfolding setcompr_eq_image fst_conv
+ by simp
+ }
+ thus ?thesis
+ unfolding SAS_Plus_STRIPS.strips_state_to_state_def
+ strips_state_to_state_def dom_map_of_conv_image_fst
+ by blast
+qed
+
+lemma strips_state_to_state_range_is:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ and "(v, a) \<in> dom s'"
+ and "\<forall>(v, a) \<in> dom s'. \<forall>(v, a') \<in> dom s'. s' (v, a) = Some True \<and> s' (v, a') = Some True
+ \<longrightarrow> (v, a) = (v, a')"
+ shows "(\<phi>\<^sub>S\<inverse> \<Psi> s') v = Some a \<longleftrightarrow> the (s' (v, a))"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?D = "range_of \<Psi>"
+ and ?s = "\<phi>\<^sub>S\<inverse> \<Psi> s'"
+ let ?as = "all_possible_assignments_for \<Psi>"
+ let ?l = "filter (\<lambda>(v, a). s' (v, a) = Some True) ?as"
+ show ?thesis
+ proof (rule iffI)
+ assume s_of_v_is_Some_a: "?s v = Some a"
+ {
+ have "(v, a) \<in> set ?l"
+ using s_of_v_is_Some_a
+ unfolding SAS_Plus_STRIPS.strips_state_to_state_def
+ strips_state_to_state_def
+ using map_of_SomeD
+ by fast
+ hence "s' (v, a) = Some True"
+ unfolding all_possible_assignments_for_set_is set_filter
+ by blast
+ }
+ thus "the (s' (v, a))"
+ by simp
+ next
+ assume the_of_s'_of_v_a_is: "the (s' (v, a))"
+ then have s'_of_v_a_is_Some_true: "s' (v, a) = Some True"
+ using assms(4) domIff
+ by force
+ \<comment> \<open> TODO slow. \<close>
+ moreover {
+ fix v v' a a'
+ assume "(v, a) \<in> set ?l" and "(v', a') \<in> set ?l"
+ then have "v \<noteq> v' \<or> a = a'"
+ using assms(5)
+ by fastforce
+ }
+ moreover {
+ have "\<forall>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). sas_plus_problem.range_of \<Psi> v \<noteq> None"
+ using is_valid_problem_sas_plus_then(1) assms(1)
+ range_of_not_empty
+ by force
+ (* TODO slow. *)
+ moreover have "set ?l = Set.filter (\<lambda>(v, a). s' (v, a) = Some True)
+ (\<Union>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+ using all_possible_assignments_for_set_is calculation
+ by force
+ ultimately have "(v, a) \<in> set ?l"
+ using assms(2, 3) s'_of_v_a_is_Some_true
+ by simp
+ }
+ ultimately show "?s v = Some a"
+ using map_of_constant_assignments_defined_if[of ?l v a]
+ unfolding SAS_Plus_STRIPS.strips_state_to_state_def
+ strips_state_to_state_def
+ by blast
+ qed
+qed
+
+\<comment> \<open> NOTE A technical lemma which characterizes the return values for possible assignments
+@{text "(v, a)"} when used as variables on a state @{text "s"} which was transformed from. \<close>
+lemma strips_state_to_state_inverse_is_i:
+assumes "is_valid_problem_sas_plus \<Psi>"
+ and "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "s v \<noteq> None"
+ and "a \<in> \<R>\<^sub>+ \<Psi> v"
+shows "(\<phi>\<^sub>S \<Psi> s) (v, a) = Some (the (s v) = a)"
+proof -
+ let ?vs = "sas_plus_problem.variables_of \<Psi>"
+ let ?s' = "\<phi>\<^sub>S \<Psi> s"
+ and ?f = "\<lambda>(v, a). the (s v) = a"
+ and ?l = "concat (map (possible_assignments_for \<Psi>) (filter (\<lambda>v. s v \<noteq> None) ?vs))"
+ have "(v, a) \<in> dom ?s'"
+ using state_to_strips_state_dom_element_iff[
+ OF assms(1)] assms(2, 3, 4)
+ by presburger
+ {
+ have "v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None }"
+ using assms(2, 3)
+ by blast
+ moreover have "\<forall>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). v \<in> dom (sas_plus_problem.range_of \<Psi>)"
+ using is_valid_problem_sas_plus_dom_sas_plus_problem_range_of[OF assms(1)].
+ moreover have "set ?l = (\<Union>v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None }.
+ { (v, a) |a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+ unfolding state_to_strips_state_dom_is_i[OF calculation(2)]
+ by blast
+ ultimately have "(v, a) \<in> set ?l"
+ using assms(4)
+ by blast
+ }
+ moreover have "set ?l \<noteq> {}"
+ using calculation
+ by force
+ \<comment> \<open> TODO slow.\<close>
+ ultimately show ?thesis
+ unfolding SAS_Plus_STRIPS.state_to_strips_state_def
+ state_to_strips_state_def
+ using map_of_from_function_graph_is_some_if[of ?l "(v, a)" ?f]
+ unfolding split_def
+ by fastforce
+qed
+
+\<comment> \<open> NOTE Show that the transformed strips state is consistent for pairs of assignments
+@{text "(v, a)"} and @{text "(v, a')"} in the same variable domain. \<close>
+(* TODO make private. *)
+corollary strips_state_to_state_inverse_is_ii:
+assumes "is_valid_problem_sas_plus \<Psi>"
+ and "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "s v = Some a"
+ and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ and "a' \<in> \<R>\<^sub>+ \<Psi> v"
+ and "a' \<noteq> a"
+shows "(\<phi>\<^sub>S \<Psi> s) (v, a') = Some False"
+proof -
+ have "s v \<noteq> None"
+ using assms(3)
+ by simp
+ moreover have "the (s v) \<noteq> a'"
+ using assms(3, 6)
+ by simp
+ ultimately show ?thesis
+ using strips_state_to_state_inverse_is_i[OF assms(1, 2) _ assms(5)]
+ by force
+qed
+
+\<comment> \<open> NOTE Follows from the corollary above by contraposition. \<close>
+(* TODO make private. *)
+corollary strips_state_to_state_inverse_is_iii:
+assumes "is_valid_problem_sas_plus \<Psi>"
+ and "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "s v = Some a"
+ and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ and "a' \<in> \<R>\<^sub>+ \<Psi> v"
+ and "(\<phi>\<^sub>S \<Psi> s) (v, a) = Some True"
+ and "(\<phi>\<^sub>S \<Psi> s) (v, a') = Some True"
+shows "a = a'"
+proof -
+ have "s v \<noteq> None"
+ using assms(3)
+ by blast
+ thus ?thesis
+ using strips_state_to_state_inverse_is_i[OF assms(1, 2)] assms(4, 5, 6, 7)
+ by auto
+qed
+
+(* TODO make private. *)
+lemma strips_state_to_state_inverse_is_iv:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "dom s \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "s v = Some a"
+ and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ shows "(\<phi>\<^sub>S\<inverse> \<Psi> (\<phi>\<^sub>S \<Psi> s)) v = Some a"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?s' = "\<phi>\<^sub>S \<Psi> s"
+ let ?s'' = "\<phi>\<^sub>S\<inverse> \<Psi> ?s'"
+ let ?P = "\<lambda>(v, a). ?s' (v, a) = Some True"
+ let ?as = "filter ?P (all_possible_assignments_for \<Psi>)"
+ and ?As = "Set.filter ?P (\<Union>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+).
+ { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+ {
+ have "\<forall>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). range_of \<Psi> v \<noteq> None"
+ using sublocale_sas_plus_finite_domain_representation_ii(1)[OF assms(1)]
+ range_of_not_empty
+ by force
+ (* TODO slow. *)
+ hence "set ?as = ?As"
+ unfolding set_filter
+ using all_possible_assignments_for_set_is
+ by force
+ } note nb = this
+ moreover {
+ {
+ fix v v' a a'
+ assume "(v, a) \<in> set ?as"
+ and "(v', a') \<in> set ?as"
+ then have "(v, a) \<in> ?As" and "(v', a') \<in> ?As"
+ using nb
+ by blast+
+ then have v_in_set_vs: "v \<in> set ?vs" and v'_in_set_vs: "v' \<in> set ?vs"
+ and a_in_range_of_v: "a \<in> \<R>\<^sub>+ \<Psi> v"
+ and a'_in_range_of_v: "a' \<in> \<R>\<^sub>+ \<Psi> v'"
+ and s'_of_v_a_is: "?s' (v, a) = Some True" and s'_of_v'_a'_is: "?s' (v', a') = Some True"
+ by fastforce+
+ then have "(v, a) \<in> dom ?s'"
+ by blast
+ then have s_of_v_is_Some_a: "s v = Some a"
+ using state_to_strips_state_dom_element_iff[OF assms(1)]
+ state_to_strips_state_range_is[OF assms(1)] s'_of_v_a_is
+ by auto
+ have "v \<noteq> v' \<or> a = a'"
+ proof (rule ccontr)
+ assume "\<not>(v \<noteq> v' \<or> a = a')"
+ then have "v = v'" and "a \<noteq> a'"
+ by simp+
+ thus False
+ using a'_in_range_of_v a_in_range_of_v assms(1) v'_in_set_vs s'_of_v'_a'_is
+ s'_of_v_a_is s_of_v_is_Some_a strips_state_to_state_inverse_is_iii
+ by force
+ qed
+ }
+ moreover {
+ have "s v \<noteq> None"
+ using assms(4)
+ by simp
+ then have "?s' (v, a) = Some True"
+ using strips_state_to_state_inverse_is_i[OF assms(1, 3) _ assms(5)]
+ assms(4)
+ by simp
+ (* TODO slow *)
+ hence "(v, a) \<in> set ?as"
+ using all_possible_assignments_for_set_is assms(3, 5) nb
+ by simp
+ }
+ ultimately have "map_of ?as v = Some a"
+ using map_of_constant_assignments_defined_if[of ?as v a]
+ by blast
+ }
+ \<comment> \<open> TODO slow. \<close>
+ thus ?thesis
+ unfolding SAS_Plus_STRIPS.strips_state_to_state_def
+ strips_state_to_state_def all_possible_assignments_for_def
+ by simp
+qed
+
+(* TODO the constraints on the state @{text "s"} could be refactored into a definition of valid
+states for a problem description. *)
+(* TODO The proof is not very elegant. Should be simplified. *)
+\<comment> \<open> Show that that \<open>\<phi>\<^sub>S\<inverse> \<Psi>\<close> is the inverse of \<open>\<phi>\<^sub>S \<Psi>\<close>. The additional constraints
+\<^term>\<open>dom s = set ((\<Psi>)\<^sub>\<V>\<^sub>+)\<close> and \<^term>\<open>\<forall>v \<in> dom s. the (s v) \<in> \<R>\<^sub>+ \<Psi> v\<close> are needed because the
+transformation functions only take into account variables and domains declared in the problem
+description. They also sufficiently characterize a state that was transformed from SAS+ to STRIPS. \<close>
+lemma strips_state_to_state_inverse_is:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "dom s \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom s. the (s v) \<in> \<R>\<^sub>+ \<Psi> v"
+ shows "s = (\<phi>\<^sub>S\<inverse> \<Psi> (\<phi>\<^sub>S \<Psi> s))"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?D = "range_of \<Psi>"
+ let ?s' = "\<phi>\<^sub>S \<Psi> s"
+ let ?s'' = "\<phi>\<^sub>S\<inverse> \<Psi> ?s'"
+ \<comment> \<open> NOTE Show the thesis by proving that @{text "s"} and @{text "?s'"} are mutual submaps. \<close>
+ {
+ fix v
+ assume v_in_dom_s: "v \<in> dom s"
+ then have v_in_set_vs: "v \<in> set ?vs"
+ using assms(2)
+ by auto
+ then obtain a
+ where the_s_v_is_a: "s v = Some a"
+ and a_in_dom_v: "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using assms(2, 3) v_in_dom_s
+ by force
+ moreover have "?s'' v = Some a"
+ using strips_state_to_state_inverse_is_iv[OF assms(1, 2)] v_in_set_vs
+ the_s_v_is_a a_in_dom_v
+ by force
+ ultimately have "s v = ?s'' v"
+ by argo
+ } note nb = this
+ moreover {
+ fix v
+ assume "v \<in> dom ?s''"
+ then obtain a
+ where "a \<in> \<R>\<^sub>+ \<Psi> v"
+ and "?s' (v, a) = Some True"
+ using strips_state_to_state_dom_is[OF assms(1)]
+ by blast
+ then have "(v, a) \<in> dom ?s'"
+ by blast
+ then have "s v \<noteq> None"
+ using state_to_strips_state_dom_is[OF assms(1)]
+ by simp
+ then obtain a where "s v = Some a"
+ by blast
+ hence "?s'' v = s v"
+ using nb
+ by fastforce
+ }
+ \<comment> \<open> TODO slow.\<close>
+ ultimately show ?thesis
+ using map_le_antisym[of s ?s''] map_le_def
+ unfolding strips_state_to_state_def
+ state_to_strips_state_def
+ by blast
+qed
+
+\<comment> \<open> An important lemma which shows that the submap relation does not change if we transform the
+states on either side from SAS+ to STRIPS.
+% TODO what is this called generally? Predicate monotony?? \<close>
+lemma state_to_strips_state_map_le_iff:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "dom s \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom s. the (s v) \<in> \<R>\<^sub>+ \<Psi> v"
+ shows "s \<subseteq>\<^sub>m t \<longleftrightarrow> (\<phi>\<^sub>S \<Psi> s) \<subseteq>\<^sub>m (\<phi>\<^sub>S \<Psi> t)"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?D = "range_of \<Psi>"
+ and ?s' = "\<phi>\<^sub>S \<Psi> s"
+ and ?t' = "\<phi>\<^sub>S \<Psi> t"
+ show ?thesis
+ proof (rule iffI)
+ assume s_map_le_t: "s \<subseteq>\<^sub>m t"
+ {
+ fix v a
+ assume "(v, a) \<in> dom ?s'"
+ moreover have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)" and "s v \<noteq> None" and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using state_to_strips_state_dom_is[OF assms(1)] calculation
+ by blast+
+ moreover have "?s' (v, a) = Some (the (s v) = a)"
+ using state_to_strips_state_range_is[OF assms(1)] calculation(1)
+ by meson
+ moreover have "v \<in> dom s"
+ using calculation(3)
+ by auto
+ moreover have "s v = t v"
+ using s_map_le_t calculation(6)
+ unfolding map_le_def
+ by blast
+ moreover have "t v \<noteq> None"
+ using calculation(3, 7)
+ by argo
+ moreover have "(v, a) \<in> dom ?t'"
+ using state_to_strips_state_dom_is[OF assms(1)] calculation(2, 4, 8)
+ by blast
+ moreover have "?t' (v, a) = Some (the (t v) = a)"
+ using state_to_strips_state_range_is[OF assms(1)] calculation(9)
+ by simp
+ ultimately have "?s' (v, a) = ?t' (v, a)"
+ by presburger
+ }
+ thus "?s' \<subseteq>\<^sub>m ?t'"
+ unfolding map_le_def
+ by fast
+ next
+ assume s'_map_le_t': "?s' \<subseteq>\<^sub>m ?t'"
+ {
+ fix v
+ assume v_in_dom_s: "v \<in> dom s"
+ moreover obtain a where the_of_s_of_v_is_a: "the (s v) = a"
+ by blast
+ moreover have v_in_vs: "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and s_of_v_is_not_None: "s v \<noteq> None"
+ and a_in_range_of_v: "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using assms(2, 3) v_in_dom_s calculation
+ by blast+
+ moreover have "(v, a) \<in> dom ?s'"
+ using state_to_strips_state_dom_is[OF assms(1)]
+ calculation(3, 4, 5)
+ by simp
+ moreover have "?s' (v, a) = ?t' (v, a)"
+ using s'_map_le_t' calculation
+ unfolding map_le_def
+ by blast
+ moreover have "(v, a) \<in> dom ?t'"
+ using calculation
+ unfolding domIff
+ by argo
+ moreover have "?s' (v, a) = Some (the (s v) = a)"
+ and "?t' (v, a) = Some (the (t v) = a)"
+ using state_to_strips_state_range_is[OF assms(1)] calculation
+ by fast+
+ moreover have "s v = Some a"
+ using calculation(2, 4)
+ by force
+ moreover have "?s' (v, a) = Some True"
+ using calculation(9, 11)
+ by fastforce
+ moreover have "?t' (v, a) = Some True"
+ using calculation(7, 12)
+ by argo
+ moreover have "the (t v) = a"
+ using calculation(10, 13) try0
+ by force
+ moreover {
+ have "v \<in> dom t"
+ using state_to_strips_state_dom_element_iff[OF assms(1)]
+ calculation(8)
+ by auto
+ hence "t v = Some a"
+ using calculation(14)
+ by force
+ }
+ ultimately have "s v = t v"
+ by argo
+ }
+ thus "s \<subseteq>\<^sub>m t"
+ unfolding map_le_def
+ by simp
+ qed
+qed
+
+\<comment> \<open> We also show that \<open>\<phi>\<^sub>O\<inverse> \<Pi>\<close> is the inverse of \<open>\<phi>\<^sub>O \<Psi>\<close>. Note that this proof is completely
+mechanical since both the precondition and effect lists are simply being copied when transforming
+from SAS+ to STRIPS and when transforming back from STRIPS to SAS+. \<close>
+(* TODO rename \<open>sasp_op_to_strips_inverse_is\<close> *)
+(* TODO prune assumptions (not required) *)
+lemma sas_plus_operator_inverse_is:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ shows "(\<phi>\<^sub>O\<inverse> \<Psi> (\<phi>\<^sub>O \<Psi> op)) = op"
+proof -
+ let ?op = "\<phi>\<^sub>O\<inverse> \<Psi> (\<phi>\<^sub>O \<Psi> op)"
+ have "precondition_of ?op = precondition_of op"
+ unfolding SAS_Plus_STRIPS.strips_op_to_sasp_def
+ strips_op_to_sasp_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def
+ by fastforce
+ moreover have "effect_of ?op = effect_of op"
+ unfolding SAS_Plus_STRIPS.strips_op_to_sasp_def
+ strips_op_to_sasp_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def
+ by force
+ ultimately show ?thesis
+ by simp
+qed
+
+\<comment> \<open> Note that we have to make the assumption that \<open>op'\<close> is a member of the operator set of the
+induced STRIPS problem \<open>\<phi> \<Psi>\<close>. This implies that \<open>op'\<close> was transformed from an
+\<open>op \<in> operators_of \<Psi>\<close>. If we don't make this assumption, then multiple STRIPS operators of the
+form \<open>\<lparr> precondition_of = [], add_effects_of = [], delete_effects_of = [(v, a), ...] \<rparr>\<close> correspond
+to one SAS+ operator (since the delete effects are being discarded in the transformation function).
+\<close>
+lemma strips_operator_inverse_is:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "op' \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ shows "(\<phi>\<^sub>O \<Psi> (\<phi>\<^sub>O\<inverse> \<Psi> op')) = op'"
+ proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ obtain op where "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)" and "op' = \<phi>\<^sub>O \<Psi> op"
+ using assms
+ by auto
+ moreover have "\<phi>\<^sub>O\<inverse> \<Psi> op' = op"
+ using sas_plus_operator_inverse_is[OF assms(1) calculation(1)] calculation(2)
+ by blast
+ ultimately show ?thesis
+ by argo
+ qed
+
+(*
+ \<^item> TODO Simplify | refactor proof.
+ \<^item> TODO make private. *)
+lemma sas_plus_equivalent_to_strips_i_a_I:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "set ops' \<subseteq> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and "STRIPS_Semantics.are_all_operators_applicable (\<phi>\<^sub>S \<Psi> s) ops'"
+ and "op \<in> set [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ shows "map_of (precondition_of op) \<subseteq>\<^sub>m (\<phi>\<^sub>S\<inverse> \<Psi> (\<phi>\<^sub>S \<Psi> s))"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ and ?s' = "\<phi>\<^sub>S \<Psi> s"
+ let ?s = "\<phi>\<^sub>S\<inverse> \<Psi> ?s'"
+ and ?D = "range_of \<Psi>"
+ and ?ops = "[\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ and ?pre = "precondition_of op"
+ have nb\<^sub>1: "\<forall>(v, a) \<in> dom ?s'.
+ \<forall>(v, a') \<in> dom ?s'.
+ ?s' (v, a) = Some True \<and> ?s' (v, a') = Some True
+ \<longrightarrow> (v, a) = (v, a')"
+ using state_to_strips_state_effect_consistent[OF assms(1)]
+ by blast
+ {
+ fix op'
+ assume "op' \<in> set ops'"
+ moreover have "op' \<in> set ((?\<Pi>)\<^sub>\<O>)"
+ using assms(2) calculation
+ by blast
+ ultimately have "\<exists>op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+). op' = (\<phi>\<^sub>O \<Psi> op)"
+ by auto
+ } note nb\<^sub>2 = this
+ {
+ fix op
+ assume "op \<in> set ?ops"
+ then obtain op' where "op' \<in> set ops'" and "op = \<phi>\<^sub>O\<inverse> \<Psi> op'"
+ using assms(4)
+ by auto
+ moreover obtain op'' where "op'' \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)" and "op' = \<phi>\<^sub>O \<Psi> op''"
+ using nb\<^sub>2 calculation(1)
+ by blast
+ moreover have "op = op''"
+ using sas_plus_operator_inverse_is[OF assms(1) calculation(3)] calculation(2, 4)
+ by blast
+ ultimately have "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ by blast
+ } note nb\<^sub>3 = this
+ {
+ fix op v a
+ assume "op \<in> set ?ops"
+ and v_a_in_precondition_of_op': "(v, a) \<in> set (precondition_of op)"
+ moreover obtain op' where "op' \<in> set ops'" and "op = \<phi>\<^sub>O\<inverse> \<Psi> op'"
+ using calculation(1)
+ by auto
+ moreover have "strips_operator.precondition_of op' = precondition_of op"
+ using calculation(4)
+ unfolding SAS_Plus_STRIPS.strips_op_to_sasp_def
+ strips_op_to_sasp_def
+ by simp
+ ultimately have "\<exists>op' \<in> set ops'. op = (\<phi>\<^sub>O\<inverse> \<Psi> op')
+ \<and> (v, a) \<in> set (strips_operator.precondition_of op')"
+ by metis
+ } note nb\<^sub>4 = this
+ {
+ fix op' v a
+ assume "op' \<in> set ops'"
+ and v_a_in_precondition_of_op': "(v, a) \<in> set (strips_operator.precondition_of op')"
+ moreover have s'_of_v_a_is_Some_True: "?s' (v, a) = Some True"
+ using assms(3) calculation(1, 2)
+ unfolding are_all_operators_applicable_set
+ by blast
+ moreover {
+ obtain op where "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)" and "op' = \<phi>\<^sub>O \<Psi> op"
+ using nb\<^sub>2 calculation(1)
+ by blast
+ moreover have "strips_operator.precondition_of op' = precondition_of op"
+ using calculation(2)
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def
+ by simp
+ moreover have "(v, a) \<in> set (precondition_of op)"
+ using v_a_in_precondition_of_op' calculation(3)
+ by argo
+ moreover have "is_valid_operator_sas_plus \<Psi> op"
+ using is_valid_problem_sas_plus_then(2) assms(1) calculation(1)
+ unfolding is_valid_operator_sas_plus_def
+ by auto
+ moreover have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)" and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_operator_sas_plus_then(1,2) calculation(4, 5)
+ unfolding is_valid_operator_sas_plus_def
+ by fastforce+
+ moreover have "v \<in> dom ?s"
+ using strips_state_to_state_dom_is[OF assms(1), of ?s']
+ s'_of_v_a_is_Some_True calculation(6, 7)
+ by blast
+ moreover have "(v, a) \<in> dom ?s'"
+ using s'_of_v_a_is_Some_True domIff
+ by blast
+ ultimately have "?s v = Some a"
+ using strips_state_to_state_range_is[OF assms(1) _ _ _ nb\<^sub>1]
+ s'_of_v_a_is_Some_True
+ by simp
+ }
+ hence "?s v = Some a".
+ } note nb\<^sub>5 = this
+ {
+ fix v
+ assume "v \<in> dom (map_of ?pre)"
+ then obtain a where "map_of ?pre v = Some a"
+ by fast
+ moreover have "(v, a) \<in> set ?pre"
+ using map_of_SomeD calculation
+ by fast
+ moreover {
+ have "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using assms(4) nb\<^sub>3
+ by blast
+ then have "is_valid_operator_sas_plus \<Psi> op"
+ using is_valid_problem_sas_plus_then(2) assms(1)
+ unfolding is_valid_operator_sas_plus_def
+ by auto
+ hence "\<forall>(v, a) \<in> set ?pre. \<forall>(v', a') \<in> set ?pre. v \<noteq> v' \<or> a = a'"
+ using is_valid_operator_sas_plus_then(5)
+ unfolding is_valid_operator_sas_plus_def
+ by fast
+ }
+ moreover have "map_of ?pre v = Some a"
+ using map_of_constant_assignments_defined_if[of ?pre] calculation(2, 3)
+ by blast
+ moreover obtain op' where "op' \<in> set ops'"
+ and "(v, a) \<in> set (strips_operator.precondition_of op')"
+ using nb\<^sub>4[OF assms(4) calculation(2)]
+ by blast
+ moreover have "?s v = Some a"
+ using nb\<^sub>5 calculation(5, 6)
+ by fast
+ ultimately have "map_of ?pre v = ?s v"
+ by argo
+ }
+ thus ?thesis
+ unfolding map_le_def
+ by blast
+qed
+
+lemma to_sas_plus_list_of_transformed_sas_plus_problem_operators_structure:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "set ops' \<subseteq> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and "op \<in> set [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ shows "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+) \<and> (\<exists>op' \<in> set ops'. op' = \<phi>\<^sub>O \<Psi> op)"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ obtain op' where "op' \<in> set ops'" and "op = \<phi>\<^sub>O\<inverse> \<Psi> op'"
+ using assms(3)
+ by auto
+ moreover have "op' \<in> set ((?\<Pi>)\<^sub>\<O>)"
+ using assms(2) calculation(1)
+ by blast
+ moreover obtain op'' where "op'' \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)" and "op' = \<phi>\<^sub>O \<Psi> op''"
+ using calculation(3)
+ by auto
+ moreover have "op = op''"
+ using sas_plus_operator_inverse_is[OF assms(1) calculation(4)] calculation(2, 5)
+ by presburger
+ ultimately show ?thesis
+ by blast
+qed
+
+(* \<^item> TODO Prune premises (2nd premise and \<open>are_all_operators_applicable s' ops'\<close> can be removed?).
+ \<^item> TODO make private.
+ \<^item> TODO adjust nb indexes *)
+lemma sas_plus_equivalent_to_strips_i_a_II:
+ fixes \<Psi> :: "('variable, 'domain) sas_plus_problem"
+ fixes s :: "('variable, 'domain) state"
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "set ops' \<subseteq> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and "STRIPS_Semantics.are_all_operators_applicable (\<phi>\<^sub>s \<Psi> s) ops'
+ \<and> STRIPS_Semantics.are_all_operator_effects_consistent ops'"
+ shows "are_all_operator_effects_consistent [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+proof -
+ let ?s' = "\<phi>\<^sub>S \<Psi> s"
+ let ?s = "\<phi>\<^sub>S\<inverse> \<Psi> ?s'"
+ and ?ops = "[\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ and ?\<Pi> = "\<phi> \<Psi>"
+ have nb: "\<forall>(v, a) \<in> dom ?s'.
+ \<forall>(v, a') \<in> dom ?s'.
+ ?s' (v, a) = Some True \<and> ?s' (v, a') = Some True
+ \<longrightarrow> (v, a) = (v, a')"
+ using state_to_strips_state_effect_consistent[OF assms(1)]
+ by blast
+ {
+ fix op\<^sub>1' op\<^sub>2'
+ assume "op\<^sub>1' \<in> set ops'" and "op\<^sub>2' \<in> set ops'"
+ hence "STRIPS_Semantics.are_operator_effects_consistent op\<^sub>1' op\<^sub>2'"
+ using assms(3)
+ unfolding STRIPS_Semantics.are_all_operator_effects_consistent_def list_all_iff
+ by blast
+ } note nb\<^sub>1 = this
+ {
+ fix op\<^sub>1 op\<^sub>1' op\<^sub>2 op\<^sub>2'
+ assume op\<^sub>1_in_ops: "op\<^sub>1 \<in> set ?ops"
+ and op\<^sub>1'_in_ops': "op\<^sub>1' \<in> set ops'"
+ and op\<^sub>1'_is: "op\<^sub>1' = \<phi>\<^sub>O \<Psi> op\<^sub>1"
+ and is_valid_op\<^sub>1: "is_valid_operator_sas_plus \<Psi> op\<^sub>1"
+ and op\<^sub>2_in_ops: "op\<^sub>2 \<in> set ?ops"
+ and op\<^sub>2'_in_ops': "op\<^sub>2' \<in> set ops'"
+ and op\<^sub>2'_is: "op\<^sub>2' = \<phi>\<^sub>O \<Psi> op\<^sub>2"
+ and is_valid_op\<^sub>2: "is_valid_operator_sas_plus \<Psi> op\<^sub>2"
+ have "\<forall>(v, a) \<in> set (add_effects_of op\<^sub>1'). \<forall>(v', a') \<in> set (add_effects_of op\<^sub>2').
+ v \<noteq> v' \<or> a = a'"
+ proof (rule ccontr)
+ assume "\<not>(\<forall>(v, a) \<in> set (add_effects_of op\<^sub>1'). \<forall>(v', a') \<in> set (add_effects_of op\<^sub>2').
+ v \<noteq> v' \<or> a = a')"
+ then obtain v v' a a' where "(v, a) \<in> set (add_effects_of op\<^sub>1')"
+ and "(v', a') \<in> set (add_effects_of op\<^sub>2')"
+ and "v = v'"
+ and "a \<noteq> a'"
+ by blast
+ \<comment> \<open> TODO slow. \<close>
+ moreover have "(v, a) \<in> set (effect_of op\<^sub>1)"
+ using op\<^sub>1'_is op\<^sub>2'_is calculation(1, 2)
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def
+ by force
+ moreover {
+ have "(v', a') \<in> set (effect_of op\<^sub>2)"
+ using op\<^sub>2'_is calculation(2)
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def
+ by force
+ hence "a' \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_operator_sas_plus_then is_valid_op\<^sub>2 calculation(3)
+ by fastforce
+ }
+ moreover have "(v, a') \<in> set (delete_effects_of op\<^sub>1')"
+ using sasp_op_to_strips_set_delete_effects_is
+ op\<^sub>1'_is is_valid_op\<^sub>1 calculation(3, 4, 5, 6)
+ by blast
+ moreover have "\<not>STRIPS_Semantics.are_operator_effects_consistent op\<^sub>1' op\<^sub>2'"
+ unfolding STRIPS_Semantics.are_operator_effects_consistent_def list_ex_iff
+ using calculation(2, 3, 7)
+ by meson
+ ultimately show False
+ using assms(3) op\<^sub>1'_in_ops' op\<^sub>2'_in_ops'
+ unfolding STRIPS_Semantics.are_all_operator_effects_consistent_def list_all_iff
+ by blast
+ qed
+ } note nb\<^sub>3 = this
+ {
+ fix op\<^sub>1 op\<^sub>2
+ assume op\<^sub>1_in_ops: "op\<^sub>1 \<in> set ?ops" and op\<^sub>2_in_ops: "op\<^sub>2 \<in> set ?ops"
+ moreover have op\<^sub>1_in_operators_of_\<Psi>: "op\<^sub>1 \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ and op\<^sub>2_in_operators_of_\<Psi>: "op\<^sub>2 \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using to_sas_plus_list_of_transformed_sas_plus_problem_operators_structure[OF
+ assms(1, 2)] calculation
+ by blast+
+ moreover have is_valid_operator_op\<^sub>1: "is_valid_operator_sas_plus \<Psi> op\<^sub>1"
+ and is_valid_operator_op\<^sub>2: "is_valid_operator_sas_plus \<Psi> op\<^sub>2"
+ using is_valid_problem_sas_plus_then(2) op\<^sub>1_in_operators_of_\<Psi> op\<^sub>2_in_operators_of_\<Psi>
+ assms(1)
+ unfolding is_valid_operator_sas_plus_def
+ by auto+
+ moreover obtain op\<^sub>1' op\<^sub>2'
+ where op\<^sub>1_in_ops': "op\<^sub>1' \<in> set ops'"
+ and op\<^sub>1_is: "op\<^sub>1' = \<phi>\<^sub>O \<Psi> op\<^sub>1"
+ and op\<^sub>2_in_ops': "op\<^sub>2' \<in> set ops'"
+ and op\<^sub>2_is: "op\<^sub>2' = \<phi>\<^sub>O \<Psi> op\<^sub>2"
+ using to_sas_plus_list_of_transformed_sas_plus_problem_operators_structure[OF
+ assms(1, 2)] op\<^sub>1_in_ops op\<^sub>2_in_ops
+ by blast
+ \<comment> \<open> TODO slow.\<close>
+ ultimately have "\<forall>(v, a) \<in> set (add_effects_of op\<^sub>1'). \<forall>(v', a') \<in> set (add_effects_of op\<^sub>2').
+ v \<noteq> v' \<or> a = a'"
+ using nb\<^sub>3
+ by auto
+ hence "are_operator_effects_consistent op\<^sub>1 op\<^sub>2"
+ using op\<^sub>1_is op\<^sub>2_is
+ unfolding are_operator_effects_consistent_def
+ sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ list_all_iff Let_def
+ by simp
+ }
+ thus ?thesis
+ unfolding are_all_operator_effects_consistent_def list_all_iff
+ by fast
+qed
+
+\<comment> \<open> A technical lemmas used in \<open>sas_plus_equivalent_to_strips_i_a\<close> showing that
+the execution precondition is linear w.r.t. to STRIPS transformation to SAS+.
+
+The second premise states that the given STRIPS state corresponds to a consistent SAS+ state (i.e.
+no two assignments of the same variable to different values exist). \<close>
+(*
+ \<^item> TODO make private.
+ \<^item> TODO decrement suffix *)
+lemma sas_plus_equivalent_to_strips_i_a_IV:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "set ops' \<subseteq> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and "STRIPS_Semantics.are_all_operators_applicable (\<phi>\<^sub>S \<Psi> s) ops'
+ \<and> STRIPS_Semantics.are_all_operator_effects_consistent ops'"
+ shows "are_all_operators_applicable_in (\<phi>\<^sub>S\<inverse> \<Psi> (\<phi>\<^sub>S \<Psi> s)) [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops'] \<and>
+ are_all_operator_effects_consistent [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ and ?s' = "\<phi>\<^sub>S \<Psi> s"
+ let ?vs' = "strips_problem.variables_of ?\<Pi>"
+ and ?ops' = "strips_problem.operators_of ?\<Pi>"
+ and ?vs = "variables_of \<Psi>"
+ and ?D = "range_of \<Psi>"
+ and ?s = "\<phi>\<^sub>S\<inverse> \<Psi> ?s'"
+ and ?ops = "[\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ have nb: "\<forall>(v, a) \<in> dom ?s'.
+ \<forall>(v, a') \<in> dom (\<phi>\<^sub>S \<Psi> s).
+ ?s' (v, a) = Some True \<and> ?s' (v, a') = Some True
+ \<longrightarrow> (v, a) = (v, a')"
+ using state_to_strips_state_effect_consistent[OF assms(1)]
+ by blast
+ {
+ have "STRIPS_Semantics.are_all_operators_applicable ?s' ops'"
+ using assms(3)
+ by simp
+ moreover have "list_all (\<lambda>op. map_of (precondition_of op) \<subseteq>\<^sub>m ?s) ?ops"
+ using sas_plus_equivalent_to_strips_i_a_I[OF assms(1) assms(2)] calculation
+ unfolding list_all_iff
+ by blast
+ moreover have "list_all (\<lambda>op. list_all (are_operator_effects_consistent op) ?ops) ?ops"
+ using sas_plus_equivalent_to_strips_i_a_II assms nb
+ unfolding are_all_operator_effects_consistent_def is_valid_operator_sas_plus_def list_all_iff
+ by blast
+ ultimately have "are_all_operators_applicable_in ?s ?ops"
+ unfolding are_all_operators_applicable_in_def is_operator_applicable_in_def list_all_iff
+ by argo
+ }
+ moreover have "are_all_operator_effects_consistent ?ops"
+ using sas_plus_equivalent_to_strips_i_a_II assms nb
+ by simp
+ ultimately show ?thesis
+ by simp
+qed
+
+(* TODO:
+ \<^item> prune premises + make private.
+ \<^item> decrement suffixes
+*)
+lemma sas_plus_equivalent_to_strips_i_a_VI:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "dom s \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom s. the (s v) \<in> \<R>\<^sub>+ \<Psi> v"
+ and "set ops' \<subseteq> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and "are_all_operators_applicable_in s [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops'] \<and>
+ are_all_operator_effects_consistent [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ shows "STRIPS_Semantics.are_all_operators_applicable (\<phi>\<^sub>S \<Psi> s) ops'"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?D = "range_of \<Psi>"
+ and ?\<Pi> = "\<phi> \<Psi>"
+ and ?ops = "[\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ and ?s' = "\<phi>\<^sub>S \<Psi> s"
+ \<comment> \<open> TODO refactor. \<close>
+ {
+ fix op'
+ assume "op' \<in> set ops'"
+ moreover obtain op where "op \<in> set ?ops" and "op = \<phi>\<^sub>O\<inverse> \<Psi> op'"
+ using calculation
+ by force
+ moreover obtain op'' where "op'' \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)" and "op' = \<phi>\<^sub>O \<Psi> op''"
+ using assms(4) calculation(1)
+ by auto
+ moreover have "is_valid_operator_sas_plus \<Psi> op''"
+ using is_valid_problem_sas_plus_then(2) assms(1) calculation(4)
+ unfolding is_valid_operator_sas_plus_def
+ by auto
+ moreover have "op = op''"
+ using sas_plus_operator_inverse_is[OF assms(1)] calculation(3, 4, 5)
+ by blast
+ ultimately have "\<exists>op \<in> set ?ops. op \<in> set ?ops \<and> op = (\<phi>\<^sub>O\<inverse> \<Psi> op')
+ \<and> is_valid_operator_sas_plus \<Psi> op"
+ by blast
+ } note nb\<^sub>1 = this
+ have nb\<^sub>2: "\<forall>(v, a) \<in> dom ?s'.
+ \<forall>(v, a') \<in> dom ?s'.
+ ?s' (v, a) = Some True \<and> ?s' (v, a') = Some True
+ \<longrightarrow> (v, a) = (v, a')"
+ using state_to_strips_state_effect_consistent[OF assms(1), of _ _ s]
+ by blast
+ {
+ fix op
+ assume "op \<in> set ?ops"
+ hence "map_of (precondition_of op) \<subseteq>\<^sub>m s"
+ using assms(5)
+ unfolding are_all_operators_applicable_in_def
+ is_operator_applicable_in_def list_all_iff
+ by blast
+ } note nb\<^sub>3 = this
+ {
+ fix op'
+ assume "op' \<in> set ops'"
+ then obtain op where op_in_ops: "op \<in> set ?ops"
+ and op_is: "op = (\<phi>\<^sub>O\<inverse> \<Psi> op')"
+ and is_valid_operator_op: "is_valid_operator_sas_plus \<Psi> op"
+ using nb\<^sub>1
+ by force
+ moreover have preconditions_are_consistent:
+ "\<forall>(v, a) \<in> set (precondition_of op). \<forall>(v', a') \<in> set (precondition_of op). v \<noteq> v' \<or> a = a'"
+ using is_valid_operator_sas_plus_then(5) calculation(3)
+ unfolding is_valid_operator_sas_plus_def
+ by fast
+ moreover {
+ fix v a
+ assume "(v, a) \<in> set (strips_operator.precondition_of op')"
+ moreover have v_a_in_precondition_of_op: "(v, a) \<in> set (precondition_of op)"
+ using op_is calculation
+ unfolding SAS_Plus_STRIPS.strips_op_to_sasp_def
+ strips_op_to_sasp_def
+ by auto
+ moreover have "map_of (precondition_of op) v = Some a"
+ using map_of_constant_assignments_defined_if[OF
+ preconditions_are_consistent calculation(2)]
+ by blast
+ moreover have s_of_v_is: "s v = Some a"
+ using nb\<^sub>3[OF op_in_ops] calculation(3)
+ unfolding map_le_def
+ by force
+ moreover have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)" and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_operator_sas_plus_then(1, 2) is_valid_operator_op
+ v_a_in_precondition_of_op
+ unfolding is_valid_operator_sas_plus_def
+ SAS_Plus_Representation.is_valid_operator_sas_plus_def Let_def list_all_iff ListMem_iff
+ by auto+
+ moreover have "(v, a) \<in> dom ?s'"
+ using state_to_strips_state_dom_is[OF assms(1)] s_of_v_is
+ calculation
+ by simp
+ moreover have "(\<phi>\<^sub>S\<inverse> \<Psi> ?s') v = Some a"
+ using strips_state_to_state_inverse_is[OF assms(1, 2, 3)] s_of_v_is
+ by argo
+ \<comment> \<open> TODO slow. \<close>
+ ultimately have "?s' (v, a) = Some True"
+ using strips_state_to_state_range_is[OF assms(1)] nb\<^sub>2
+ by auto
+ }
+ ultimately have "\<forall>(v, a) \<in> set (strips_operator.precondition_of op'). ?s' (v, a) = Some True"
+ by fast
+ }
+ thus ?thesis
+ unfolding are_all_operators_applicable_def is_operator_applicable_in_def
+ STRIPS_Representation.is_operator_applicable_in_def list_all_iff
+ by simp
+qed
+
+(* TODO Prune premises. *)
+lemma sas_plus_equivalent_to_strips_i_a_VII:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "dom s \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom s. the (s v) \<in> \<R>\<^sub>+ \<Psi> v"
+ and "set ops' \<subseteq> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and "are_all_operators_applicable_in s [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops'] \<and>
+ are_all_operator_effects_consistent [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ shows "STRIPS_Semantics.are_all_operator_effects_consistent ops'"
+proof -
+ let ?s' = "\<phi>\<^sub>S \<Psi> s"
+ and ?ops = "[\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ and ?D = "range_of \<Psi>"
+ and ?\<Pi> = "\<phi> \<Psi>"
+ \<comment> \<open> TODO refactor. \<close>
+ {
+ fix op'
+ assume "op' \<in> set ops'"
+ moreover obtain op where "op \<in> set ?ops" and "op = \<phi>\<^sub>O\<inverse> \<Psi> op'"
+ using calculation
+ by force
+ moreover obtain op'' where "op'' \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)" and "op' = \<phi>\<^sub>O \<Psi> op''"
+ using assms(4) calculation(1)
+ by auto
+ moreover have "is_valid_operator_sas_plus \<Psi> op''"
+ using is_valid_problem_sas_plus_then(2) assms(1) calculation(4)
+ unfolding is_valid_operator_sas_plus_def
+ by auto
+ moreover have "op = op''"
+ using sas_plus_operator_inverse_is[OF assms(1)] calculation(3, 4, 5)
+ by blast
+ ultimately have "\<exists>op \<in> set ?ops. op \<in> set ?ops \<and> op' = (\<phi>\<^sub>O \<Psi> op)
+ \<and> is_valid_operator_sas_plus \<Psi> op"
+ by blast
+ } note nb\<^sub>1 = this
+ {
+ fix op\<^sub>1' op\<^sub>2'
+ assume "op\<^sub>1' \<in> set ops'"
+ and "op\<^sub>2' \<in> set ops'"
+ and "\<exists>(v, a) \<in> set (add_effects_of op\<^sub>1'). \<exists>(v', a') \<in> set (delete_effects_of op\<^sub>2').
+ (v, a) = (v', a')"
+ moreover obtain op\<^sub>1 op\<^sub>2
+ where "op\<^sub>1 \<in> set ?ops"
+ and "op\<^sub>1' = \<phi>\<^sub>O \<Psi> op\<^sub>1"
+ and "is_valid_operator_sas_plus \<Psi> op\<^sub>1"
+ and "op\<^sub>2 \<in> set ?ops"
+ and "op\<^sub>2' = \<phi>\<^sub>O \<Psi> op\<^sub>2"
+ and is_valid_op\<^sub>2: "is_valid_operator_sas_plus \<Psi> op\<^sub>2"
+ using nb\<^sub>1 calculation(1, 2)
+ by meson
+ moreover obtain v v' a a'
+ where "(v, a) \<in> set (add_effects_of op\<^sub>1')"
+ and "(v', a') \<in> set (delete_effects_of op\<^sub>2')"
+ and "(v, a) = (v', a')"
+ using calculation
+ by blast
+ moreover have "(v, a) \<in> set (effect_of op\<^sub>1)"
+ using calculation(5, 10)
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def
+ by fastforce
+ moreover have "v = v'" and "a = a'"
+ using calculation(12)
+ by simp+
+ \<comment> \<open> The next proof block shows that \<open>(v', a')\<close> is constructed from an effect \<open>(v'', a'')\<close>
+ s.t. \<open>a' \<noteq> a''\<close>. \<close>
+ moreover {
+ (* TODO slow. *)
+ have "(v', a') \<in> (\<Union>(v'', a'') \<in> set (effect_of op\<^sub>2).
+ { (v'', a''') | a'''. a''' \<in> (\<R>\<^sub>+ \<Psi> v'') \<and> a''' \<noteq> a'' })"
+ using sasp_op_to_strips_set_delete_effects_is
+ calculation(8, 11) is_valid_op\<^sub>2
+ by blast
+ then obtain v'' a'' where "(v'', a'') \<in> set (effect_of op\<^sub>2)"
+ and "(v', a') \<in> { (v'', a''') | a'''. a''' \<in> (\<R>\<^sub>+ \<Psi> v'') \<and> a''' \<noteq> a'' }"
+ by blast
+ moreover have "(v', a'') \<in> set (effect_of op\<^sub>2)"
+ using calculation
+ by blast
+ moreover have "a' \<in> \<R>\<^sub>+ \<Psi> v''" and "a' \<noteq> a''"
+ using calculation(1, 2)
+ by fast+
+ ultimately have "\<exists>a''. (v', a'') \<in> set (effect_of op\<^sub>2) \<and> a' \<in> (\<R>\<^sub>+ \<Psi> v')
+ \<and> a' \<noteq> a''"
+ by blast
+ }
+ moreover obtain a'' where "(v', a'') \<in> set (effect_of op\<^sub>2)"
+ and "a' \<in> \<R>\<^sub>+ \<Psi> v'"
+ and "a' \<noteq> a''"
+ using calculation(16)
+ by blast
+ moreover have "\<exists>(v, a) \<in> set (effect_of op\<^sub>1). (\<exists>(v', a') \<in> set (effect_of op\<^sub>2).
+ v = v' \<and> a \<noteq> a')"
+ using calculation(13, 14, 15, 17, 19)
+ by blast
+ moreover have "\<not>are_operator_effects_consistent op\<^sub>1 op\<^sub>2"
+ unfolding are_operator_effects_consistent_def list_all_iff
+ using calculation(20)
+ by fastforce
+ ultimately have "\<not>are_all_operator_effects_consistent ?ops"
+ unfolding are_all_operator_effects_consistent_def list_all_iff
+ by meson
+ } note nb\<^sub>2 = this
+ {
+ fix op\<^sub>1' op\<^sub>2'
+ assume op\<^sub>1'_in_ops: "op\<^sub>1' \<in> set ops'" and op\<^sub>2'_in_ops: "op\<^sub>2' \<in> set ops'"
+ have "STRIPS_Semantics.are_operator_effects_consistent op\<^sub>1' op\<^sub>2'"
+ proof (rule ccontr)
+ assume "\<not>STRIPS_Semantics.are_operator_effects_consistent op\<^sub>1' op\<^sub>2'"
+ then consider (A) "\<exists>(v, a) \<in> set (add_effects_of op\<^sub>1').
+ \<exists>(v', a') \<in> set (delete_effects_of op\<^sub>2'). (v, a) = (v', a')"
+ | (B) "\<exists>(v, a) \<in> set (add_effects_of op\<^sub>2').
+ \<exists>(v', a') \<in> set (delete_effects_of op\<^sub>1'). (v, a) = (v', a')"
+ unfolding STRIPS_Semantics.are_operator_effects_consistent_def list_ex_iff
+ by fastforce
+ thus False
+ using nb\<^sub>2[OF op\<^sub>1'_in_ops op\<^sub>2'_in_ops] nb\<^sub>2[OF op\<^sub>2'_in_ops op\<^sub>1'_in_ops] assms(5)
+ by (cases, argo, force)
+ qed
+ }
+ thus ?thesis
+ unfolding STRIPS_Semantics.are_all_operator_effects_consistent_def
+ STRIPS_Semantics.are_operator_effects_consistent_def list_all_iff
+ by blast
+qed
+
+lemma sas_plus_equivalent_to_strips_i_a_VIII:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "dom s \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom s. the (s v) \<in> \<R>\<^sub>+ \<Psi> v"
+ and "set ops' \<subseteq> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and "are_all_operators_applicable_in s [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops'] \<and>
+ are_all_operator_effects_consistent [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ shows "STRIPS_Semantics.are_all_operators_applicable (\<phi>\<^sub>S \<Psi> s) ops'
+ \<and> STRIPS_Semantics.are_all_operator_effects_consistent ops'"
+ using sas_plus_equivalent_to_strips_i_a_VI sas_plus_equivalent_to_strips_i_a_VII assms
+ by fastforce
+
+(* TODO refactor. *)
+lemma sas_plus_equivalent_to_strips_i_a_IX:
+ assumes "dom s \<subseteq> V"
+ and "\<forall>op \<in> set ops. \<forall>(v, a) \<in> set (effect_of op). v \<in> V"
+ shows "dom (execute_parallel_operator_sas_plus s ops) \<subseteq> V"
+proof -
+ show ?thesis
+ using assms
+ proof (induction ops arbitrary: s)
+ case Nil
+ then show ?case
+ unfolding execute_parallel_operator_sas_plus_def
+ by simp
+ next
+ case (Cons op ops)
+ let ?s' = "s ++ map_of (effect_of op)"
+ \<comment> \<open> TODO Wrap IH instantiation in block. \<close>
+ {
+ have "\<forall>(v, a) \<in> set (effect_of op). v \<in> V"
+ using Cons.prems(2)
+ by fastforce
+ moreover have "fst ` set (effect_of op) \<subseteq> V"
+ using calculation
+ by fastforce
+ ultimately have "dom ?s' \<subseteq> V"
+ unfolding dom_map_add dom_map_of_conv_image_fst
+ using Cons.prems(1)
+ by blast
+ }
+ moreover have "\<forall>op \<in> set ops. \<forall>(v, a) \<in> set (effect_of op). v \<in> V"
+ using Cons.prems(2)
+ by fastforce
+ ultimately have "dom (execute_parallel_operator_sas_plus ?s' ops) \<subseteq> V"
+ using Cons.IH[of ?s']
+ by fast
+ thus ?case
+ unfolding execute_parallel_operator_sas_plus_cons.
+ qed
+qed
+
+\<comment> \<open> NOTE Show that the domain value constraint on states is monotonous w.r.t. to valid operator
+execution. I.e. if a parallel operator is executed on a state for which the domain value constraint
+holds, the domain value constraint will also hold on the resultant state. \<close>
+(* TODO refactor.
+ TODO Rewrite lemma without domain function, i.e. \<open>set (the (D v)) \<leadsto> D\<close> *)
+lemma sas_plus_equivalent_to_strips_i_a_X:
+ assumes "dom s \<subseteq> V"
+ and "V \<subseteq> dom D"
+ and "\<forall>v \<in> dom s. the (s v) \<in> set (the (D v))"
+ and "\<forall>op \<in> set ops. \<forall>(v, a) \<in> set (effect_of op). v \<in> V \<and> a \<in> set (the (D v))"
+ shows "\<forall>v \<in> dom (execute_parallel_operator_sas_plus s ops).
+ the (execute_parallel_operator_sas_plus s ops v) \<in> set (the (D v))"
+proof -
+ show ?thesis
+ using assms
+ proof (induction ops arbitrary: s)
+ case Nil
+ then show ?case
+ unfolding execute_parallel_operator_sas_plus_def
+ by simp
+ next
+ case (Cons op ops)
+ let ?s' = "s ++ map_of (effect_of op)"
+ {
+ {
+ have "\<forall>(v, a) \<in> set (effect_of op). v \<in> V"
+ using Cons.prems(4)
+ by fastforce
+ moreover have "fst ` set (effect_of op) \<subseteq> V"
+ using calculation
+ by fastforce
+ ultimately have "dom ?s' \<subseteq> V"
+ unfolding dom_map_add dom_map_of_conv_image_fst
+ using Cons.prems(1)
+ by blast
+ }
+ moreover {
+ fix v
+ assume v_in_dom_s': "v \<in> dom ?s'"
+ hence "the (?s' v) \<in> set (the (D v))"
+ proof (cases "v \<in> dom (map_of (effect_of op))")
+ case True
+ moreover have "?s' v = (map_of (effect_of op)) v"
+ unfolding map_add_dom_app_simps(1)[OF True]
+ by blast
+ moreover obtain a where "(map_of (effect_of op)) v = Some a"
+ using calculation(1)
+ by fast
+ moreover have "(v, a) \<in> set (effect_of op)"
+ using map_of_SomeD calculation(3)
+ by fast
+ moreover have "a \<in> set (the (D v))"
+ using Cons.prems(4) calculation(4)
+ by fastforce
+ ultimately show ?thesis
+ by force
+ next
+ case False
+ then show ?thesis
+ unfolding map_add_dom_app_simps(3)[OF False]
+ using Cons.prems(3) v_in_dom_s'
+ by fast
+ qed
+ }
+ moreover have "\<forall>op \<in> set ops. \<forall>(v, a) \<in> set (effect_of op). v \<in> V \<and> a \<in> set (the (D v))"
+ using Cons.prems(4)
+ by auto
+ ultimately have "\<forall>v \<in> dom (execute_parallel_operator_sas_plus ?s' ops).
+ the (execute_parallel_operator_sas_plus ?s' ops v) \<in> set (the (D v))"
+ using Cons.IH[of "s ++ map_of (effect_of op)", OF _ Cons.prems(2)]
+ by meson
+ }
+ thus ?case
+ unfolding execute_parallel_operator_sas_plus_cons
+ by blast
+ qed
+qed
+
+lemma transfom_sas_plus_problem_to_strips_problem_operators_valid:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "op' \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ obtains op
+ where "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ and "op' = (\<phi>\<^sub>O \<Psi> op)" "is_valid_operator_sas_plus \<Psi> op"
+proof -
+ {
+ obtain op where "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)" and "op' = \<phi>\<^sub>O \<Psi> op"
+ using assms
+ by auto
+ moreover have "is_valid_operator_sas_plus \<Psi> op"
+ using is_valid_problem_sas_plus_then(2) assms(1) calculation(1)
+ by auto
+ ultimately have "\<exists>op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+). op' = (\<phi>\<^sub>O \<Psi> op)
+ \<and> is_valid_operator_sas_plus \<Psi> op"
+ by blast
+ }
+ thus ?thesis
+ using that
+ by blast
+qed
+
+lemma sas_plus_equivalent_to_strips_i_a_XI:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "op' \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ shows "(\<phi>\<^sub>S \<Psi> s) ++ map_of (effect_to_assignments op')
+ = \<phi>\<^sub>S \<Psi> (s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op')))"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?vs = "variables_of \<Psi>"
+ and?ops = "operators_of \<Psi>"
+ and ?ops' = "strips_problem.operators_of ?\<Pi>"
+ let ?s' = "\<phi>\<^sub>S \<Psi> s"
+ let ?t = "?s' ++ map_of (effect_to_assignments op')"
+ and ?t' = "\<phi>\<^sub>S \<Psi> (s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op')))"
+ obtain op where op'_is: "op' = (\<phi>\<^sub>O \<Psi> op)"
+ and op_in_ops: "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ and is_valid_operator_op: "is_valid_operator_sas_plus \<Psi> op"
+ using transfom_sas_plus_problem_to_strips_problem_operators_valid[OF assms]
+ by auto
+ have nb\<^sub>1: "(\<phi>\<^sub>O\<inverse> \<Psi> op') = op"
+ using sas_plus_operator_inverse_is[OF assms(1)] op'_is op_in_ops
+ by blast
+ \<comment> \<open> TODO refactor. \<close>
+ {
+
+ (*have "fst ` set (effect_to_assignments op') \<equiv>
+fst ` ((\<lambda>v. (v, True)) ` set (add_effects_of op') \<union> (\<lambda>v. (v, False)) ` set (delete_effects_of op'))"
+
+ by auto
+ then*) have "dom (map_of (effect_to_assignments op'))
+ = set (strips_operator.add_effects_of op') \<union> set (strips_operator.delete_effects_of op')"
+ unfolding dom_map_of_conv_image_fst
+ by force
+ \<comment> \<open> TODO slow.\<close>
+ also have "\<dots> = set (effect_of op) \<union> set (strips_operator.delete_effects_of op')"
+ using op'_is
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def
+ by auto
+ \<comment> \<open> TODO slow.\<close>
+ finally have "dom (map_of (effect_to_assignments op')) = set (effect_of op)
+ \<union> (\<Union>(v, a) \<in> set (effect_of op). { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ using sasp_op_to_strips_set_delete_effects_is[OF
+ is_valid_operator_op] op'_is
+ by argo
+ } note nb\<^sub>2 = this
+ have nb\<^sub>3: "dom ?t = dom ?s' \<union> set (effect_of op)
+ \<union> (\<Union>(v, a) \<in> set (effect_of op). { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ unfolding nb\<^sub>2 dom_map_add
+ by blast
+ \<comment> \<open> TODO refactor. \<close>
+ have nb\<^sub>4: "dom (s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op')))
+ = dom s \<union> fst ` set (effect_of op)"
+ unfolding dom_map_add dom_map_of_conv_image_fst nb\<^sub>1
+ by fast
+ {
+ let ?u = "s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))"
+ have "dom ?t' = (\<Union>v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> ?u v \<noteq> None }.
+ { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+ using state_to_strips_state_dom_is[OF assms(1)]
+ by presburger
+ } note nb\<^sub>5 = this
+ \<comment> \<open> TODO refactor. \<close>
+ have nb\<^sub>6: "set (add_effects_of op') = set (effect_of op)"
+ using op'_is
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def
+ by auto
+ \<comment> \<open> TODO refactor. \<close>
+ have nb\<^sub>7: "set (delete_effects_of op') = (\<Union>(v, a) \<in> set (effect_of op).
+ { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ using sasp_op_to_strips_set_delete_effects_is[OF
+ is_valid_operator_op] op'_is
+ by argo
+ \<comment> \<open> TODO refactor. \<close>
+ {
+ let ?Add = "set (effect_of op)"
+ let ?Delete = "(\<Union>(v, a) \<in> set (effect_of op).
+ { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ have dom_add: "dom (map_of (map (\<lambda>v. (v, True)) (add_effects_of op'))) = ?Add"
+ unfolding dom_map_of_conv_image_fst set_map image_comp comp_apply
+ using nb\<^sub>6
+ by simp
+ have dom_delete: "dom (map_of (map (\<lambda>v. (v, False)) (delete_effects_of op'))) = ?Delete"
+ unfolding dom_map_of_conv_image_fst set_map image_comp comp_apply
+ using nb\<^sub>7
+ by auto
+ {
+ {
+ fix v a
+ assume v_a_in_dom_add: "(v, a) \<in> dom (map_of (map (\<lambda>v. (v, True)) (add_effects_of op')))"
+ have "(v, a) \<notin> dom (map_of (map (\<lambda>v. (v, False)) (delete_effects_of op')))"
+ proof (rule ccontr)
+ assume "\<not>((v, a) \<notin> dom (map_of (map (\<lambda>v. (v, False)) (delete_effects_of op'))))"
+ then have "(v, a) \<in> ?Delete" and "(v, a) \<in> ?Add"
+ using dom_add dom_delete v_a_in_dom_add
+ by argo+
+ moreover have "\<forall>(v', a') \<in> ?Add. v \<noteq> v' \<or> a = a'"
+ using is_valid_operator_sas_plus_then(6) is_valid_operator_op
+ calculation(2)
+ unfolding is_valid_operator_sas_plus_def
+ by fast
+ ultimately show False
+ by fast
+ qed
+ }
+ hence "disjnt (dom (map_of (map (\<lambda>v. (v, True)) (add_effects_of op'))))
+ (dom (map_of (map (\<lambda>v. (v, False)) (delete_effects_of op'))))"
+ unfolding disjnt_def Int_def
+ using nb\<^sub>7
+ by simp
+ }
+ hence "dom (map_of (map (\<lambda>v. (v, True)) (add_effects_of op'))) = ?Add"
+ and "dom (map_of (map (\<lambda>v. (v, False)) (delete_effects_of op'))) = ?Delete"
+ and "disjnt (dom (map_of (map (\<lambda>v. (v, True)) (add_effects_of op'))))
+ (dom (map_of (map (\<lambda>v. (v, False)) (delete_effects_of op'))))"
+ using dom_add dom_delete
+ by blast+
+ } note nb\<^sub>8 = this
+ \<comment> \<open> TODO refactor. \<close>
+ {
+ let ?Add = "set (effect_of op)"
+ let ?Delete = "(\<Union>(v, a) \<in> set (effect_of op).
+ { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ \<comment> \<open> TODO slow.\<close>
+ have "\<forall>(v, a) \<in> ?Add. map_of (effect_to_assignments op') (v, a) = Some True"
+ and "\<forall>(v, a) \<in> ?Delete. map_of (effect_to_assignments op') (v, a) = Some False"
+ proof -
+ {
+ fix v a
+ assume "(v, a) \<in> ?Add"
+ hence "map_of (effect_to_assignments op') (v, a) = Some True"
+ unfolding effect_to_assignments_simp
+ using nb\<^sub>6 map_of_defined_if_constructed_from_list_of_constant_assignments[of
+ "map (\<lambda>v. (v, True)) (add_effects_of op')" True "add_effects_of op'"]
+ by force
+ }
+ moreover {
+ fix v a
+ assume "(v, a) \<in> ?Delete"
+ moreover have "(v, a) \<in> dom (map_of (map (\<lambda>v. (v, False)) (delete_effects_of op')))"
+ using nb\<^sub>8(2) calculation(1)
+ by argo
+ moreover have "(v, a) \<notin> dom (map_of (map (\<lambda>v. (v, True)) (add_effects_of op')))"
+ using nb\<^sub>8
+ unfolding disjnt_def
+ using calculation(1)
+ by blast
+ moreover have "map_of (effect_to_assignments op') (v, a)
+ = map_of (map (\<lambda>v. (v, False)) (delete_effects_of op')) (v, a)"
+ unfolding effect_to_assignments_simp map_of_append
+ using map_add_dom_app_simps(3)[OF calculation(3)]
+ by presburger
+ \<comment> \<open> TODO slow. \<close>
+ ultimately have "map_of (effect_to_assignments op') (v, a) = Some False"
+ using map_of_defined_if_constructed_from_list_of_constant_assignments[
+ of "map (\<lambda>v. (v, False)) (delete_effects_of op')" False "delete_effects_of op'"]
+ nb\<^sub>7
+ by auto
+ }
+ ultimately show "\<forall>(v, a) \<in> ?Add. map_of (effect_to_assignments op') (v, a) = Some True"
+ and "\<forall>(v, a) \<in> ?Delete. map_of (effect_to_assignments op') (v, a) = Some False"
+ by blast+
+ qed
+ } note nb\<^sub>9 = this
+ {
+ fix v a
+ assume "(v, a) \<in> set (effect_of op)"
+ moreover have "\<forall>(v, a) \<in> set (effect_of op). \<forall>(v', a') \<in> set (effect_of op). v \<noteq> v' \<or> a = a'"
+ using is_valid_operator_sas_plus_then is_valid_operator_op
+ unfolding is_valid_operator_sas_plus_def
+ by fast
+ ultimately have "map_of (effect_of op) v = Some a"
+ using map_of_constant_assignments_defined_if[of "effect_of op"]
+ by presburger
+ } note nb\<^sub>1\<^sub>0 = this
+ {
+ fix v a
+ assume v_a_in_effect_of_op: "(v, a) \<in> set (effect_of op)"
+ and "(s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))) v \<noteq> None"
+ moreover have "v \<in> set ?vs"
+ using is_valid_operator_op is_valid_operator_sas_plus_then(3) calculation(1)
+ by fastforce
+ moreover {
+ have "is_valid_problem_strips ?\<Pi>"
+ using is_valid_problem_sas_plus_then_strips_transformation_too
+ assms(1)
+ by blast
+ thm calculation(1) nb\<^sub>6 assms(2)
+ moreover have "set (add_effects_of op') \<subseteq> set ((?\<Pi>)\<^sub>\<V>)"
+ using assms(2) is_valid_problem_strips_operator_variable_sets(2)
+ calculation
+ by blast
+ moreover have "(v, a) \<in> set ((?\<Pi>)\<^sub>\<V>)"
+ using v_a_in_effect_of_op nb\<^sub>6 calculation(2)
+ by blast
+ ultimately have "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using sas_plus_problem_to_strips_problem_variable_set_element_iff[OF
+ assms(1)]
+ by fast
+ }
+ \<comment> \<open> TODO slow. \<close>
+ ultimately have "(v, a) \<in> dom (\<phi>\<^sub>S \<Psi> (s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))))"
+ using state_to_strips_state_dom_is[OF assms(1), of
+ "s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))"]
+ by simp
+ } note nb\<^sub>1\<^sub>1 = this
+ {
+ fix v a
+ assume "(v, a) \<in> set (effect_of op)"
+ moreover have "v \<in> dom (map_of (effect_of op))"
+ unfolding dom_map_of_conv_image_fst
+ using calculation
+ by force
+ moreover have "(s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))) v = Some a"
+ unfolding map_add_dom_app_simps(1)[OF calculation(2)] nb\<^sub>1
+ using nb\<^sub>1\<^sub>0 calculation(1)
+ by blast
+ moreover have "(s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))) v \<noteq> None"
+ using calculation(3)
+ by auto
+ moreover have "(v, a) \<in> dom (\<phi>\<^sub>S \<Psi> (s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))))"
+ using nb\<^sub>1\<^sub>1 calculation(1, 4)
+ by presburger
+ ultimately have "(\<phi>\<^sub>S \<Psi> (s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op')))) (v, a) = Some True"
+ using state_to_strips_state_range_is[OF assms(1)]
+ by simp
+ } note nb\<^sub>1\<^sub>2 = this
+ {
+ fix v a'
+ assume "(v, a') \<in> dom (map_of (effect_to_assignments op'))"
+ and "(v, a') \<in> (\<Union>(v, a) \<in> set (effect_of op).
+ { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ moreover have "v \<in> dom (map_of (effect_of op))"
+ unfolding dom_map_of_conv_image_fst
+ using calculation(2)
+ by force
+ moreover have "v \<in> set ?vs"
+ using calculation(3) is_valid_operator_sas_plus_then(3) is_valid_operator_op
+ unfolding dom_map_of_conv_image_fst is_valid_operator_sas_plus_def
+ by fastforce
+ moreover obtain a where "(v, a) \<in> set (effect_of op)"
+ and "a' \<in> \<R>\<^sub>+ \<Psi> v"
+ and "a' \<noteq> a"
+ using calculation(2)
+ by blast
+ moreover have "(s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))) v = Some a"
+ unfolding map_add_dom_app_simps(1)[OF calculation(3)] nb\<^sub>1
+ using nb\<^sub>1\<^sub>0 calculation(5)
+ by blast
+ moreover have "(s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))) v \<noteq> None"
+ using calculation(8)
+ by auto
+ \<comment> \<open> TODO slow. \<close>
+ moreover have "(v, a') \<in> dom (\<phi>\<^sub>S \<Psi> (s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))))"
+ using state_to_strips_state_dom_is[OF assms(1), of
+ "s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))"] calculation(4, 6, 9)
+ by simp
+ \<comment> \<open> TODO slow. \<close>
+ ultimately have "(\<phi>\<^sub>S \<Psi> (s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op')))) (v, a') = Some False"
+ using state_to_strips_state_range_is[OF assms(1),
+ of v a' "s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))"]
+ by simp
+ } note nb\<^sub>1\<^sub>3 = this
+ {
+ fix v a
+ assume "(v, a) \<in> dom ?t"
+ and "(v, a) \<notin> dom (map_of (effect_to_assignments op'))"
+ moreover have "(v, a) \<in> dom ?s'"
+ using calculation(1, 2)
+ unfolding dom_map_add
+ by blast
+ moreover have "?t (v, a) = ?s' (v, a)"
+ unfolding map_add_dom_app_simps(3)[OF calculation(2)]..
+ ultimately have "?t (v, a) = Some (the (s v) = a)"
+ using state_to_strips_state_range_is[OF assms(1)]
+ by presburger
+ } note nb\<^sub>1\<^sub>4 = this
+ {
+ fix v a
+ assume "(v, a) \<in> dom ?t"
+ and v_a_not_in: "(v, a) \<notin> dom (map_of (effect_to_assignments op'))"
+ moreover have "(v, a) \<in> dom ?s'"
+ using calculation(1, 2)
+ unfolding dom_map_add
+ by blast
+ moreover have "(v, a) \<in> (\<Union> v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None }.
+ { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+ using state_to_strips_state_dom_is[OF assms(1)] calculation(3)
+ by presburger
+ moreover have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)" and "s v \<noteq> None" and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using calculation(4)
+ by blast+
+ \<comment> \<open> NOTE Hasn't this been proved before? \<close>
+ moreover {
+ have "dom (map_of (effect_to_assignments op')) = (\<Union>(v, a) \<in> set (effect_of op). { (v, a) })
+ \<union> (\<Union>(v, a) \<in> set (effect_of op).
+ { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ unfolding nb\<^sub>2
+ by blast
+ also have "\<dots> = (\<Union>(v, a) \<in> set (effect_of op). { (v, a) }
+ \<union> { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ by blast
+ finally have "dom (map_of (effect_to_assignments op'))
+ = (\<Union>(v, a) \<in> set (effect_of op). { (v, a) }
+ \<union> { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+ by auto
+ then have "(v, a) \<notin> (\<Union>(v, a) \<in> set (effect_of op).
+ { (v, a) | a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+ using v_a_not_in
+ by blast
+ }
+ \<comment> \<open> TODO slow. \<close>
+ moreover have "v \<notin> dom (map_of (effect_of op))"
+ using dom_map_of_conv_image_fst calculation
+ by fastforce
+ moreover have "(s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))) v = s v"
+ unfolding nb\<^sub>1 map_add_dom_app_simps(3)[OF calculation(9)]
+ by simp
+ \<comment> \<open> TODO slow. \<close>
+ moreover have "(v, a) \<in> dom ?t'"
+ using state_to_strips_state_dom_is[OF assms(1), of
+ "s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))"] calculation(5, 6, 7, 8, 10)
+ by simp
+ ultimately have "?t' (v, a) = Some (the (s v) = a)"
+ using state_to_strips_state_range_is[OF assms(1)]
+ by presburger
+ } note nb\<^sub>1\<^sub>5 = this
+ \<comment> \<open> TODO refactor. \<close>
+ have nb\<^sub>1\<^sub>6: "dom ?t = (\<Union> v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None }.
+ { (v, a) | a. a \<in> (\<R>\<^sub>+ \<Psi> v) })
+ \<union> set (effect_of op)
+ \<union> (\<Union>(v, a)\<in>set (effect_of op).
+ {(v, a') |a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a})"
+ unfolding dom_map_add nb\<^sub>2
+ using state_to_strips_state_dom_is[OF assms(1), of s]
+ by auto
+ {
+ {
+ fix v a
+ assume "(v, a) \<in> dom ?t"
+ then consider (A) "(v, a) \<in> dom (\<phi>\<^sub>S \<Psi> s)"
+ | (B) "(v, a) \<in> dom (map_of (effect_to_assignments op'))"
+ by fast
+ hence "(v, a) \<in> dom ?t'"
+ proof (cases)
+ case A
+ then have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)" and "s v \<noteq> None" and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ unfolding state_to_strips_state_dom_element_iff[OF assms(1)]
+ by blast+
+ thm map_add_None state_to_strips_state_dom_element_iff[OF assms(1)]
+ moreover have "(s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))) v \<noteq> None"
+ using calculation(2)
+ by simp
+ ultimately show ?thesis
+ unfolding state_to_strips_state_dom_element_iff[OF assms(1)]
+ by blast
+ next
+ case B
+ then have "(v, a) \<in>
+ set (effect_of op)
+ \<union> (\<Union>(v, a)\<in>set (effect_of op). { (v, a') | a'. a' \<in> \<R>\<^sub>+ \<Psi> v \<and> a' \<noteq> a })"
+ unfolding nb\<^sub>2
+ by blast
+ then consider (B\<^sub>1) "(v, a) \<in> set (effect_of op)"
+ | (B\<^sub>2) "(v, a) \<in> (\<Union>(v, a)\<in>set (effect_of op).
+ { (v, a') | a'. a' \<in> \<R>\<^sub>+ \<Psi> v \<and> a' \<noteq> a })"
+ by blast
+ thm nb\<^sub>1\<^sub>2 nb\<^sub>1\<^sub>3 nb\<^sub>2
+ thus ?thesis
+ proof (cases)
+ case B\<^sub>1
+ then show ?thesis
+ using nb\<^sub>1\<^sub>2
+ by fast
+ next
+ case B\<^sub>2
+ then show ?thesis
+ using nb\<^sub>1\<^sub>3 B
+ by blast
+ qed
+ qed
+ }
+ moreover {
+ let ?u = "s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))"
+ fix v a
+ assume v_a_in_dom_t': "(v, a) \<in> dom ?t'"
+ thm nb\<^sub>5
+ then have v_in_vs: "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and u_of_v_is_not_None: "?u v \<noteq> None"
+ and a_in_range_of_v: "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using state_to_strips_state_dom_element_iff[OF assms(1)]
+ v_a_in_dom_t'
+ by meson+
+ {
+ assume "(v, a) \<notin> dom ?t"
+ then have contradiction: "(v, a) \<notin>
+ (\<Union>v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None}. { (v, a) |a. a \<in> \<R>\<^sub>+ \<Psi> v })
+ \<union> set (effect_of op)
+ \<union> (\<Union>(v, a)\<in>set (effect_of op). {(v, a') |a'. a' \<in> \<R>\<^sub>+ \<Psi> v \<and> a' \<noteq> a})"
+ unfolding nb\<^sub>1\<^sub>6
+ by fast
+ hence False
+ proof (cases "map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op')) v = None")
+ case True
+ then have "s v \<noteq> None"
+ using u_of_v_is_not_None
+ by simp
+ then have "(v, a) \<in> (\<Union>v \<in> { v | v. v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> s v \<noteq> None}.
+ { (v, a) |a. a \<in> \<R>\<^sub>+ \<Psi> v })"
+ using v_in_vs a_in_range_of_v
+ by blast
+ thus ?thesis
+ using contradiction
+ by blast
+ next
+ case False
+ then have "v \<in> dom (map_of (effect_of op))"
+ using u_of_v_is_not_None nb\<^sub>1
+ by blast
+ then obtain a' where map_of_effect_of_op_v_is: "map_of (effect_of op) v = Some a'"
+ by blast
+ then have v_a'_in: "(v, a') \<in> set (effect_of op)"
+ using map_of_SomeD
+ by fast
+ then show ?thesis
+ proof (cases "a = a'")
+ case True
+ then have "(v, a) \<in> set (effect_of op)"
+ using v_a'_in
+ by blast
+ then show ?thesis
+ using contradiction
+ by blast
+ next
+ case False
+ then have "(v, a) \<in> (\<Union>(v, a)\<in>set (effect_of op).
+ {(v, a') |a'. a' \<in> \<R>\<^sub>+ \<Psi> v \<and> a' \<noteq> a})"
+ using v_a'_in calculation a_in_range_of_v
+ by blast
+ thus ?thesis
+ using contradiction
+ by fast
+ qed
+ qed
+ }
+ hence "(v, a) \<in> dom ?t"
+ by argo
+ }
+ moreover have "dom ?t \<subseteq> dom ?t'" and "dom ?t' \<subseteq> dom ?t"
+ subgoal
+ using calculation(1) subrelI[of "dom ?t" "dom ?t'"]
+ by fast
+ subgoal
+ using calculation(2) subrelI[of "dom ?t'" "dom ?t"]
+ by argo
+ done
+ ultimately have "dom ?t = dom ?t'"
+ by force
+ } note nb\<^sub>1\<^sub>7 = this
+ {
+ fix v a
+ assume v_a_in_dom_t: "(v, a) \<in> dom ?t"
+ hence "?t (v, a) = ?t' (v, a)"
+ proof (cases "(v, a) \<in> dom (map_of (effect_to_assignments op'))")
+ case True
+ \<comment> \<open> TODO slow. \<close>
+ \<comment> \<open> NOTE Split on the (disjunct) domain variable sets of
+ @{text "map_of (effect_to_assignments op')"}. \<close>
+ then consider (A1) "(v, a) \<in> set (effect_of op)"
+ | (A2) "(v, a) \<in> (\<Union>(v, a) \<in> set (effect_of op).
+ { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ using nb\<^sub>2
+ by fastforce
+ then show ?thesis
+ proof (cases)
+ case A1
+ then have "?t (v, a) = Some True"
+ unfolding map_add_dom_app_simps(1)[OF True]
+ using nb\<^sub>9(1)
+ by fast
+ moreover have "?t' (v, a) = Some True"
+ using nb\<^sub>1\<^sub>2[OF A1].
+ ultimately show ?thesis..
+ next
+ case A2
+ then have "?t (v, a) = Some False"
+ unfolding map_add_dom_app_simps(1)[OF True]
+ using nb\<^sub>9(2)
+ by blast
+ moreover have "?t' (v, a) = Some False"
+ using nb\<^sub>1\<^sub>3[OF True A2].
+ ultimately show ?thesis..
+ qed
+ next
+ case False
+ moreover have "?t (v, a) = Some (the (s v) = a)"
+ using nb\<^sub>1\<^sub>4[OF v_a_in_dom_t False].
+ moreover have "?t' (v, a) = Some (the (s v) = a)"
+ using nb\<^sub>1\<^sub>5[OF v_a_in_dom_t False].
+ ultimately show ?thesis
+ by argo
+ qed
+ } note nb\<^sub>1\<^sub>8 = this
+ moreover {
+ fix v a
+ assume "(v, a) \<in> dom ?t'"
+ hence "?t (v, a) = ?t' (v, a)"
+ using nb\<^sub>1\<^sub>7 nb\<^sub>1\<^sub>8
+ by presburger
+ }
+ \<comment> \<open> TODO slow.\<close>
+ ultimately have "?t \<subseteq>\<^sub>m ?t'" and "?t' \<subseteq>\<^sub>m ?t"
+ unfolding map_le_def
+ by fastforce+
+ thus ?thesis
+ using map_le_antisym[of ?t ?t']
+ by fast
+qed
+
+\<comment> \<open> NOTE This is the essential step in the SAS+/STRIPS equivalence theorem. We show that executing
+a given parallel STRIPS operator @{text "ops'"} on the corresponding STRIPS state
+@{text "s' = \<phi>\<^sub>S \<Psi> s"} yields the same state as executing the transformed SAS+ parallel operator
+@{text "ops = [\<phi>\<^sub>O\<inverse> (\<phi> \<Psi>) op'. op' \<leftarrow> ops']"} on the original SAS+ state @{text "s"} and the
+transforming the resultant SAS+ state to its corresponding STRIPS state. \<close>
+(* TODO refactor. *)
+lemma sas_plus_equivalent_to_strips_i_a_XII:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "\<forall>op' \<in> set ops'. op' \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ shows "execute_parallel_operator (\<phi>\<^sub>S \<Psi> s) ops'
+ = \<phi>\<^sub>S \<Psi> (execute_parallel_operator_sas_plus s [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops'])"
+using assms
+proof (induction ops' arbitrary: s)
+ case Nil
+ then show ?case
+ unfolding execute_parallel_operator_def execute_parallel_operator_sas_plus_def
+ by simp
+next
+ case (Cons op' ops')
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?t' = "(\<phi>\<^sub>S \<Psi> s) ++ map_of (effect_to_assignments op')"
+ and ?t = "s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> op'))"
+ have nb\<^sub>1: "?t' = \<phi>\<^sub>S \<Psi> ?t"
+ using sas_plus_equivalent_to_strips_i_a_XI[OF assms(1)] Cons.prems(2)
+ by force
+ {
+ have "\<forall>op' \<in> set ops'. op' \<in> set (strips_problem.operators_of ?\<Pi>)"
+ using Cons.prems(2)
+ by simp
+ then have "execute_parallel_operator (\<phi>\<^sub>S \<Psi> ?t) ops'
+ = \<phi>\<^sub>S \<Psi> (execute_parallel_operator_sas_plus ?t [\<phi>\<^sub>O\<inverse> \<Psi> x. x \<leftarrow> ops'])"
+ using Cons.IH[OF Cons.prems(1), of ?t]
+ by fastforce
+ hence "execute_parallel_operator ?t' ops'
+ = \<phi>\<^sub>S \<Psi> (execute_parallel_operator_sas_plus ?t [\<phi>\<^sub>O\<inverse> \<Psi> x. x \<leftarrow> ops'])"
+ using nb\<^sub>1
+ by argo
+ }
+ thus ?case
+ by simp
+qed
+
+lemma sas_plus_equivalent_to_strips_i_a_XIII:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "\<forall>op' \<in> set ops'. op' \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and "(\<phi>\<^sub>S \<Psi> G) \<subseteq>\<^sub>m execute_parallel_plan
+ (execute_parallel_operator (\<phi>\<^sub>S \<Psi> I) ops') \<pi>"
+ shows "(\<phi>\<^sub>S \<Psi> G) \<subseteq>\<^sub>m execute_parallel_plan
+ (\<phi>\<^sub>S \<Psi> (execute_parallel_operator_sas_plus I [\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops'])) \<pi>"
+proof -
+ let ?I' = "(\<phi>\<^sub>S \<Psi> I)"
+ and ?G' = "\<phi>\<^sub>S \<Psi> G"
+ and ?ops = "[\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ and ?\<Pi> = "\<phi> \<Psi>"
+ let ?J = "execute_parallel_operator_sas_plus I ?ops"
+ {
+ fix v a
+ assume "(v, a) \<in> dom ?G'"
+ then have "?G' (v, a) = execute_parallel_plan
+ (execute_parallel_operator ?I' ops') \<pi> (v, a)"
+ using assms(3)
+ unfolding map_le_def
+ by auto
+ hence "?G' (v, a) = execute_parallel_plan (\<phi>\<^sub>S \<Psi> ?J) \<pi> (v, a)"
+ using sas_plus_equivalent_to_strips_i_a_XII[OF assms(1, 2)]
+ by simp
+ }
+ thus ?thesis
+ unfolding map_le_def
+ by fast
+qed
+
+\<comment> \<open> NOTE This is a more abstract formulation of the proposition in
+\<open>sas_plus_equivalent_to_strips_i\<close> which is better suited for induction proofs. We essentially claim
+that given a plan the execution in STRIPS semantics of which solves the problem of reaching a
+transformed goal state \<open>\<phi>\<^sub>S \<Psi> G\<close> from a transformed initial state \<open>\<phi>\<^sub>S \<Psi> I\<close>—such as
+the goal and initial state of an induced STRIPS problem for a SAS+ problem—is equivalent to an
+execution in SAS+ semantics of the transformed plan \<open>\<phi>\<^sub>P\<inverse> (\<phi> \<Psi>) \<pi>\<close> w.r.t to the original
+initial state \<open>I\<close> and original goal state \<open>G\<close>. \<close>
+lemma sas_plus_equivalent_to_strips_i_a:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "dom I \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom I. the (I v) \<in> \<R>\<^sub>+ \<Psi> v"
+ and "dom G \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom G. the (G v) \<in> \<R>\<^sub>+ \<Psi> v"
+ and "\<forall>ops' \<in> set \<pi>. \<forall>op' \<in> set ops'. op' \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and "(\<phi>\<^sub>S \<Psi> G) \<subseteq>\<^sub>m execute_parallel_plan (\<phi>\<^sub>S \<Psi> I) \<pi>"
+ shows "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus I (\<phi>\<^sub>P\<inverse> \<Psi> \<pi>)"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?\<psi> = "\<phi>\<^sub>P\<inverse> \<Psi> \<pi>"
+ show ?thesis
+ using assms
+ proof (induction \<pi> arbitrary: I)
+ case Nil
+ then have "(\<phi>\<^sub>S \<Psi> G) \<subseteq>\<^sub>m (\<phi>\<^sub>S \<Psi> I)"
+ by fastforce
+ then have "G \<subseteq>\<^sub>m I"
+ using state_to_strips_state_map_le_iff[OF assms(1, 4, 5)]
+ by blast
+ thus ?case
+ unfolding SAS_Plus_STRIPS.strips_parallel_plan_to_sas_plus_parallel_plan_def
+ strips_parallel_plan_to_sas_plus_parallel_plan_def
+ by fastforce
+ next
+ case (Cons ops' \<pi>)
+ let ?D = "range_of \<Psi>"
+ and ?\<Pi> = "\<phi> \<Psi>"
+ and ?I' = "\<phi>\<^sub>S \<Psi> I"
+ and ?G' = "\<phi>\<^sub>S \<Psi> G"
+ let ?ops = "[\<phi>\<^sub>O\<inverse> \<Psi> op'. op' \<leftarrow> ops']"
+ let ?J = "execute_parallel_operator_sas_plus I ?ops"
+ and ?J' = "execute_parallel_operator ?I' ops'"
+ have nb\<^sub>1: "set ops' \<subseteq> set ((?\<Pi>)\<^sub>\<O>)"
+ using Cons.prems(6)
+ unfolding STRIPS_Semantics.is_parallel_solution_for_problem_def list_all_iff ListMem_iff
+ by fastforce
+ {
+ fix op
+ assume "op \<in> set ?ops"
+ moreover obtain op' where "op' \<in> set ops'" and "op = \<phi>\<^sub>O\<inverse> \<Psi> op'"
+ using calculation
+ by auto
+ moreover have "op' \<in> set ((?\<Pi>)\<^sub>\<O>)"
+ using nb\<^sub>1 calculation(2)
+ by blast
+ moreover obtain op'' where "op'' \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)" and "op' = \<phi>\<^sub>O \<Psi> op''"
+ using calculation(4)
+ by auto
+ moreover have "op = op''"
+ using sas_plus_operator_inverse_is[OF assms(1) calculation(5)] calculation(3, 6)
+ by presburger
+ ultimately have "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+) \<and> (\<exists>op' \<in> set ops'. op' = \<phi>\<^sub>O \<Psi> op)"
+ by blast
+ } note nb\<^sub>2 = this
+ {
+ fix op v a
+ assume "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)" and "(v, a) \<in> set (effect_of op)"
+ moreover have "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using nb\<^sub>2 calculation(1)
+ by blast
+ moreover have "is_valid_operator_sas_plus \<Psi> op"
+ using is_valid_problem_sas_plus_then(2) Cons.prems(1) calculation(3)
+ by blast
+ ultimately have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using is_valid_operator_sas_plus_then(3)
+ by fastforce
+ } note nb\<^sub>3 = this
+ {
+ fix op
+ assume "op \<in> set ?ops"
+ then have "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using nb\<^sub>2
+ by blast
+ then have "is_valid_operator_sas_plus \<Psi> op"
+ using is_valid_problem_sas_plus_then(2) Cons.prems(1)
+ by blast
+ hence "\<forall>(v, a) \<in> set (effect_of op). v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)
+ \<and> a \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_operator_sas_plus_then(3,4)
+ by fast
+ } note nb\<^sub>4 = this
+ show ?case
+ proof (cases "STRIPS_Semantics.are_all_operators_applicable ?I' ops'
+ \<and> STRIPS_Semantics.are_all_operator_effects_consistent ops'")
+ case True
+ {
+ {
+ have "dom I \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using Cons.prems(2)
+ by blast
+ hence "(\<phi>\<^sub>S\<inverse> \<Psi> ?I') = I"
+ using strips_state_to_state_inverse_is[OF
+ Cons.prems(1) _ Cons.prems(3)]
+ by argo
+ }
+ then have "are_all_operators_applicable_in I ?ops
+ \<and> are_all_operator_effects_consistent ?ops"
+ using sas_plus_equivalent_to_strips_i_a_IV[OF assms(1) nb\<^sub>1, of I] True
+ by simp
+ moreover have "(\<phi>\<^sub>P\<inverse> \<Psi> (ops' # \<pi>)) = ?ops # (\<phi>\<^sub>P\<inverse> \<Psi> \<pi>)"
+ unfolding SAS_Plus_STRIPS.strips_parallel_plan_to_sas_plus_parallel_plan_def
+ strips_parallel_plan_to_sas_plus_parallel_plan_def
+ SAS_Plus_STRIPS.strips_op_to_sasp_def
+ strips_op_to_sasp_def
+ by simp
+ ultimately have "execute_parallel_plan_sas_plus I (\<phi>\<^sub>P\<inverse> \<Psi> (ops' # \<pi>))
+ = execute_parallel_plan_sas_plus ?J (\<phi>\<^sub>P\<inverse> \<Psi> \<pi>)"
+ by force
+ } note nb\<^sub>5 = this
+ \<comment> \<open> Show the goal using the IH. \<close>
+ {
+ have dom_J_subset_eq_vs: "dom ?J \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using sas_plus_equivalent_to_strips_i_a_IX[OF Cons.prems(2)] nb\<^sub>2 nb\<^sub>4
+ by blast
+ moreover {
+ have "set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<subseteq> dom (range_of \<Psi>)"
+ using is_valid_problem_sas_plus_then(1)[OF assms(1)]
+ by fastforce
+ moreover have "\<forall>v \<in> dom I. the (I v) \<in> set (the (range_of \<Psi> v))"
+ using Cons.prems(2, 3) assms(1) set_the_range_of_is_range_of_sas_plus_if
+ by force
+ moreover have "\<forall>op \<in> set ?ops. \<forall>(v, a) \<in> set (effect_of op).
+ v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+) \<and> a \<in> set (the (?D v))"
+ using set_the_range_of_is_range_of_sas_plus_if assms(1) nb\<^sub>4
+ by fastforce
+ moreover have v_in_dom_J_range: "\<forall>v \<in> dom ?J. the (?J v) \<in> set (the (?D v))"
+ using sas_plus_equivalent_to_strips_i_a_X[of
+ I "set ((\<Psi>)\<^sub>\<V>\<^sub>+)" ?D ?ops, OF Cons.prems(2)] calculation(1, 2, 3)
+ by fastforce
+ {
+ fix v
+ assume "v \<in> dom ?J"
+ moreover have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using nb\<^sub>2 calculation dom_J_subset_eq_vs
+ by blast
+ moreover have "set (the (range_of \<Psi> v)) = \<R>\<^sub>+ \<Psi> v"
+ using set_the_range_of_is_range_of_sas_plus_if[OF assms(1)]
+ calculation(2)
+ by presburger
+ ultimately have "the (?J v) \<in> \<R>\<^sub>+ \<Psi> v"
+ using nb\<^sub>3 v_in_dom_J_range
+ by blast
+ }
+ ultimately have "\<forall>v \<in> dom ?J. the (?J v) \<in> \<R>\<^sub>+ \<Psi> v"
+ by fast
+ }
+ moreover have "\<forall>ops' \<in> set \<pi>. \<forall>op'\<in>set ops'. op' \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ using Cons.prems(6)
+ by simp
+ moreover {
+ have "?G' \<subseteq>\<^sub>m execute_parallel_plan ?J' \<pi>"
+ using Cons.prems(7) True
+ by auto
+ hence "(\<phi>\<^sub>S \<Psi> G) \<subseteq>\<^sub>m execute_parallel_plan (\<phi>\<^sub>S \<Psi> ?J) \<pi>"
+ using sas_plus_equivalent_to_strips_i_a_XIII[OF Cons.prems(1)] nb\<^sub>1
+ by blast
+ }
+ ultimately have "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus I (\<phi>\<^sub>P\<inverse> \<Psi> (ops' # \<pi>))"
+ using Cons.IH[of ?J, OF Cons.prems(1) _ _ Cons.prems(4, 5)] Cons.prems(6) nb\<^sub>5
+ by presburger
+ }
+ thus ?thesis.
+ next
+ case False
+ then have "?G' \<subseteq>\<^sub>m ?I'"
+ using Cons.prems(7)
+ by force
+ moreover {
+ have "dom I \<subseteq> set ?vs"
+ using Cons.prems(2)
+ by simp
+ hence "\<not>(are_all_operators_applicable_in I ?ops
+ \<and> are_all_operator_effects_consistent ?ops)"
+ using sas_plus_equivalent_to_strips_i_a_VIII[OF Cons.prems(1) _ Cons.prems(3) nb\<^sub>1]
+ False
+ by force
+ }
+ moreover {
+ have "(\<phi>\<^sub>P\<inverse> \<Psi> (ops' # \<pi>)) = ?ops # (\<phi>\<^sub>P\<inverse> \<Psi> \<pi>)"
+ unfolding SAS_Plus_STRIPS.strips_parallel_plan_to_sas_plus_parallel_plan_def
+ strips_parallel_plan_to_sas_plus_parallel_plan_def
+ SAS_Plus_STRIPS.strips_op_to_sasp_def
+ strips_op_to_sasp_def
+ by simp
+ hence "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus I (?ops # (\<phi>\<^sub>P\<inverse> \<Psi> \<pi>))
+ \<longleftrightarrow> G \<subseteq>\<^sub>m I"
+ using calculation(2)
+ by force
+ }
+ ultimately show ?thesis
+ using state_to_strips_state_map_le_iff[OF Cons.prems(1, 4, 5)]
+ unfolding SAS_Plus_STRIPS.strips_parallel_plan_to_sas_plus_parallel_plan_def
+ strips_parallel_plan_to_sas_plus_parallel_plan_def
+ SAS_Plus_STRIPS.strips_op_to_sasp_def
+ strips_op_to_sasp_def
+ by force
+ qed
+ qed
+qed
+
+\<comment> \<open> NOTE Show that a solution for the induced STRIPS problem for the given valid SAS+ problem,
+ corresponds to a solution for the given SAS+ problem.
+
+Note that in the context of the SAS+ problem solving pipeline, we
+\begin{enumerate}
+ \item convert the given valid SAS+ @{text "\<Psi>"} problem to the corresponding STRIPS problem
+@{text "\<Pi>"} (this is implicitely also valid by lemma
+@{text "is_valid_problem_sas_plus_then_strips_transformation_too"}); then,
+ \item get a solution @{text "\<pi>"}—if it exists—for the induced STRIPS problem by executing
+SATPlan; and finally,
+ \item convert @{text "\<pi>"} back to a solution @{text "\<psi>"} for the SAS+ problem.
+\end{enumerate} \<close>
+lemma sas_plus_equivalent_to_strips_i:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "STRIPS_Semantics.is_parallel_solution_for_problem
+ (\<phi> \<Psi>) \<pi>"
+ shows "goal_of \<Psi> \<subseteq>\<^sub>m execute_parallel_plan_sas_plus
+ (sas_plus_problem.initial_of \<Psi>) (\<phi>\<^sub>P\<inverse> \<Psi> \<pi>)"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?I = "initial_of \<Psi>"
+ and ?G = "goal_of \<Psi>"
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?G' = "strips_problem.goal_of ?\<Pi>"
+ and ?I' = "strips_problem.initial_of ?\<Pi>"
+ let ?\<psi> = "\<phi>\<^sub>P\<inverse> \<Psi> \<pi>"
+ have "dom ?I \<subseteq> set ?vs"
+ using is_valid_problem_sas_plus_then(3) assms(1)
+ by auto
+ moreover have "\<forall>v \<in> dom ?I. the (?I v) \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_problem_sas_plus_then(4) assms(1) calculation
+ by auto
+ moreover have "dom ?G \<subseteq> set ?vs" and "\<forall>v \<in> dom ?G. the (?G v) \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_problem_sas_plus_then(5, 6) assms(1)
+ by blast+
+ moreover have "\<forall>ops'\<in>set \<pi>. \<forall>op'\<in>set ops'. op' \<in> set ((?\<Pi>)\<^sub>\<O>)"
+ using is_parallel_solution_for_problem_operator_set[OF assms(2)]
+ by simp
+ moreover {
+ have "?G' \<subseteq>\<^sub>m execute_parallel_plan ?I' \<pi>"
+ using assms(2)
+ unfolding STRIPS_Semantics.is_parallel_solution_for_problem_def..
+ moreover have "?G' = \<phi>\<^sub>S \<Psi> ?G" and "?I' = \<phi>\<^sub>S \<Psi> ?I"
+ by simp+
+ ultimately have "(\<phi>\<^sub>S \<Psi> ?G) \<subseteq>\<^sub>m execute_parallel_plan (\<phi>\<^sub>S \<Psi> ?I) \<pi>"
+ by simp
+ }
+ ultimately show ?thesis
+ using sas_plus_equivalent_to_strips_i_a[OF assms(1)]
+ by simp
+qed
+
+\<comment> \<open> NOTE Show that the operators for a given solution @{text "\<pi>"} to the induced STRIPS problem
+for a given SAS+ problem correspond to operators of the SAS+ problem. \<close>
+lemma sas_plus_equivalent_to_strips_ii:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "STRIPS_Semantics.is_parallel_solution_for_problem (\<phi> \<Psi>) \<pi>"
+ shows "list_all (list_all (\<lambda>op. ListMem op (operators_of \<Psi>))) (\<phi>\<^sub>P\<inverse> \<Psi> \<pi>)"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?ops = "operators_of \<Psi>"
+ and ?\<psi> = "\<phi>\<^sub>P\<inverse> \<Psi> \<pi>"
+ have "is_valid_problem_strips ?\<Pi>"
+ using is_valid_problem_sas_plus_then_strips_transformation_too[OF assms(1)]
+ by simp
+ have nb\<^sub>1: "\<forall>op' \<in> set ((?\<Pi>)\<^sub>\<O>). (\<exists>op \<in> set ?ops. op' = (\<phi>\<^sub>O \<Psi> op))"
+ by auto
+ {
+ fix ops' op' op
+ assume "ops' \<in> set \<pi>" and "op' \<in> set ops'"
+ then have "op' \<in> set (strips_problem.operators_of ?\<Pi>)"
+ using is_parallel_solution_for_problem_operator_set[OF assms(2)]
+ by simp
+ then obtain op where "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)" and "op' = (\<phi>\<^sub>O \<Psi> op)"
+ by auto
+ then have "(\<phi>\<^sub>O\<inverse> \<Psi> op') \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using sas_plus_operator_inverse_is[OF assms(1)]
+ by presburger
+ }
+ thus ?thesis
+ unfolding list_all_iff ListMem_iff
+ strips_parallel_plan_to_sas_plus_parallel_plan_def
+ SAS_Plus_STRIPS.strips_parallel_plan_to_sas_plus_parallel_plan_def
+ SAS_Plus_STRIPS.strips_op_to_sasp_def
+ strips_op_to_sasp_def
+ by auto
+qed
+
+text \<open> We now show that for a parallel solution \<^term>\<open>\<pi>\<close> of \<^term>\<open>\<Pi>\<close> the SAS+ plan
+\<^term>\<open>\<psi> \<equiv> \<phi>\<^sub>P\<inverse> \<Psi> \<pi>\<close> yielded by the STRIPS to SAS+ plan transformation is a solution for
+\<^term>\<open>\<Psi>\<close>. The proof uses the definition of parallel STRIPS solutions and shows that the
+execution of \<^term>\<open>\<psi>\<close> on the initial state of the SAS+ problem yields a state satisfying the
+problem's goal state, i.e.
+ @{text[display, indent=4]"G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus I \<psi>"}
+and by showing that all operators in all parallel operators of \<^term>\<open>\<psi>\<close> are operators of the
+problem. \<close>
+
+theorem
+ sas_plus_equivalent_to_strips:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "STRIPS_Semantics.is_parallel_solution_for_problem (\<phi> \<Psi>) \<pi>"
+ shows "is_parallel_solution_for_problem \<Psi> (\<phi>\<^sub>P\<inverse> \<Psi> \<pi>)"
+proof -
+ let ?I = "initial_of \<Psi>"
+ and ?G = "goal_of \<Psi>"
+ and ?ops = "operators_of \<Psi>"
+ and ?\<psi> = "\<phi>\<^sub>P\<inverse> \<Psi> \<pi>"
+ show ?thesis
+ unfolding is_parallel_solution_for_problem_def Let_def
+ proof (rule conjI)
+ show "?G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus ?I ?\<psi>"
+ using sas_plus_equivalent_to_strips_i[OF assms].
+ next
+ show "list_all (list_all (\<lambda>op. ListMem op ?ops)) ?\<psi>"
+ using sas_plus_equivalent_to_strips_ii[OF assms].
+ qed
+qed
+
+private lemma strips_equivalent_to_sas_plus_i_a_I:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "\<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ and "op' \<in> set [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]"
+ obtains op where "op \<in> set ops"
+ and "op' = \<phi>\<^sub>O \<Psi> op"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?ops = "operators_of \<Psi>"
+ obtain op where "op \<in> set ops" and "op' = \<phi>\<^sub>O \<Psi> op"
+ using assms(3)
+ by auto
+ thus ?thesis
+ using that
+ by blast
+qed
+
+private corollary strips_equivalent_to_sas_plus_i_a_II:
+ assumes"is_valid_problem_sas_plus \<Psi>"
+ and "\<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ and "op' \<in> set [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]"
+ shows "op' \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and "is_valid_operator_strips (\<phi> \<Psi>) op'"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?ops = "operators_of \<Psi>"
+ and ?ops' = "strips_problem.operators_of ?\<Pi>"
+ obtain op where op_in: "op \<in> set ops" and op'_is: "op' = \<phi>\<^sub>O \<Psi> op"
+ using strips_equivalent_to_sas_plus_i_a_I[OF assms].
+ then have nb: "op' \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ using assms(2) op_in op'_is
+ by fastforce
+ thus "op' \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and "is_valid_operator_strips ?\<Pi> op'"
+ proof -
+ have "\<forall>op' \<in> set ?ops'. is_valid_operator_strips ?\<Pi> op'"
+ using is_valid_problem_sas_plus_then_strips_transformation_too_iii[OF assms(1)]
+ unfolding list_all_iff.
+ thus "is_valid_operator_strips ?\<Pi> op'"
+ using nb
+ by fastforce
+ qed fastforce
+qed
+
+(* TODO make private *)
+lemma strips_equivalent_to_sas_plus_i_a_III:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "\<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ shows "execute_parallel_operator (\<phi>\<^sub>S \<Psi> s) [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]
+ = (\<phi>\<^sub>S \<Psi> (execute_parallel_operator_sas_plus s ops))"
+proof -
+ {
+ fix op s
+ assume "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ moreover have "(\<phi>\<^sub>O \<Psi> op) \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ using calculation
+ by simp
+ moreover have "(\<phi>\<^sub>S \<Psi> s) ++ map_of (effect_to_assignments (\<phi>\<^sub>O \<Psi> op))
+ = (\<phi>\<^sub>S \<Psi> (s ++ map_of (effect_of (\<phi>\<^sub>O\<inverse> \<Psi> (\<phi>\<^sub>O \<Psi> op)))))"
+ using sas_plus_equivalent_to_strips_i_a_XI[OF assms(1) calculation(2)]
+ by blast
+ moreover have "(\<phi>\<^sub>O\<inverse> \<Psi> (\<phi>\<^sub>O \<Psi> op)) = op"
+ using sas_plus_operator_inverse_is[OF assms(1) calculation(1)].
+ ultimately have "(\<phi>\<^sub>S \<Psi> s) \<then> (\<phi>\<^sub>O \<Psi> op)
+ = (\<phi>\<^sub>S \<Psi> (s \<then>\<^sub>+ op))"
+ unfolding execute_operator_def execute_operator_sas_plus_def
+ by simp
+ } note nb\<^sub>1 = this
+ show ?thesis
+ using assms
+ proof (induction ops arbitrary: s)
+ case Nil
+ then show ?case
+ unfolding execute_parallel_operator_def execute_parallel_operator_sas_plus_def
+ by simp
+ next
+ case (Cons op ops)
+ let ?t = "s \<then>\<^sub>+ op"
+ let ?s' = "\<phi>\<^sub>S \<Psi> s"
+ and ?ops' = "[\<phi>\<^sub>O \<Psi> op. op \<leftarrow> op # ops]"
+ let ?t' = "?s' \<then> (\<phi>\<^sub>O \<Psi> op)"
+ have "execute_parallel_operator ?s' ?ops'
+ = execute_parallel_operator ?t' [\<phi>\<^sub>O \<Psi> x. x \<leftarrow> ops]"
+ unfolding execute_operator_def
+ by simp
+ moreover have "(\<phi>\<^sub>S \<Psi> (execute_parallel_operator_sas_plus s (op # ops)))
+ = (\<phi>\<^sub>S \<Psi> (execute_parallel_operator_sas_plus ?t ops))"
+ unfolding execute_operator_sas_plus_def
+ by simp
+ moreover {
+ have "?t' = (\<phi>\<^sub>S \<Psi> ?t)"
+ using nb\<^sub>1 Cons.prems(2)
+ by simp
+ hence "execute_parallel_operator ?t'[\<phi>\<^sub>O \<Psi> x. x \<leftarrow> ops]
+ = (\<phi>\<^sub>S \<Psi> (execute_parallel_operator_sas_plus ?t ops))"
+ using Cons.IH[of ?t] Cons.prems
+ by simp
+ }
+ ultimately show ?case
+ by argo
+ qed
+qed
+
+private lemma strips_equivalent_to_sas_plus_i_a_IV:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "\<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ and "are_all_operators_applicable_in I ops
+ \<and> are_all_operator_effects_consistent ops"
+ shows "STRIPS_Semantics.are_all_operators_applicable (\<phi>\<^sub>S \<Psi> I) [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]
+ \<and> STRIPS_Semantics.are_all_operator_effects_consistent [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?ops = "operators_of \<Psi>"
+ let ?I' = "\<phi>\<^sub>S \<Psi> I"
+ and ?ops' = "[\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]"
+ have nb\<^sub>1: "\<forall>op \<in> set ops. is_operator_applicable_in I op"
+ using assms(3)
+ unfolding are_all_operators_applicable_in_def list_all_iff
+ by blast
+ have nb\<^sub>2: "\<forall>op \<in> set ops. is_valid_operator_sas_plus \<Psi> op"
+ using is_valid_problem_sas_plus_then(2) assms(1, 2)
+ unfolding is_valid_operator_sas_plus_def
+ by auto
+ have nb\<^sub>3: "\<forall>op \<in> set ops. map_of (precondition_of op) \<subseteq>\<^sub>m I"
+ using nb\<^sub>1
+ unfolding is_operator_applicable_in_def list_all_iff
+ by blast
+ {
+ fix op\<^sub>1 op\<^sub>2
+ assume "op\<^sub>1 \<in> set ops" and "op\<^sub>2 \<in> set ops"
+ hence "are_operator_effects_consistent op\<^sub>1 op\<^sub>2"
+ using assms(3)
+ unfolding are_all_operator_effects_consistent_def list_all_iff
+ by blast
+ } note nb\<^sub>4 = this
+ {
+ fix op\<^sub>1 op\<^sub>2
+ assume "op\<^sub>1 \<in> set ops" and "op\<^sub>2 \<in> set ops"
+ hence "\<forall>(v, a) \<in> set (effect_of op\<^sub>1). \<forall>(v', a') \<in> set (effect_of op\<^sub>2).
+ v \<noteq> v' \<or> a = a'"
+ using nb\<^sub>4
+ unfolding are_operator_effects_consistent_def Let_def list_all_iff
+ by presburger
+ } note nb\<^sub>5 = this
+ {
+ fix op\<^sub>1' op\<^sub>2' I
+ assume "op\<^sub>1' \<in> set ?ops'"
+ and "op\<^sub>2' \<in> set ?ops'"
+ and "\<exists>(v, a) \<in> set (add_effects_of op\<^sub>1'). \<exists>(v', a') \<in> set (delete_effects_of op\<^sub>2').
+ (v, a) = (v', a')"
+ moreover obtain op\<^sub>1 op\<^sub>2
+ where "op\<^sub>1 \<in> set ops"
+ and "op\<^sub>1' = \<phi>\<^sub>O \<Psi> op\<^sub>1"
+ and "op\<^sub>2 \<in> set ops"
+ and "op\<^sub>2' = \<phi>\<^sub>O \<Psi> op\<^sub>2"
+ using strips_equivalent_to_sas_plus_i_a_I[OF assms(1, 2)] calculation(1, 2)
+ by auto
+ moreover have "is_valid_operator_sas_plus \<Psi> op\<^sub>1"
+ and is_valid_operator_op\<^sub>2: "is_valid_operator_sas_plus \<Psi> op\<^sub>2"
+ using calculation(4, 6) nb\<^sub>2
+ by blast+
+ moreover obtain v v' a a'
+ where "(v, a) \<in> set (add_effects_of op\<^sub>1')"
+ and "(v', a') \<in> set (delete_effects_of op\<^sub>2')"
+ and "(v, a) = (v', a')"
+ using calculation
+ by blast
+ moreover have "(v, a) \<in> set (effect_of op\<^sub>1)"
+ using calculation(5, 10)
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def Let_def
+ by fastforce
+ moreover have "v = v'" and "a = a'"
+ using calculation(12)
+ by simp+
+ moreover {
+ have "(v', a') \<in> (\<Union>(v, a) \<in> set (effect_of op\<^sub>2).
+ { (v, a') | a'. a' \<in> (\<R>\<^sub>+ \<Psi> v) \<and> a' \<noteq> a })"
+ using sasp_op_to_strips_set_delete_effects_is
+ calculation(7, 9, 11)
+ by blast
+ then obtain v'' a'' where "(v'', a'') \<in> set (effect_of op\<^sub>2)"
+ and "(v', a') \<in> { (v'', a''') | a'''. a''' \<in> (\<R>\<^sub>+ \<Psi> v'') \<and> a''' \<noteq> a'' }"
+ by blast
+ moreover have "(v', a'') \<in> set (effect_of op\<^sub>2)"
+ using calculation
+ by blast
+ moreover have "a' \<in> \<R>\<^sub>+ \<Psi> v''" and "a' \<noteq> a''"
+ using calculation(1, 2)
+ by fast+
+ ultimately have "\<exists>a''. (v', a'') \<in> set (effect_of op\<^sub>2) \<and> a' \<in> (\<R>\<^sub>+ \<Psi> v')
+ \<and> a' \<noteq> a''"
+ by blast
+ }
+ moreover obtain a'' where "a' \<in> \<R>\<^sub>+ \<Psi> v'"
+ and "(v', a'') \<in> set (effect_of op\<^sub>2)"
+ and "a' \<noteq> a''"
+ using calculation(16)
+ by blast
+ moreover have "\<exists>(v, a) \<in> set (effect_of op\<^sub>1). (\<exists>(v', a') \<in> set (effect_of op\<^sub>2).
+ v = v' \<and> a \<noteq> a')"
+ using calculation(13, 14, 15, 17, 18, 19)
+ by blast
+ \<comment> \<open> TODO slow. \<close>
+ ultimately have "\<exists>op\<^sub>1 \<in> set ops. \<exists>op\<^sub>2 \<in> set ops. \<not>are_operator_effects_consistent op\<^sub>1 op\<^sub>2"
+ unfolding are_operator_effects_consistent_def list_all_iff
+ by fastforce
+ } note nb\<^sub>6 = this
+ show ?thesis
+ proof (rule conjI)
+ {
+ fix op'
+ assume "op' \<in> set ?ops'"
+ moreover obtain op where op_in: "op \<in> set ops"
+ and op'_is: "op' = \<phi>\<^sub>O \<Psi> op"
+ and op'_in: "op' \<in> set ((\<phi> \<Psi>)\<^sub>\<O>)"
+ and is_valid_op': "is_valid_operator_strips (\<phi> \<Psi>) op'"
+ using strips_equivalent_to_sas_plus_i_a_I[OF assms(1, 2)]
+ strips_equivalent_to_sas_plus_i_a_II[OF assms(1, 2)] calculation
+ by metis
+ moreover have is_valid_op: "is_valid_operator_sas_plus \<Psi> op"
+ using nb\<^sub>2 calculation(2)..
+ {
+ fix v a
+ assume v_a_in_preconditions': "(v, a) \<in> set (strips_operator.precondition_of op')"
+ have v_a_in_preconditions: "(v, a) \<in> set (precondition_of op)"
+ using op'_is
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def Let_def
+ using v_a_in_preconditions'
+ by force
+ moreover have "v \<in> set ?vs" and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_operator_sas_plus_then(1,2) is_valid_op calculation(1)
+ by fastforce+
+ moreover {
+ have "\<forall>(v, a) \<in> set (precondition_of op). \<forall>(v', a') \<in> set (precondition_of op).
+ v \<noteq> v' \<or> a = a'"
+ using is_valid_operator_sas_plus_then(5) is_valid_op
+ by fast
+ hence "map_of (precondition_of op) v = Some a"
+ using map_of_constant_assignments_defined_if[OF _ v_a_in_preconditions]
+ by blast
+ }
+ moreover have "v \<in> dom (map_of (precondition_of op))"
+ using calculation(4)
+ by blast
+ moreover have "I v = Some a"
+ using nb\<^sub>3
+ unfolding map_le_def
+ using op_in calculation(4, 5)
+ by metis
+ moreover have "(v, a) \<in> dom ?I'"
+ using state_to_strips_state_dom_element_iff[OF assms(1)]
+ calculation(2, 3, 6)
+ by simp
+ ultimately have "?I' (v, a) = Some True"
+ using state_to_strips_state_range_is[OF assms(1)]
+ by simp
+ }
+ hence "STRIPS_Representation.is_operator_applicable_in ?I' op'"
+ unfolding
+ STRIPS_Representation.is_operator_applicable_in_def
+ Let_def list_all_iff
+ by fast
+ }
+ thus "are_all_operators_applicable ?I' ?ops'"
+ unfolding are_all_operators_applicable_def list_all_iff
+ by blast
+ next
+ {
+ fix op\<^sub>1' op\<^sub>2'
+ assume op\<^sub>1'_in_ops': "op\<^sub>1' \<in> set ?ops'" and op\<^sub>2'_in_ops': "op\<^sub>2' \<in> set ?ops'"
+ have "STRIPS_Semantics.are_operator_effects_consistent op\<^sub>1' op\<^sub>2'"
+ unfolding STRIPS_Semantics.are_operator_effects_consistent_def Let_def
+ \<comment> \<open> TODO proof is symmetrical... refactor into nb. \<close>
+ proof (rule conjI)
+ show "\<not>list_ex (\<lambda>x. list_ex ((=) x) (delete_effects_of op\<^sub>2'))
+ (add_effects_of op\<^sub>1')"
+ proof (rule ccontr)
+ assume "\<not>\<not>list_ex (\<lambda>v. list_ex ((=) v) (delete_effects_of op\<^sub>2'))
+ (add_effects_of op\<^sub>1')"
+ then have "\<exists>(v, a) \<in> set (delete_effects_of op\<^sub>2').
+ \<exists>(v', a') \<in> set (add_effects_of op\<^sub>1'). (v, a) = (v', a')"
+ unfolding list_ex_iff
+ by fastforce
+ then obtain op\<^sub>1 op\<^sub>2 where "op\<^sub>1 \<in> set ops"
+ and "op\<^sub>2 \<in> set ops"
+ and "\<not>are_operator_effects_consistent op\<^sub>1 op\<^sub>2"
+ using nb\<^sub>6[OF op\<^sub>1'_in_ops' op\<^sub>2'_in_ops']
+ by blast
+ thus False
+ using nb\<^sub>4
+ by blast
+ qed
+ next
+ show "\<not>list_ex (\<lambda>v. list_ex ((=) v) (add_effects_of op\<^sub>2')) (delete_effects_of op\<^sub>1')"
+ proof (rule ccontr)
+ assume "\<not>\<not>list_ex (\<lambda>v. list_ex ((=) v) (add_effects_of op\<^sub>2'))
+ (delete_effects_of op\<^sub>1')"
+ then have "\<exists>(v, a) \<in> set (delete_effects_of op\<^sub>1').
+ \<exists>(v', a') \<in> set (add_effects_of op\<^sub>2'). (v, a) = (v', a')"
+ unfolding list_ex_iff
+ by fastforce
+ then obtain op\<^sub>1 op\<^sub>2 where "op\<^sub>1 \<in> set ops"
+ and "op\<^sub>2 \<in> set ops"
+ and "\<not>are_operator_effects_consistent op\<^sub>1 op\<^sub>2"
+ using nb\<^sub>6[OF op\<^sub>2'_in_ops' op\<^sub>1'_in_ops']
+ by blast
+ thus False
+ using nb\<^sub>4
+ by blast
+ qed
+ qed
+ }
+ thus "STRIPS_Semantics.are_all_operator_effects_consistent ?ops'"
+ unfolding STRIPS_Semantics.are_all_operator_effects_consistent_def list_all_iff
+ by blast
+ qed
+qed
+
+private lemma strips_equivalent_to_sas_plus_i_a_V:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "\<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ and "\<not>(are_all_operators_applicable_in s ops
+ \<and> are_all_operator_effects_consistent ops)"
+ shows "\<not>(STRIPS_Semantics.are_all_operators_applicable (\<phi>\<^sub>S \<Psi> s) [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]
+ \<and> STRIPS_Semantics.are_all_operator_effects_consistent [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops])"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?ops = "operators_of \<Psi>"
+ let ?s' = "\<phi>\<^sub>S \<Psi> s"
+ and ?ops' = "[\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]"
+ {
+ fix op
+ assume "op \<in> set ops"
+ hence "\<exists>op' \<in> set ?ops'. op' = \<phi>\<^sub>O \<Psi> op"
+ by simp
+ } note nb\<^sub>1 = this
+ {
+ fix op
+ assume "op \<in> set ops"
+ then have "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using assms(2)
+ by blast
+ then have "is_valid_operator_sas_plus \<Psi> op"
+ using is_valid_problem_sas_plus_then(2) assms(1)
+ unfolding is_valid_operator_sas_plus_def
+ by auto
+ hence "\<forall>(v, a) \<in> set (precondition_of op). \<forall>(v', a') \<in> set (precondition_of op).
+ v \<noteq> v' \<or> a = a'"
+ using is_valid_operator_sas_plus_then(5)
+ unfolding is_valid_operator_sas_plus_def
+ by fast
+ } note nb\<^sub>2 = this
+ {
+ consider (A) "\<not>are_all_operators_applicable_in s ops"
+ | (B) "\<not>are_all_operator_effects_consistent ops"
+ using assms(3)
+ by blast
+ hence "\<not>STRIPS_Semantics.are_all_operators_applicable ?s' ?ops'
+ \<or> \<not>STRIPS_Semantics.are_all_operator_effects_consistent ?ops'"
+ proof (cases)
+ case A
+ then obtain op where op_in: "op \<in> set ops"
+ and not_precondition_map_le_s: "\<not>(map_of (precondition_of op) \<subseteq>\<^sub>m s)"
+ using A
+ unfolding are_all_operators_applicable_in_def list_all_iff
+ is_operator_applicable_in_def
+ by blast
+ then obtain op' where op'_in: "op' \<in> set ?ops'" and op'_is: "op' = \<phi>\<^sub>O \<Psi> op"
+ using nb\<^sub>1
+ by blast
+ have "\<not>are_all_operators_applicable ?s' ?ops'"
+ proof (rule ccontr)
+ assume "\<not>\<not>are_all_operators_applicable ?s' ?ops'"
+ then have all_operators_applicable: "are_all_operators_applicable ?s' ?ops'"
+ by simp
+ moreover {
+ fix v
+ assume "v \<in> dom (map_of (precondition_of op))"
+ moreover obtain a where "map_of (precondition_of op) v = Some a"
+ using calculation
+ by blast
+ moreover have "(v, a) \<in> set (precondition_of op)"
+ using map_of_SomeD[OF calculation(2)].
+ moreover have "(v, a) \<in> set (strips_operator.precondition_of op')"
+ using op'_is
+ unfolding sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ using calculation(3)
+ by auto
+ moreover have "?s' (v, a) = Some True"
+ using all_operators_applicable calculation
+ unfolding are_all_operators_applicable_def
+ STRIPS_Representation.is_operator_applicable_in_def
+ is_operator_applicable_in_def Let_def list_all_iff
+ using op'_in
+ by fast
+ moreover have "(v, a) \<in> dom ?s'"
+ using calculation(5)
+ by blast
+ moreover have "(v, a) \<in> set (precondition_of op)"
+ using op'_is calculation(3)
+ unfolding sasp_op_to_strips_def Let_def
+ by fastforce
+ moreover have "v \<in> set ?vs"
+ and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ and "s v \<noteq> None"
+ using state_to_strips_state_dom_element_iff[OF assms(1)]
+ calculation(6)
+ by simp+
+ moreover have "?s' (v, a) = Some (the (s v) = a)"
+ using state_to_strips_state_range_is[OF
+ assms(1) calculation(6)].
+ moreover have "the (s v) = a"
+ using calculation(5, 11)
+ by fastforce
+ moreover have "s v = Some a"
+ using calculation(12) option.collapse[OF calculation(10)]
+ by argo
+ moreover have "map_of (precondition_of op) v = Some a"
+ using map_of_constant_assignments_defined_if[OF nb\<^sub>2[OF op_in] calculation(7)].
+ ultimately have "map_of (precondition_of op) v = s v"
+ by argo
+ }
+ then have "map_of (precondition_of op) \<subseteq>\<^sub>m s"
+ unfolding map_le_def
+ by blast
+ thus False
+ using not_precondition_map_le_s
+ by simp
+ qed
+ thus ?thesis
+ by simp
+ next
+ case B
+ {
+ obtain op\<^sub>1 op\<^sub>2 v v' a a'
+ where "op\<^sub>1 \<in> set ops"
+ and op\<^sub>2_in: "op\<^sub>2 \<in> set ops"
+ and v_a_in: "(v, a) \<in> set (effect_of op\<^sub>1)"
+ and v'_a'_in: "(v', a') \<in> set (effect_of op\<^sub>2)"
+ and v_is: "v = v'" and a_is: "a \<noteq> a'"
+ using B
+ unfolding are_all_operator_effects_consistent_def
+ are_operator_effects_consistent_def list_all_iff Let_def
+ by blast
+ moreover obtain op\<^sub>1' op\<^sub>2' where "op\<^sub>1' \<in> set ?ops'" and "op\<^sub>1' = \<phi>\<^sub>O \<Psi> op\<^sub>1"
+ and "op\<^sub>1' \<in> set ?ops'" and op\<^sub>2'_is: "op\<^sub>2' = \<phi>\<^sub>O \<Psi> op\<^sub>2"
+ using nb\<^sub>1[OF calculation(1)] nb\<^sub>1[OF calculation(2)]
+ by blast
+ moreover have "(v, a) \<in> set (add_effects_of op\<^sub>1')"
+ using calculation(3, 8)
+ unfolding SAS_Plus_STRIPS.sasp_op_to_strips_def
+ sasp_op_to_strips_def Let_def
+ by force
+ moreover {
+ have "is_valid_operator_sas_plus \<Psi> op\<^sub>1"
+ using assms(2) calculation(1) is_valid_problem_sas_plus_then(2) assms(1)
+ unfolding is_valid_operator_sas_plus_def
+ by auto
+ moreover have "is_valid_operator_sas_plus \<Psi> op\<^sub>2"
+ using sublocale_sas_plus_finite_domain_representation_ii(2)[
+ OF assms(1)] assms(2) op\<^sub>2_in
+ by blast
+ moreover have "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_operator_sas_plus_then(4) calculation v_a_in
+ unfolding is_valid_operator_sas_plus_def
+ by fastforce
+ ultimately have "(v, a) \<in> set (delete_effects_of op\<^sub>2')"
+ using sasp_op_to_strips_set_delete_effects_is[of \<Psi> op\<^sub>2]
+ v'_a'_in v_is a_is
+ using op\<^sub>2'_is
+ by blast
+ }
+ \<comment> \<open> TODO slow. \<close>
+ ultimately have "\<exists>op\<^sub>1' \<in> set ?ops'. \<exists>op\<^sub>2' \<in> set ?ops'.
+ \<exists>(v, a) \<in> set (delete_effects_of op\<^sub>2'). \<exists>(v', a') \<in> set (add_effects_of op\<^sub>1').
+ (v, a) = (v', a')"
+ by fastforce
+ }
+ then have "\<not>STRIPS_Semantics.are_all_operator_effects_consistent ?ops'"
+ unfolding STRIPS_Semantics.are_all_operator_effects_consistent_def
+ STRIPS_Semantics.are_operator_effects_consistent_def list_all_iff list_ex_iff Let_def
+ by blast
+ thus ?thesis
+ by simp
+ qed
+ }
+ thus ?thesis
+ by blast
+qed
+
+(* TODO make private *)
+lemma strips_equivalent_to_sas_plus_i_a:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "dom I \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom I. the (I v) \<in> \<R>\<^sub>+ \<Psi> v"
+ and "dom G \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom G. the (G v) \<in> \<R>\<^sub>+ \<Psi> v"
+ and "\<forall>ops \<in> set \<psi>. \<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ and "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus I \<psi>"
+ shows "(\<phi>\<^sub>S \<Psi> G) \<subseteq>\<^sub>m execute_parallel_plan (\<phi>\<^sub>S \<Psi> I) (\<phi>\<^sub>P \<Psi> \<psi>)"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ and ?G' = "\<phi>\<^sub>S \<Psi> G"
+ show ?thesis
+ using assms
+ proof (induction \<psi> arbitrary: I)
+ case Nil
+ let ?I' = "\<phi>\<^sub>S \<Psi> I"
+ have "G \<subseteq>\<^sub>m I"
+ using Nil
+ by simp
+ moreover have "?G' \<subseteq>\<^sub>m ?I'"
+ using state_to_strips_state_map_le_iff[OF Nil.prems(1, 4, 5)]
+ calculation..
+ ultimately show ?case
+ unfolding SAS_Plus_STRIPS.sas_plus_parallel_plan_to_strips_parallel_plan_def
+ sas_plus_parallel_plan_to_strips_parallel_plan_def
+ by simp
+ next
+ case (Cons ops \<psi>)
+ let ?vs = "variables_of \<Psi>"
+ and ?ops = "operators_of \<Psi>"
+ and ?J = "execute_parallel_operator_sas_plus I ops"
+ and ?\<pi> = "\<phi>\<^sub>P \<Psi> (ops # \<psi>)"
+ let ?I' = "\<phi>\<^sub>S \<Psi> I"
+ and ?J' = "\<phi>\<^sub>S \<Psi> ?J"
+ and ?ops' = "[\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]"
+ {
+ fix op v a
+ assume "op \<in> set ops" and "(v, a) \<in> set (effect_of op)"
+ moreover have "op \<in> set ?ops"
+ using Cons.prems(6) calculation(1)
+ by simp
+ moreover have "is_valid_operator_sas_plus \<Psi> op"
+ using is_valid_problem_sas_plus_then(2) Cons.prems(1) calculation(3)
+ unfolding is_valid_operator_sas_plus_def
+ by auto
+ ultimately have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_operator_sas_plus_then(3,4)
+ by fastforce+
+ } note nb\<^sub>1 = this
+ show ?case
+ proof (cases "are_all_operators_applicable_in I ops
+ \<and> are_all_operator_effects_consistent ops")
+ case True
+ {
+ have "(\<phi>\<^sub>P \<Psi> (ops # \<psi>)) = ?ops' # (\<phi>\<^sub>P \<Psi> \<psi>)"
+ unfolding sas_plus_parallel_plan_to_strips_parallel_plan_def
+ SAS_Plus_STRIPS.sas_plus_parallel_plan_to_strips_parallel_plan_def
+ sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ by simp
+ moreover have "\<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using Cons.prems(6)
+ by simp
+ moreover have "STRIPS_Semantics.are_all_operators_applicable ?I' ?ops'"
+ and "STRIPS_Semantics.are_all_operator_effects_consistent ?ops'"
+ using strips_equivalent_to_sas_plus_i_a_IV[OF Cons.prems(1) _ True] calculation
+ by blast+
+ ultimately have "execute_parallel_plan ?I' ?\<pi>
+ = execute_parallel_plan (execute_parallel_operator ?I' ?ops') (\<phi>\<^sub>P \<Psi> \<psi>)"
+ by fastforce
+ }
+ \<comment> \<open> NOTE Instantiate the IH on the next state of the SAS+ execution
+ \<open>execute_parallel_operator_sas_plus I ops\<close>. \<close>
+ moreover
+ {
+ {
+ have "dom I \<subseteq> set (sas_plus_problem.variables_of \<Psi>)"
+ using Cons.prems(2)
+ by blast
+ moreover have "\<forall>op \<in> set ops. \<forall>(v, a) \<in> set (effect_of op).
+ v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using nb\<^sub>1(1)
+ by blast
+ ultimately have "dom ?J \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using sas_plus_equivalent_to_strips_i_a_IX[of I "set ?vs"]
+ by simp
+ } note nb\<^sub>2 = this
+ moreover {
+ have "dom I \<subseteq> set (sas_plus_problem.variables_of \<Psi>)"
+ using Cons.prems(2)
+ by blast
+ moreover have "set (sas_plus_problem.variables_of \<Psi>)
+ \<subseteq> dom (range_of \<Psi>)"
+ using is_valid_problem_sas_plus_dom_sas_plus_problem_range_of assms(1)
+ by auto
+ moreover {
+ fix v
+ assume "v \<in> dom I"
+ moreover have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using Cons.prems(2) calculation
+ by blast
+ ultimately have "the (I v) \<in> set (the (range_of \<Psi> v))"
+ using Cons.prems(3)
+ using set_the_range_of_is_range_of_sas_plus_if[OF assms(1)]
+ by blast
+ }
+ moreover have "\<forall>op\<in>set ops. \<forall>(v, a)\<in>set (effect_of op).
+ v \<in> set (sas_plus_problem.variables_of \<Psi>) \<and> a \<in> set (the (range_of \<Psi> v))"
+ using set_the_range_of_is_range_of_sas_plus_if[OF assms(1)] nb\<^sub>1(1) nb\<^sub>1(2)
+ by force
+ moreover have nb\<^sub>3: "\<forall>v \<in> dom ?J. the (?J v) \<in> set (the (range_of \<Psi> v))"
+ using sas_plus_equivalent_to_strips_i_a_X[of I "set ?vs" "range_of \<Psi>" ops]
+ calculation
+ by fast
+ moreover {
+ fix v
+ assume "v \<in> dom ?J"
+ moreover have "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using nb\<^sub>2 calculation
+ by blast
+ moreover have "set (the (range_of \<Psi> v)) = \<R>\<^sub>+ \<Psi> v"
+ using set_the_range_of_is_range_of_sas_plus_if[OF assms(1)]
+ calculation(2)
+ by presburger
+ ultimately have "the (?J v) \<in> \<R>\<^sub>+ \<Psi> v"
+ using nb\<^sub>3
+ by blast
+ }
+ ultimately have "\<forall>v \<in> dom ?J. the (?J v) \<in> \<R>\<^sub>+ \<Psi> v"
+ by fast
+ }
+ moreover have "\<forall>ops\<in>set \<psi>. \<forall>op\<in>set ops. op \<in> set ?ops"
+ using Cons.prems(6)
+ by auto
+ moreover have "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus ?J \<psi>"
+ using Cons.prems(7) True
+ by simp
+ ultimately have "(\<phi>\<^sub>S \<Psi> G) \<subseteq>\<^sub>m execute_parallel_plan ?J' (\<phi>\<^sub>P \<Psi> \<psi>)"
+ using Cons.IH[of ?J, OF Cons.prems(1) _ _ Cons.prems(4, 5)]
+ by fastforce
+ }
+ moreover have "execute_parallel_operator ?I' ?ops' = ?J'"
+ using assms(1) strips_equivalent_to_sas_plus_i_a_III[OF assms(1)] Cons.prems(6)
+ by auto
+ ultimately show ?thesis
+ by argo
+ next
+ case False
+ then have nb: "G \<subseteq>\<^sub>m I"
+ using Cons.prems(7)
+ by force
+ moreover {
+ have "?\<pi> = ?ops' # (\<phi>\<^sub>P \<Psi> \<psi>)"
+ unfolding sas_plus_parallel_plan_to_strips_parallel_plan_def
+ SAS_Plus_STRIPS.sas_plus_parallel_plan_to_strips_parallel_plan_def
+ sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def Let_def
+ by auto
+ moreover have "set ?ops' \<subseteq> set (strips_problem.operators_of ?\<Pi>)"
+ using strips_equivalent_to_sas_plus_i_a_II(1)[OF assms(1)] Cons.prems(6)
+ by auto
+ moreover have "\<not>(STRIPS_Semantics.are_all_operators_applicable ?I' ?ops'
+ \<and> STRIPS_Semantics.are_all_operator_effects_consistent ?ops')"
+ using strips_equivalent_to_sas_plus_i_a_V[OF assms(1) _ False] Cons.prems(6)
+ by force
+ ultimately have "execute_parallel_plan ?I' ?\<pi> = ?I'"
+ by auto
+ }
+ moreover have "?G' \<subseteq>\<^sub>m ?I'"
+ using state_to_strips_state_map_le_iff[OF Cons.prems(1, 4, 5)] nb
+ by blast
+ ultimately show ?thesis
+ by presburger
+ qed
+ qed
+qed
+
+(* TODO make private *)
+lemma strips_equivalent_to_sas_plus_i:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "is_parallel_solution_for_problem \<Psi> \<psi>"
+ shows "(strips_problem.goal_of (\<phi> \<Psi>)) \<subseteq>\<^sub>m execute_parallel_plan
+ (strips_problem.initial_of (\<phi> \<Psi>)) (\<phi>\<^sub>P \<Psi> \<psi>)"
+proof -
+ let ?vs = "variables_of \<Psi>"
+ and ?ops = "operators_of \<Psi>"
+ and ?I = "initial_of \<Psi>"
+ and ?G = "goal_of \<Psi>"
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?I' = "strips_problem.initial_of ?\<Pi>"
+ and ?G' = "strips_problem.goal_of ?\<Pi>"
+ have "dom ?I \<subseteq> set ?vs"
+ using is_valid_problem_sas_plus_then(3) assms(1)
+ by auto
+ moreover have "\<forall>v\<in>dom ?I. the (?I v) \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_problem_sas_plus_then(4) assms(1) calculation
+ by auto
+ moreover have "dom ?G \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using is_valid_problem_sas_plus_then(5) assms(1)
+ by auto
+ moreover have "\<forall>v \<in> dom ?G. the (?G v) \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_problem_sas_plus_then(6) assms(1)
+ by auto
+ moreover have "\<forall>ops \<in> set \<psi>. \<forall>op \<in> set ops. op \<in> set ?ops"
+ using is_parallel_solution_for_problem_plan_operator_set[OF assms(2)]
+ by fastforce
+ moreover have "?G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus ?I \<psi>"
+ using assms(2)
+ unfolding is_parallel_solution_for_problem_def
+ by simp
+ (* TODO slow *)
+ ultimately show ?thesis
+ using strips_equivalent_to_sas_plus_i_a[OF assms(1), of ?I ?G \<psi>]
+ unfolding sas_plus_problem_to_strips_problem_def
+ SAS_Plus_STRIPS.sas_plus_problem_to_strips_problem_def
+ state_to_strips_state_def
+ SAS_Plus_STRIPS.state_to_strips_state_def
+ by force
+qed
+
+(* TODO make private *)
+lemma strips_equivalent_to_sas_plus_ii:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "is_parallel_solution_for_problem \<Psi> \<psi>"
+ shows "list_all (list_all (\<lambda>op. ListMem op (strips_problem.operators_of (\<phi> \<Psi>)))) (\<phi>\<^sub>P \<Psi> \<psi>)"
+proof -
+ let ?ops = "operators_of \<Psi>"
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?ops' = "strips_problem.operators_of ?\<Pi>"
+ and ?\<pi> = "\<phi>\<^sub>P \<Psi> \<psi>"
+ have "is_valid_problem_strips ?\<Pi>"
+ using is_valid_problem_sas_plus_then_strips_transformation_too[OF assms(1)]
+ by simp
+ have nb\<^sub>1: "\<forall>op \<in> set ?ops. (\<exists>op' \<in> set ?ops'. op' = (\<phi>\<^sub>O \<Psi> op))"
+ unfolding sas_plus_problem_to_strips_problem_def
+ SAS_Plus_STRIPS.sas_plus_problem_to_strips_problem_def Let_def
+ sasp_op_to_strips_def
+ by force
+ {
+ fix ops op op'
+ assume "ops \<in> set \<psi>" and "op \<in> set ops"
+ moreover have "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using is_parallel_solution_for_problem_plan_operator_set[OF assms(2)]
+ calculation
+ by blast
+ moreover obtain op' where "op' \<in> set ?ops'" and "op' = (\<phi>\<^sub>O \<Psi> op)"
+ using nb\<^sub>1 calculation(3)
+ by auto
+ ultimately have "(\<phi>\<^sub>O \<Psi> op) \<in> set ?ops'"
+ by blast
+ }
+ thus ?thesis
+ unfolding list_all_iff ListMem_iff Let_def
+ sas_plus_problem_to_strips_problem_def
+ SAS_Plus_STRIPS.sas_plus_problem_to_strips_problem_def
+ sas_plus_parallel_plan_to_strips_parallel_plan_def
+ SAS_Plus_STRIPS.sas_plus_parallel_plan_to_strips_parallel_plan_def
+ sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ Let_def
+ by auto
+qed
+
+text \<open> The following lemma proves the complementary proposition to theorem
+\ref{isathm:equivalence-parallel-strips-parallel-sas-plus}. Namely, given a parallel solution
+\<^term>\<open>\<psi>\<close> for a SAS+ problem, the transformation to a STRIPS plan \<^term>\<open>\<phi>\<^sub>P \<Psi> \<psi>\<close> also is a solution
+to the corresponding STRIPS problem \<^term>\<open>\<Pi> \<equiv> (\<phi> \<Psi>)\<close>. In this direction, we have to show that the
+execution of the transformed plan reaches the goal state \<^term>\<open>G' \<equiv> strips_problem.goal_of \<Pi>\<close>
+of the corresponding STRIPS problem, i.e.
+ @{text[display, indent=4] "G' \<subseteq>\<^sub>m execute_parallel_plan I' \<pi>"}
+and that all operators in the transformed plan \<^term>\<open>\<pi>\<close> are operators of \<^term>\<open>\<Pi>\<close>. \<close>
+
+theorem
+ strips_equivalent_to_sas_plus:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "is_parallel_solution_for_problem \<Psi> \<psi>"
+ shows "STRIPS_Semantics.is_parallel_solution_for_problem (\<phi> \<Psi>) (\<phi>\<^sub>P \<Psi> \<psi>)"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?I' = "strips_problem.initial_of ?\<Pi>"
+ and ?G' = "strips_problem.goal_of ?\<Pi>"
+ and ?ops' = "strips_problem.operators_of ?\<Pi>"
+ and ?\<pi> = "\<phi>\<^sub>P \<Psi> \<psi>"
+ show ?thesis
+ unfolding STRIPS_Semantics.is_parallel_solution_for_problem_def
+ proof (rule conjI)
+ show "?G' \<subseteq>\<^sub>m execute_parallel_plan ?I' ?\<pi>"
+ using strips_equivalent_to_sas_plus_i[OF assms]
+ by simp
+ next
+ show "list_all (list_all (\<lambda>op. ListMem op ?ops')) ?\<pi>"
+ using strips_equivalent_to_sas_plus_ii[OF assms].
+ qed
+qed
+
+lemma embedded_serial_sas_plus_plan_operator_structure:
+ assumes "ops \<in> set (embed \<psi>)"
+ obtains op
+ where "op \<in> set \<psi>"
+ and "[\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops] = [\<phi>\<^sub>O \<Psi> op]"
+proof -
+ let ?\<psi>' = "embed \<psi>"
+ {
+ have "?\<psi>' = [[op]. op \<leftarrow> \<psi>]"
+ by (induction \<psi>; force)
+ moreover obtain op where "ops = [op]" and "op \<in> set \<psi>"
+ using assms calculation
+ by fastforce
+ ultimately have "\<exists>op \<in> set \<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops] = [\<phi>\<^sub>O \<Psi> op]"
+ by auto
+ }
+ thus ?thesis
+ using that
+ by meson
+qed
+
+private lemma serial_sas_plus_equivalent_to_serial_strips_i:
+ assumes "ops \<in> set (\<phi>\<^sub>P \<Psi> (embed \<psi>))"
+ obtains op where "op \<in> set \<psi>" and "ops = [\<phi>\<^sub>O \<Psi> op]"
+proof -
+ let ?\<psi>' = "embed \<psi>"
+ {
+ have "set (\<phi>\<^sub>P \<Psi> (embed \<psi>)) = { [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops] | ops. ops \<in> set ?\<psi>' }"
+
+ unfolding sas_plus_parallel_plan_to_strips_parallel_plan_def
+ SAS_Plus_STRIPS.sas_plus_parallel_plan_to_strips_parallel_plan_def
+ sasp_op_to_strips_def set_map
+ using setcompr_eq_image
+ by blast
+ moreover obtain ops' where "ops' \<in> set ?\<psi>'" and "ops = [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops']"
+ using assms(1) calculation
+ by blast
+ moreover obtain op where "op \<in> set \<psi>" and "ops = [\<phi>\<^sub>O \<Psi> op]"
+ using embedded_serial_sas_plus_plan_operator_structure calculation(2, 3)
+ by blast
+ ultimately have "\<exists>op \<in> set \<psi>. ops = [\<phi>\<^sub>O \<Psi> op]"
+ by meson
+ }
+ thus ?thesis
+ using that..
+qed
+
+private lemma serial_sas_plus_equivalent_to_serial_strips_ii[simp]:
+ "concat (\<phi>\<^sub>P \<Psi> (embed \<psi>)) = [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]"
+proof -
+ let ?\<psi>' = "List_Supplement.embed \<psi>"
+ have "concat (\<phi>\<^sub>P \<Psi> ?\<psi>') = map (\<lambda>op. \<phi>\<^sub>O \<Psi> op) (concat ?\<psi>')"
+ unfolding sas_plus_parallel_plan_to_strips_parallel_plan_def
+ SAS_Plus_STRIPS.sas_plus_parallel_plan_to_strips_parallel_plan_def
+ sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def Let_def
+ map_concat
+ by blast
+ also have "\<dots> = map (\<lambda>op. \<phi>\<^sub>O \<Psi> op) \<psi>"
+ unfolding concat_is_inverse_of_embed[of \<psi>]..
+ finally show "concat (\<phi>\<^sub>P \<Psi> (embed \<psi>)) = [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]".
+qed
+
+text \<open> Having established the equivalence of parallel STRIPS and SAS+, we can now show the
+equivalence in the serial case. The proof combines the
+embedding theorem for serial SAS+ solutions (\ref{isathm:serial-sas-plus-embedding}), the parallel
+plan equivalence theorem \ref{isathm:equivalence-parallel-sas-plus-parallel-strips}, and the
+flattening theorem for parallel STRIPS plans (\ref{isathm:embedded-serial-plan-flattening-strips}).
+More precisely, given a serial SAS+ solution \<^term>\<open>\<psi>\<close> for a SAS+ problem \<^term>\<open>\<Psi>\<close>, the embedding
+theorem confirms that the embedded plan \<^term>\<open>embed \<psi>\<close> is an equivalent parallel solution to
+\<^term>\<open>\<Psi>\<close>. By parallel plan equivalence, \<^term>\<open>\<pi> \<equiv> \<phi>\<^sub>P \<Psi> (embed \<psi>)\<close> is a parallel solution for the
+corresponding STRIPS problem \<^term>\<open>\<phi> \<Psi>\<close>. Moreover, since \<^term>\<open>embed \<psi>\<close> is a plan consisting of
+singleton parallel operators, the same is true for \<^term>\<open>\<pi>\<close>. Hence, the flattening lemma applies
+and \<^term>\<open>concat \<pi>\<close> is a serial solution for \<^term>\<open>\<phi> \<Psi>\<close>. Since \<^term>\<open>concat\<close> moreover can be shown
+to be the inverse of \<^term>\<open>embed\<close>, the term
+ @{text[display, indent=4] "concat \<pi> = concat (\<phi>\<^sub>P \<Psi> (embed \<psi>))"}
+can be reduced to the intuitive form
+ @{text[display, indent=4] "\<pi> = [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]"}
+which concludes the proof. \<close>
+
+theorem
+ serial_sas_plus_equivalent_to_serial_strips:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "SAS_Plus_Semantics.is_serial_solution_for_problem \<Psi> \<psi>"
+ shows "STRIPS_Semantics.is_serial_solution_for_problem (\<phi> \<Psi>) [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]"
+proof -
+ let ?\<psi>' = "embed \<psi>"
+ and ?\<Pi> = "\<phi> \<Psi>"
+ let ?\<pi>' = "\<phi>\<^sub>P \<Psi> ?\<psi>'"
+ let ?\<pi> = "concat ?\<pi>'"
+ {
+ have "SAS_Plus_Semantics.is_parallel_solution_for_problem \<Psi> ?\<psi>'"
+ using execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus[OF assms]
+ by simp
+ hence "STRIPS_Semantics.is_parallel_solution_for_problem ?\<Pi> ?\<pi>'"
+ using strips_equivalent_to_sas_plus[OF assms(1)]
+ by simp
+ }
+ moreover have "?\<pi> = [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]"
+ by simp
+ moreover have "is_valid_problem_strips ?\<Pi>"
+ using is_valid_problem_sas_plus_then_strips_transformation_too[OF assms(1)].
+ moreover have "\<forall>ops \<in> set ?\<pi>'. \<exists>op \<in> set \<psi>. ops = [\<phi>\<^sub>O \<Psi> op]"
+ using serial_sas_plus_equivalent_to_serial_strips_i[of _ \<Psi> \<psi>]
+ by metis
+ ultimately show ?thesis
+ using STRIPS_Semantics.flattening_lemma[of ?\<Pi>]
+ by metis
+qed
+
+
+lemma embedded_serial_strips_plan_operator_structure:
+ assumes "ops' \<in> set (embed \<pi>)"
+ obtains op
+ where "op \<in> set \<pi>" and "[\<phi>\<^sub>O\<inverse> \<Pi> op. op \<leftarrow> ops'] = [\<phi>\<^sub>O\<inverse> \<Pi> op]"
+proof -
+ let ?\<pi>' = "embed \<pi>"
+ {
+ have "?\<pi>' = [[op]. op \<leftarrow> \<pi>]"
+ by (induction \<pi>; force)
+ moreover obtain op where "ops' = [op]" and "op \<in> set \<pi>"
+ using calculation assms
+ by fastforce
+ ultimately have "\<exists>op \<in> set \<pi>. [\<phi>\<^sub>O\<inverse> \<Pi> op. op \<leftarrow> ops'] = [\<phi>\<^sub>O\<inverse> \<Pi> op]"
+ by auto
+ }
+ thus ?thesis
+ using that
+ by meson
+qed
+
+private lemma serial_strips_equivalent_to_serial_sas_plus_i:
+ assumes "ops \<in> set (\<phi>\<^sub>P\<inverse> \<Pi> (embed \<pi>))"
+ obtains op where "op \<in> set \<pi>" and "ops = [\<phi>\<^sub>O\<inverse> \<Pi> op]"
+proof -
+ let ?\<pi>' = "embed \<pi>"
+ {
+ have "set (\<phi>\<^sub>P\<inverse> \<Pi> (embed \<pi>)) = { [\<phi>\<^sub>O\<inverse> \<Pi> op. op \<leftarrow> ops] | ops. ops \<in> set ?\<pi>' }"
+ unfolding strips_parallel_plan_to_sas_plus_parallel_plan_def
+ SAS_Plus_STRIPS.strips_parallel_plan_to_sas_plus_parallel_plan_def
+ strips_op_to_sasp_def set_map
+ using setcompr_eq_image
+ by blast
+ moreover obtain ops' where "ops' \<in> set ?\<pi>'" and "ops = [\<phi>\<^sub>O\<inverse> \<Pi> op. op \<leftarrow> ops']"
+ using assms(1) calculation
+ by blast
+ moreover obtain op where "op \<in> set \<pi>" and "ops = [\<phi>\<^sub>O\<inverse> \<Pi> op]"
+ using embedded_serial_strips_plan_operator_structure calculation(2, 3)
+ by blast
+ ultimately have "\<exists>op \<in> set \<pi>. ops = [\<phi>\<^sub>O\<inverse> \<Pi> op]"
+ by meson
+ }
+ thus ?thesis
+ using that..
+qed
+
+private lemma serial_strips_equivalent_to_serial_sas_plus_ii[simp]:
+ "concat (\<phi>\<^sub>P\<inverse> \<Pi> (embed \<pi>)) = [\<phi>\<^sub>O\<inverse> \<Pi> op. op \<leftarrow> \<pi>]"
+proof -
+ let ?\<pi>' = "List_Supplement.embed \<pi>"
+ have "concat (\<phi>\<^sub>P\<inverse> \<Pi> ?\<pi>') = map (\<lambda>op. \<phi>\<^sub>O\<inverse> \<Pi> op) (concat ?\<pi>')"
+ unfolding strips_parallel_plan_to_sas_plus_parallel_plan_def
+ SAS_Plus_STRIPS.strips_parallel_plan_to_sas_plus_parallel_plan_def
+ strips_op_to_sasp_def
+ SAS_Plus_STRIPS.strips_op_to_sasp_def Let_def
+ map_concat
+ by simp
+ also have "\<dots> = map (\<lambda>op. \<phi>\<^sub>O\<inverse> \<Pi> op) \<pi>"
+ unfolding concat_is_inverse_of_embed[of \<pi>]..
+ finally show "concat (\<phi>\<^sub>P\<inverse> \<Pi> (embed \<pi>)) = [\<phi>\<^sub>O\<inverse> \<Pi> op. op \<leftarrow> \<pi>]".
+qed
+
+text \<open> Using the analogous lemmas for the opposite direction, we can show the counterpart to
+theorem \ref{isathm:equivalence-serial-sas-plus-serial-strips} which shows that serial solutions
+to STRIPS solutions can be transformed to serial SAS+ solutions via composition of embedding,
+transformation and flattening. \<close>
+
+theorem
+ serial_strips_equivalent_to_serial_sas_plus:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "STRIPS_Semantics.is_serial_solution_for_problem (\<phi> \<Psi>) \<pi>"
+ shows "SAS_Plus_Semantics.is_serial_solution_for_problem \<Psi> [\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> \<pi>]"
+proof -
+ let ?\<pi>' = "embed \<pi>"
+ and ?\<Pi> = "\<phi> \<Psi>"
+ let ?\<psi>' = "\<phi>\<^sub>P\<inverse> \<Psi> ?\<pi>'"
+ let ?\<psi> = "concat ?\<psi>'"
+ {
+ have "STRIPS_Semantics.is_parallel_solution_for_problem ?\<Pi> ?\<pi>'"
+ using embedding_lemma[OF
+ is_valid_problem_sas_plus_then_strips_transformation_too[OF assms(1)] assms(2)].
+ hence "SAS_Plus_Semantics.is_parallel_solution_for_problem \<Psi> ?\<psi>'"
+ using sas_plus_equivalent_to_strips[OF assms(1)]
+ by simp
+ }
+ moreover have "?\<psi> = [\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> \<pi>]"
+ by simp
+ moreover have "is_valid_problem_strips ?\<Pi>"
+ using is_valid_problem_sas_plus_then_strips_transformation_too[OF assms(1)].
+ moreover have "\<forall>ops \<in> set ?\<psi>'. \<exists>op \<in> set \<pi>. ops = [\<phi>\<^sub>O\<inverse> \<Psi> op]"
+ using serial_strips_equivalent_to_serial_sas_plus_i
+ by metis
+ ultimately show ?thesis
+ using flattening_lemma[OF assms(1)]
+ by metis
+qed
+
+subsection "Equivalence of SAS+ and STRIPS"
+
+\<comment> \<open> Define the sets of plans with upper length bound as well as the sets of solutions with
+upper length bound for SAS problems and induced STRIPS problems.
+
+ We keep this polymorphic by not specifying concrete types so it applies to both STRIPS and
+SAS+ plans. \<close>
+abbreviation bounded_plan_set
+ where "bounded_plan_set ops k \<equiv> { \<pi>. set \<pi> \<subseteq> set ops \<and> length \<pi> = k }"
+
+definition bounded_solution_set_sas_plus'
+ :: "('variable, 'domain) sas_plus_problem
+ \<Rightarrow> nat
+ \<Rightarrow> ('variable, 'domain) sas_plus_plan set"
+ where "bounded_solution_set_sas_plus' \<Psi> k
+ \<equiv> { \<psi>. is_serial_solution_for_problem \<Psi> \<psi> \<and> length \<psi> = k}"
+
+abbreviation bounded_solution_set_sas_plus
+ :: "('variable, 'domain) sas_plus_problem
+ \<Rightarrow> nat
+ \<Rightarrow> ('variable, 'domain) sas_plus_plan set"
+ where "bounded_solution_set_sas_plus \<Psi> N
+ \<equiv> (\<Union>k \<in> {0..N}. bounded_solution_set_sas_plus' \<Psi> k)"
+
+definition bounded_solution_set_strips'
+ :: "('variable \<times> 'domain) strips_problem
+ \<Rightarrow> nat
+ \<Rightarrow> ('variable \<times> 'domain) strips_plan set"
+ where "bounded_solution_set_strips' \<Pi> k
+ \<equiv> { \<pi>. STRIPS_Semantics.is_serial_solution_for_problem \<Pi> \<pi> \<and> length \<pi> = k }"
+
+abbreviation bounded_solution_set_strips
+ :: "('variable \<times> 'domain) strips_problem
+ \<Rightarrow> nat
+ \<Rightarrow> ('variable \<times> 'domain) strips_plan set"
+ where "bounded_solution_set_strips \<Pi> N \<equiv> (\<Union>k \<in> {0..N}. bounded_solution_set_strips' \<Pi> k)"
+
+\<comment> \<open> Show that plan transformation for all SAS Plus solutions yields a STRIPS solution for the
+induced STRIPS problem with same length.
+
+We first show injectiveness of plan transformation \<open>\<lambda>\<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]\<close> on the set of plans
+\<open>P\<^sub>k \<equiv> bounded_plan_set (operators_of \<Psi>) k\<close> with length bound \<open>k\<close>. The injectiveness of
+\<open>Sol\<^sub>k \<equiv> bounded_solution_set_sas_plus \<Psi> k\<close>---the set of solutions with length bound \<open>k\<close>--then
+follows from the subset relation \<open>Sol\<^sub>k \<subseteq> P\<^sub>k\<close>. \<close>
+lemma sasp_op_to_strips_injective:
+ assumes "(\<phi>\<^sub>O \<Psi> op\<^sub>1) = (\<phi>\<^sub>O \<Psi> op\<^sub>2)"
+ shows "op\<^sub>1 = op\<^sub>2"
+ proof -
+ let ?op\<^sub>1' = "\<phi>\<^sub>O \<Psi> op\<^sub>1"
+ and ?op\<^sub>2' = "\<phi>\<^sub>O \<Psi> op\<^sub>2"
+ {
+ have "strips_operator.precondition_of ?op\<^sub>1' = strips_operator.precondition_of ?op\<^sub>2'"
+ using assms
+ by argo
+ hence "sas_plus_operator.precondition_of op\<^sub>1 = sas_plus_operator.precondition_of op\<^sub>2"
+ unfolding sasp_op_to_strips_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ Let_def
+ by simp
+ }
+ moreover {
+ have "strips_operator.add_effects_of ?op\<^sub>1' = strips_operator.add_effects_of ?op\<^sub>2'"
+ using assms
+ unfolding sasp_op_to_strips_def Let_def
+ by argo
+ hence "sas_plus_operator.effect_of op\<^sub>1 = sas_plus_operator.effect_of op\<^sub>2"
+ unfolding sasp_op_to_strips_def Let_def
+ SAS_Plus_STRIPS.sasp_op_to_strips_def
+ by simp
+ }
+ ultimately show ?thesis
+ by simp
+ qed
+
+lemma sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_i_a:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "inj_on (\<lambda>\<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]) (bounded_plan_set (sas_plus_problem.operators_of \<Psi>) k)"
+ proof -
+ let ?ops = "sas_plus_problem.operators_of \<Psi>"
+ (* TODO refactor transformation definitions *)
+ and ?\<phi>\<^sub>P = "\<lambda>\<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]"
+ let ?P = "bounded_plan_set ?ops"
+ {
+ fix \<psi>\<^sub>1 \<psi>\<^sub>2
+ assume \<psi>\<^sub>1_in: "\<psi>\<^sub>1 \<in> ?P k"
+ and \<psi>\<^sub>2_in: "\<psi>\<^sub>2 \<in> ?P k"
+ and \<phi>\<^sub>P_of_\<psi>\<^sub>1_is_\<phi>\<^sub>P_of_\<psi>\<^sub>2: "(?\<phi>\<^sub>P \<psi>\<^sub>1) = (?\<phi>\<^sub>P \<psi>\<^sub>2)"
+ hence "\<psi>\<^sub>1 = \<psi>\<^sub>2"
+ proof (induction k arbitrary: \<psi>\<^sub>1 \<psi>\<^sub>2)
+ case 0
+ then have "length \<psi>\<^sub>1 = 0"
+ and "length \<psi>\<^sub>2 = 0"
+ using \<psi>\<^sub>1_in \<psi>\<^sub>2_in
+ unfolding bounded_solution_set_sas_plus'_def
+ by blast+
+ then show ?case
+ by blast
+ next
+ case (Suc k)
+ moreover have "length \<psi>\<^sub>1 = Suc k" and "length \<psi>\<^sub>2 = Suc k"
+ using length_Suc_conv Suc(2, 3)
+ unfolding bounded_solution_set_sas_plus'_def
+ by blast+
+ moreover obtain op\<^sub>1 \<psi>\<^sub>1' where "\<psi>\<^sub>1 = op\<^sub>1 # \<psi>\<^sub>1'"
+ and "set (op\<^sub>1 # \<psi>\<^sub>1') \<subseteq> set ?ops"
+ and "length \<psi>\<^sub>1' = k"
+ using calculation(5) Suc(2)
+ unfolding length_Suc_conv
+ by blast
+ moreover obtain op\<^sub>2 \<psi>\<^sub>2' where "\<psi>\<^sub>2 = op\<^sub>2 # \<psi>\<^sub>2'"
+ and "set (op\<^sub>2 # \<psi>\<^sub>2') \<subseteq> set ?ops"
+ and "length \<psi>\<^sub>2' = k"
+ using calculation(6) Suc(3)
+ unfolding length_Suc_conv
+ by blast
+ moreover have "set \<psi>\<^sub>1' \<subseteq> set ?ops" and "set \<psi>\<^sub>2' \<subseteq> set ?ops"
+ using calculation(8, 11)
+ by auto+
+ moreover have "\<psi>\<^sub>1' \<in> ?P k" and "\<psi>\<^sub>2' \<in> ?P k"
+ using calculation(9, 12, 13, 14)
+ by fast+
+ moreover have "?\<phi>\<^sub>P \<psi>\<^sub>1' = ?\<phi>\<^sub>P \<psi>\<^sub>2'"
+ using Suc.prems(3) calculation(7, 10)
+ by fastforce
+ moreover have "\<psi>\<^sub>1' = \<psi>\<^sub>2'"
+ using Suc.IH[of \<psi>\<^sub>1' \<psi>\<^sub>2', OF calculation(15, 16, 17)]
+ by simp
+ moreover have "?\<phi>\<^sub>P \<psi>\<^sub>1 = (\<phi>\<^sub>O \<Psi> op\<^sub>1) # ?\<phi>\<^sub>P \<psi>\<^sub>1'"
+ and "?\<phi>\<^sub>P \<psi>\<^sub>2 = (\<phi>\<^sub>O \<Psi> op\<^sub>2) # ?\<phi>\<^sub>P \<psi>\<^sub>2'"
+ using Suc.prems(3) calculation(7, 10)
+ by fastforce+
+ moreover have "(\<phi>\<^sub>O \<Psi> op\<^sub>1) = (\<phi>\<^sub>O \<Psi> op\<^sub>2)"
+ using Suc.prems(3) calculation(17, 19, 20)
+ by simp
+ moreover have "op\<^sub>1 = op\<^sub>2"
+ using sasp_op_to_strips_injective[OF calculation(21)].
+ ultimately show ?case
+ by argo
+ qed
+ }
+ thus ?thesis
+ unfolding inj_on_def
+ by blast
+ qed
+
+private corollary sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_i_b:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "inj_on (\<lambda>\<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]) (bounded_solution_set_sas_plus' \<Psi> k)"
+ proof -
+ let ?ops = "sas_plus_problem.operators_of \<Psi>"
+ and ?\<phi>\<^sub>P = "\<lambda>\<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]"
+ {
+ fix \<psi>
+ assume "\<psi> \<in> bounded_solution_set_sas_plus' \<Psi> k"
+ then have "set \<psi> \<subseteq> set ?ops"
+ and "length \<psi> = k"
+ unfolding bounded_solution_set_sas_plus'_def is_serial_solution_for_problem_def Let_def
+ list_all_iff ListMem_iff
+ by fast+
+ hence "\<psi> \<in> bounded_plan_set ?ops k"
+ by blast
+ }
+ hence "bounded_solution_set_sas_plus' \<Psi> k \<subseteq> bounded_plan_set ?ops k"
+ by blast
+ moreover have "inj_on ?\<phi>\<^sub>P (bounded_plan_set ?ops k)"
+ using sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_i_a[OF assms(1)].
+ ultimately show ?thesis
+ using inj_on_subset[of ?\<phi>\<^sub>P "bounded_plan_set ?ops k" "bounded_solution_set_sas_plus' \<Psi> k"]
+ by fast
+ qed
+
+(*
+lemma "card ((\<lambda>\<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]) ` (bounded_solution_set_sas_plus' \<Psi> k))
+ = card (bounded_solution_set_strips' (\<phi> \<Psi>) k)" sorry
+*)
+
+\<comment> \<open> Show that mapping plan transformation \<open>\<lambda>\<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]\<close> over the solution set for a
+given SAS+ problem yields the solution set for the induced STRIPS problem. \<close>
+private lemma sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_i_c:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "(\<lambda>\<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]) ` (bounded_solution_set_sas_plus' \<Psi> k)
+ = bounded_solution_set_strips' (\<phi> \<Psi>) k"
+ proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ and ?\<phi>\<^sub>P = "\<lambda>\<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]"
+ let ?Sol\<^sub>k = "bounded_solution_set_sas_plus' \<Psi> k"
+ and ?Sol\<^sub>k' = "bounded_solution_set_strips' ?\<Pi> k"
+ {
+ assume "?\<phi>\<^sub>P ` ?Sol\<^sub>k \<noteq> ?Sol\<^sub>k'"
+ then consider (A) "\<exists>\<pi> \<in> ?\<phi>\<^sub>P ` ?Sol\<^sub>k. \<pi> \<notin> ?Sol\<^sub>k'"
+ | (B) "\<exists>\<pi> \<in> ?Sol\<^sub>k'. \<pi> \<notin> ?\<phi>\<^sub>P ` ?Sol\<^sub>k"
+ by blast
+ hence False
+ proof (cases)
+ case A
+ moreover obtain \<pi> where "\<pi> \<in> ?\<phi>\<^sub>P ` ?Sol\<^sub>k" and "\<pi> \<notin> ?Sol\<^sub>k'"
+ using calculation
+ by blast
+ moreover obtain \<psi> where "length \<psi> = k"
+ and "SAS_Plus_Semantics.is_serial_solution_for_problem \<Psi> \<psi>"
+ and "\<pi> = ?\<phi>\<^sub>P \<psi>"
+ using calculation(2)
+ unfolding bounded_solution_set_sas_plus'_def
+ by blast
+ moreover have "length \<pi> = k" and "STRIPS_Semantics.is_serial_solution_for_problem ?\<Pi> \<pi>"
+ subgoal
+ using calculation(4, 6) by auto
+ subgoal
+ using serial_sas_plus_equivalent_to_serial_strips
+ assms(1) calculation(5) calculation(6)
+ by blast
+ done
+ moreover have "\<pi> \<in> ?Sol\<^sub>k'"
+ unfolding bounded_solution_set_strips'_def
+ using calculation(7, 8)
+ by simp
+ ultimately show ?thesis
+ by fast
+ next
+ case B
+ moreover obtain \<pi> where "\<pi> \<in> ?Sol\<^sub>k'" and "\<pi> \<notin> ?\<phi>\<^sub>P ` ?Sol\<^sub>k"
+ using calculation
+ by blast
+ moreover have "STRIPS_Semantics.is_serial_solution_for_problem ?\<Pi> \<pi>"
+ and "length \<pi> = k"
+ using calculation(2)
+ unfolding bounded_solution_set_strips'_def
+ by simp+
+ \<comment> \<open> Construct the counter example \<open>\<psi> \<equiv> [\<phi>\<^sub>O\<inverse> ?\<Pi> op. op \<leftarrow> \<pi>]\<close> and show that \<open>\<psi> \<in> ?Sol\<^sub>k\<close>
+ as well as \<open>?\<phi>\<^sub>P \<psi> = \<pi>\<close> hence \<open>\<pi> \<in> ?\<phi>\<^sub>P ` ?Sol\<^sub>k\<close>. \<close>
+ moreover have "length [\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> \<pi>] = k"
+ and "SAS_Plus_Semantics.is_serial_solution_for_problem \<Psi> [\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> \<pi>]"
+ subgoal
+ using calculation(5)
+ by simp
+ subgoal
+ using serial_strips_equivalent_to_serial_sas_plus[OF assms(1)]
+ calculation(4)
+ by simp
+ done
+ moreover have "[\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> \<pi>] \<in> ?Sol\<^sub>k"
+ unfolding bounded_solution_set_sas_plus'_def
+ using calculation(6, 7)
+ by blast
+ (* TODO refactor transformation lemmas *)
+ moreover {
+ have "\<forall>op \<in> set \<pi>. op \<in> set ((?\<Pi>)\<^sub>\<O>)"
+ using calculation(4)
+ unfolding STRIPS_Semantics.is_serial_solution_for_problem_def list_all_iff ListMem_iff
+ by simp
+ hence "?\<phi>\<^sub>P [\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> \<pi>] = \<pi>"
+ proof (induction \<pi>)
+ case (Cons op \<pi>)
+ moreover have "?\<phi>\<^sub>P [\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> op # \<pi>]
+ = (\<phi>\<^sub>O \<Psi> (\<phi>\<^sub>O\<inverse> \<Psi> op)) # ?\<phi>\<^sub>P [\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> \<pi>]"
+ by simp
+ moreover have "op \<in> set ((?\<Pi>)\<^sub>\<O>)"
+ using Cons.prems
+ by simp
+ moreover have "(\<phi>\<^sub>O \<Psi> (\<phi>\<^sub>O\<inverse> \<Psi> op)) = op"
+ using strips_operator_inverse_is[OF assms(1) calculation(4)].
+ moreover have "?\<phi>\<^sub>P [\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> \<pi>] = \<pi>"
+ using Cons.IH Cons.prems
+ by auto
+ ultimately show ?case
+ by argo
+ qed simp
+ }
+ moreover have "\<pi> \<in> ?\<phi>\<^sub>P ` ?Sol\<^sub>k"
+ using calculation(8, 9)
+ by force
+ ultimately show ?thesis
+ by blast
+ qed
+ }
+ thus ?thesis
+ by blast
+ qed
+
+private lemma sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_i_d:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "card (bounded_solution_set_sas_plus' \<Psi> k) \<le> card (bounded_solution_set_strips' (\<phi> \<Psi>) k)"
+ proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ and ?\<phi>\<^sub>P = "\<lambda>\<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>]"
+ let ?Sol\<^sub>k = "bounded_solution_set_sas_plus' \<Psi> k"
+ and ?Sol\<^sub>k' = "bounded_solution_set_strips' ?\<Pi> k"
+ have "card (?\<phi>\<^sub>P ` ?Sol\<^sub>k) = card (?Sol\<^sub>k)"
+ using sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_i_b[OF assms(1)]
+ card_image
+ by blast
+ moreover have "?\<phi>\<^sub>P ` ?Sol\<^sub>k = ?Sol\<^sub>k'"
+ using sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_i_c[OF assms(1)].
+ ultimately show ?thesis
+ by simp
+ qed
+
+\<comment> \<open> The set of fixed length plans with operators in a given operator set is finite. \<close>
+lemma bounded_plan_set_finite:
+ shows "finite { \<pi>. set \<pi> \<subseteq> set ops \<and> length \<pi> = k }"
+ proof (induction k)
+ case (Suc k)
+ let ?P = "{ \<pi>. set \<pi> \<subseteq> set ops \<and> length \<pi> = k }"
+ and ?P' = "{ \<pi>. set \<pi> \<subseteq> set ops \<and> length \<pi> = Suc k }"
+ let ?P'' = "(\<Union>op \<in> set ops. (\<Union>\<pi> \<in> ?P. { op # \<pi> }))"
+ {
+ have "\<forall>op \<pi>. finite { op # \<pi> }"
+ by simp
+ then have "\<forall>op. finite (\<Union>\<pi> \<in> ?P. { op # \<pi> })"
+ using finite_UN[of ?P] Suc
+ by blast
+ hence "finite ?P''"
+ using finite_UN[of "set ops"]
+ by blast
+ }
+ moreover {
+ {
+ fix \<pi>
+ assume "\<pi> \<in> ?P'"
+ moreover have "set \<pi> \<subseteq> set ops"
+ and "length \<pi> = Suc k"
+ using calculation
+ by simp+
+ moreover obtain op \<pi>' where "\<pi> = op # \<pi>'"
+ using calculation (3)
+ unfolding length_Suc_conv
+ by fast
+ moreover have "set \<pi>' \<subseteq> set ops" and "op \<in> set ops"
+ using calculation(2, 4)
+ by simp+
+ moreover have "length \<pi>' = k"
+ using calculation(3, 4)
+ by auto
+ moreover have "\<pi>' \<in> ?P"
+ using calculation(5, 7)
+ by blast
+ ultimately have "\<pi> \<in> ?P''"
+ by blast
+ }
+ hence "?P' \<subseteq> ?P''"
+ by blast
+ }
+ ultimately show ?case
+ using rev_finite_subset[of ?P'' ?P']
+ by blast
+ qed force
+
+\<comment> \<open> The set of fixed length SAS+ solutions are subsets of the set of plans with fixed length and
+therefore also finite. \<close>
+private lemma sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_ii_a:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "finite (bounded_solution_set_sas_plus' \<Psi> k)"
+proof -
+ let ?Ops = "set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ let ?Sol\<^sub>k = "bounded_solution_set_sas_plus' \<Psi> k"
+ and ?P\<^sub>k = "{ \<pi>. set \<pi> \<subseteq> ?Ops \<and> length \<pi> = k }"
+ {
+ fix \<psi>
+ assume "\<psi> \<in> ?Sol\<^sub>k"
+ then have "length \<psi> = k" and "set \<psi> \<subseteq> ?Ops"
+ unfolding bounded_solution_set_sas_plus'_def
+ SAS_Plus_Semantics.is_serial_solution_for_problem_def Let_def list_all_iff ListMem_iff
+ by fastforce+
+ hence "\<psi> \<in> ?P\<^sub>k"
+ by blast
+ }
+ then have "?Sol\<^sub>k \<subseteq> ?P\<^sub>k"
+ by force
+ thus ?thesis
+ using bounded_plan_set_finite rev_finite_subset[of ?P\<^sub>k ?Sol\<^sub>k]
+ by auto
+qed
+
+\<comment> \<open> The set of fixed length STRIPS solutions are subsets of the set of plans with fixed length and
+therefore also finite. \<close>
+private lemma sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_ii_b:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "finite (bounded_solution_set_strips' (\<phi> \<Psi>) k)"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ let ?Ops = "set ((?\<Pi>)\<^sub>\<O>)"
+ let ?Sol\<^sub>k = "bounded_solution_set_strips' ?\<Pi> k"
+ and ?P\<^sub>k = "{ \<pi>. set \<pi> \<subseteq> ?Ops \<and> length \<pi> = k }"
+ {
+ fix \<pi>
+ assume "\<pi> \<in> ?Sol\<^sub>k"
+ then have "length \<pi> = k" and "set \<pi> \<subseteq> ?Ops"
+ unfolding bounded_solution_set_strips'_def
+ STRIPS_Semantics.is_serial_solution_for_problem_def Let_def list_all_iff ListMem_iff
+ by fastforce+
+ hence "\<pi> \<in> ?P\<^sub>k"
+ by blast
+ }
+ then have "?Sol\<^sub>k \<subseteq> ?P\<^sub>k"
+ by force
+ thus ?thesis
+ using bounded_plan_set_finite rev_finite_subset[of ?P\<^sub>k ?Sol\<^sub>k]
+ unfolding state_to_strips_state_def
+ SAS_Plus_STRIPS.state_to_strips_state_def operators_of_def
+ by blast
+qed
+
+text \<open> With the results on the equivalence of SAS+ and STRIPS solutions, we can now show that given
+problems in both formalisms, the solution sets have the same size.
+This is the property required by the definition of planning formalism equivalence presented earlier
+in theorem \ref{thm:solution-sets-sas-plus-strips-f} (\autoref{sub:equivalence-sas-plus-strips}) and
+thus end up with the desired equivalence result.
+
+The proof uses the finiteness and disjunctiveness of the solution sets for either problem to be
+able to equivalently transform the set cardinality over the union of sets of solutions with bounded
+lengths into a sum over the cardinality of the sets of solutions with bounded length. Moreover,
+since we know that for each SAS+ solution with a given length an equivalent STRIPS solution exists
+in the solution set of the transformed problem with the same length, both sets must have the same
+cardinality.
+
+Hence the cardinality of the SAS+ solution set over all lengths up to a given upper bound \<^term>\<open>N\<close>
+has the same size as the solution set of the corresponding STRIPS problem over all length up to a
+given upper bound \<^term>\<open>N\<close>. \<close>
+
+theorem
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "card (bounded_solution_set_sas_plus \<Psi> N)
+ = card (bounded_solution_set_strips (\<phi> \<Psi>) N)"
+ proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ and ?R = "{0..N}"
+ \<comment> \<open> Due to the disjoint nature of the bounded solution sets for fixed plan length for different
+ lengths, we can sum the individual set cardinality to obtain the cardinality of the overall SAS+
+ resp. STRIPS solution sets. \<close>
+ have finite_R: "finite ?R"
+ by simp
+ moreover {
+ have "\<forall>k \<in> ?R. finite (bounded_solution_set_sas_plus' \<Psi> k)"
+ using sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_ii_a[OF
+ assms(1)]..
+ moreover have "\<forall>j \<in> ?R. \<forall>k \<in> ?R. j \<noteq> k
+ \<longrightarrow> bounded_solution_set_sas_plus' \<Psi> j
+ \<inter> bounded_solution_set_sas_plus' \<Psi> k = {}"
+ unfolding bounded_solution_set_sas_plus'_def
+ by blast
+ (* TODO slow. *)
+ ultimately have "card (bounded_solution_set_sas_plus \<Psi> N)
+ = (\<Sum>k \<in> ?R. card (bounded_solution_set_sas_plus' \<Psi> k))"
+ using card_UN_disjoint
+ by blast
+ }
+ moreover {
+ have "\<forall>k \<in> ?R. finite (bounded_solution_set_strips' ?\<Pi> k)"
+ using sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_ii_b[OF
+ assms(1)]..
+ moreover have "\<forall>j \<in> ?R. \<forall>k \<in> ?R. j \<noteq> k
+ \<longrightarrow> bounded_solution_set_strips' ?\<Pi> j
+ \<inter> bounded_solution_set_strips' ?\<Pi> k = {}"
+ unfolding bounded_solution_set_strips'_def
+ by blast
+ (* TODO slow. *)
+ ultimately have "card (bounded_solution_set_strips ?\<Pi> N)
+ = (\<Sum>k \<in> ?R. card (bounded_solution_set_strips' ?\<Pi> k))"
+ using card_UN_disjoint
+ by blast
+ }
+ moreover {
+ fix k
+ have "card (bounded_solution_set_sas_plus' \<Psi> k)
+ = card ((\<lambda>\<psi>. [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> \<psi>])
+ ` bounded_solution_set_sas_plus' \<Psi> k)"
+ using sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_i_b[OF assms]
+ card_image[symmetric]
+ by blast
+ hence "card (bounded_solution_set_sas_plus' \<Psi> k)
+ = card (bounded_solution_set_strips' ?\<Pi> k)"
+ using sas_plus_formalism_and_induced_strips_formalism_are_equally_expressive_i_c[OF assms]
+ by presburger
+ }
+ ultimately show ?thesis
+ by presburger
+ qed
+
+
+end
+
+end
\ No newline at end of file
diff --git a/thys/Verified_SAT_Based_AI_Planning/SAS_Plus_Semantics.thy b/thys/Verified_SAT_Based_AI_Planning/SAS_Plus_Semantics.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/SAS_Plus_Semantics.thy
@@ -0,0 +1,1002 @@
+(*
+ Author: Mohammad Abdulaziz, Fred Kurz
+*)
+theory SAS_Plus_Semantics
+ imports "SAS_Plus_Representation" "List_Supplement"
+ "Map_Supplement"
+begin
+section "SAS+ Semantics"
+
+
+subsection "Serial Execution Semantics"
+
+text \<open> Serial plan execution is implemented recursively just like in the STRIPS case. By and large,
+compared to definition \ref{isadef:plan-execution-strips}, we only substitute the operator
+applicability function with its SAS+ counterpart. \<close>
+
+primrec execute_serial_plan_sas_plus
+ where "execute_serial_plan_sas_plus s [] = s"
+ | "execute_serial_plan_sas_plus s (op # ops)
+ = (if is_operator_applicable_in s op
+ then execute_serial_plan_sas_plus (execute_operator_sas_plus s op) ops
+ else s)"
+
+text \<open> Similarly, serial SAS+ solutions are defined just like in STRIPS but based on the
+corresponding SAS+ definitions. \<close>
+
+definition is_serial_solution_for_problem
+ :: "('variable, 'domain) sas_plus_problem \<Rightarrow> ('variable, 'domain) sas_plus_plan \<Rightarrow> bool"
+ where "is_serial_solution_for_problem \<Psi> \<psi>
+ \<equiv> let
+ I = sas_plus_problem.initial_of \<Psi>
+ ; G = sas_plus_problem.goal_of \<Psi>
+ ; ops = sas_plus_problem.operators_of \<Psi>
+ in G \<subseteq>\<^sub>m execute_serial_plan_sas_plus I \<psi>
+ \<and> list_all (\<lambda>op. ListMem op ops) \<psi>"
+
+
+context
+begin
+
+private lemma execute_operator_sas_plus_effect_i:
+ assumes "is_operator_applicable_in s op"
+ and "\<forall>(v, a) \<in> set (effect_of op). \<forall>(v', a') \<in> set (effect_of op).
+ v \<noteq> v' \<or> a = a'"
+ and"(v, a) \<in> set (effect_of op)"
+ shows "(s \<then>\<^sub>+ op) v = Some a"
+proof -
+ let ?effect = "effect_of op"
+ have "map_of ?effect v = Some a"
+ using map_of_constant_assignments_defined_if[OF assms(2, 3)] try0
+ by blast
+ thus ?thesis
+ unfolding execute_operator_sas_plus_def map_add_def
+ by fastforce
+qed
+
+private lemma execute_operator_sas_plus_effect_ii:
+ assumes "is_operator_applicable_in s op"
+ and "\<forall>(v', a') \<in> set (effect_of op). v' \<noteq> v"
+ shows "(s \<then>\<^sub>+ op) v = s v"
+proof -
+ let ?effect = "effect_of op"
+ {
+ have "v \<notin> fst ` set ?effect"
+ using assms(2)
+ by fastforce
+ then have "v \<notin> dom (map_of ?effect)"
+ using dom_map_of_conv_image_fst[of ?effect]
+ by argo
+ hence "(s ++ map_of ?effect) v = s v"
+ using map_add_dom_app_simps(3)[of v "map_of ?effect" s]
+ by blast
+ }
+ thus ?thesis
+ by fastforce
+qed
+
+text \<open> Given an operator \<^term>\<open>op\<close> that is applicable in a state \<^term>\<open>s\<close> and has a consistent set
+of effects (second assumption) we can now show that the successor state \<^term>\<open>s' \<equiv> s \<then>\<^sub>+ op\<close>
+has the following properties:
+\begin{itemize}
+ \item \<^term>\<open>s' v = Some a\<close> if \<^term>\<open>(v, a)\<close> exist in \<^term>\<open>set (effect_of op)\<close>; and,
+ \item \<^term>\<open>s' v = s v\<close> if no \<^term>\<open>(v, a')\<close> exist in \<^term>\<open>set (effect_of op)\<close>.
+\end{itemize}
+The second property is the case if the operator doesn't have an effect for a variable \<^term>\<open>v\<close>. \<close>
+
+theorem execute_operator_sas_plus_effect:
+ assumes "is_operator_applicable_in s op"
+ and "\<forall>(v, a) \<in> set (effect_of op).
+ \<forall>(v', a') \<in> set (effect_of op). v \<noteq> v' \<or> a = a'"
+ shows "(v, a) \<in> set (effect_of op)
+ \<longrightarrow> (s \<then>\<^sub>+ op) v = Some a"
+ and "(\<forall>a. (v, a) \<notin> set (effect_of op))
+ \<longrightarrow> (s \<then>\<^sub>+ op) v = s v"
+proof -
+ show "(v, a) \<in> set (effect_of op)
+ \<longrightarrow> (s \<then>\<^sub>+ op) v = Some a"
+ using execute_operator_sas_plus_effect_i[OF assms(1, 2)]
+ by blast
+next
+ show "(\<forall>a. (v, a) \<notin> set (effect_of op))
+ \<longrightarrow> (s \<then>\<^sub>+ op) v = s v"
+ using execute_operator_sas_plus_effect_ii[OF assms(1)]
+ by blast
+qed
+
+end
+
+
+subsection "Parallel Execution Semantics"
+
+\<comment> \<open> Define a type synonym for \emph{SAS+ parallel plans} and add a definition lifting SAS+
+operator applicability to parallel plans. \<close>
+
+type_synonym ('variable, 'domain) sas_plus_parallel_plan
+ = "('variable, 'domain) sas_plus_operator list list"
+
+definition are_all_operators_applicable_in
+ :: "('variable, 'domain) state
+ \<Rightarrow> ('variable, 'domain) sas_plus_operator list
+ \<Rightarrow> bool"
+ where "are_all_operators_applicable_in s ops
+ \<equiv> list_all (is_operator_applicable_in s) ops"
+
+definition are_operator_effects_consistent
+ :: "('variable, 'domain) sas_plus_operator
+ \<Rightarrow> ('variable, 'domain) sas_plus_operator
+ \<Rightarrow> bool"
+ where "are_operator_effects_consistent op op'
+ \<equiv> let
+ effect = effect_of op
+ ; effect' = effect_of op'
+ in list_all (\<lambda>(v, a). list_all (\<lambda>(v', a'). v \<noteq> v' \<or> a = a') effect') effect"
+
+definition are_all_operator_effects_consistent
+ :: "('variable, 'domain) sas_plus_operator list
+ \<Rightarrow> bool"
+ where "are_all_operator_effects_consistent ops
+ \<equiv> list_all (\<lambda>op. list_all (are_operator_effects_consistent op) ops) ops"
+
+definition execute_parallel_operator_sas_plus
+ :: "('variable, 'domain) state
+ \<Rightarrow> ('variable, 'domain) sas_plus_operator list
+ \<Rightarrow> ('variable, 'domain) state"
+ where "execute_parallel_operator_sas_plus s ops
+ \<equiv> foldl (++) s (map (map_of \<circ> effect_of) ops)"
+
+text \<open> We now define parallel execution and parallel traces for SAS+ by lifting the tests for
+applicability and effect consistency to parallel SAS+ operators. The definitions are again very
+similar to their STRIPS analogs (definitions \ref{isadef:parallel-plan-execution-strips} and
+\ref{isadef:parallel-plan-trace-strips}). \<close>
+
+fun execute_parallel_plan_sas_plus
+ :: "('variable, 'domain) state
+ \<Rightarrow> ('variable, 'domain) sas_plus_parallel_plan
+ \<Rightarrow> ('variable, 'domain) state"
+ where "execute_parallel_plan_sas_plus s [] = s"
+ | "execute_parallel_plan_sas_plus s (ops # opss) = (if
+ are_all_operators_applicable_in s ops
+ \<and> are_all_operator_effects_consistent ops
+ then execute_parallel_plan_sas_plus
+ (execute_parallel_operator_sas_plus s ops) opss
+ else s)"
+
+fun trace_parallel_plan_sas_plus
+ :: "('variable, 'domain) state
+ \<Rightarrow> ('variable, 'domain) sas_plus_parallel_plan
+ \<Rightarrow> ('variable, 'domain) state list"
+ where "trace_parallel_plan_sas_plus s [] = [s]"
+ | "trace_parallel_plan_sas_plus s (ops # opss) = s # (if
+ are_all_operators_applicable_in s ops
+ \<and> are_all_operator_effects_consistent ops
+ then trace_parallel_plan_sas_plus
+ (execute_parallel_operator_sas_plus s ops) opss
+ else [])"
+
+text \<open> A plan \<^term>\<open>\<psi>\<close> is a solution for a SAS+ problem \<^term>\<open>\<Psi>\<close> if
+\begin{enumerate}
+ \item starting from the initial state \<^term>\<open>\<Psi>\<close>, SAS+ parallel plan execution
+ reaches a state which satisfies the described goal state \<^term>\<open>sas_plus_problem.goal_of \<Psi>\<close>; and,
+ \item all parallel operators \<^term>\<open>ops\<close> in the plan \<^term>\<open>\<psi>\<close> only consist of operators that
+ are specified in the problem description.
+\end{enumerate} \<close>
+definition is_parallel_solution_for_problem
+ :: "('variable, 'domain) sas_plus_problem
+ \<Rightarrow> ('variable, 'domain) sas_plus_parallel_plan
+ \<Rightarrow> bool"
+ where "is_parallel_solution_for_problem \<Psi> \<psi>
+ \<equiv> let
+ G = sas_plus_problem.goal_of \<Psi>
+ ; I = sas_plus_problem.initial_of \<Psi>
+ ; Ops = sas_plus_problem.operators_of \<Psi>
+ in G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus I \<psi>
+ \<and> list_all (\<lambda>ops. list_all (\<lambda>op. ListMem op Ops) ops) \<psi>"
+
+context
+begin
+
+lemma execute_parallel_operator_sas_plus_cons[simp]:
+ "execute_parallel_operator_sas_plus s (op # ops)
+ = execute_parallel_operator_sas_plus (s ++ map_of (effect_of op)) ops"
+ unfolding execute_parallel_operator_sas_plus_def
+ by simp
+
+text \<open>The following lemmas show the properties of SAS+ parallel plan execution traces.
+The results are analogous to those for STRIPS. So, let \<^term>\<open>\<tau> \<equiv> trace_parallel_plan_sas_plus I \<psi>\<close>
+be a trace of a parallel SAS+ plan \<^term>\<open>\<psi>\<close> with initial state \<^term>\<open>I\<close>, then
+\begin{itemize}
+ \item the head of the trace \<^term>\<open>\<tau> ! 0\<close> is the initial state of the
+problem (lemma \ref{isathm:head-parallel-plan-trace-sas-plus}); moreover,
+ \item for all but the last element of the trace---i.e. elements with index
+\<^term>\<open>k < length \<tau> - 1\<close>---the parallel operator \<^term>\<open>\<pi> ! k\<close> is executable (lemma
+\ref{isathm:parallel-plan-trace-operator-execution-conditions-sas-plus}); and
+finally,
+ \item for all \<^term>\<open>k < length \<tau>\<close>, the parallel execution of the plan prefix \<^term>\<open>take k \<psi>\<close> with
+initial state \<^term>\<open>I\<close> equals the \<^term>\<open>k\<close>-th element of the trace \<^term>\<open>\<tau> ! k\<close> (lemma
+\ref{isathm:parallel-trace-plan-prefixes-sas-plus}).
+\end{itemize} \<close>
+
+(* TODO? Make invisible? *)
+lemma trace_parallel_plan_sas_plus_head_is_initial_state:
+ "trace_parallel_plan_sas_plus I \<psi> ! 0 = I"
+proof (cases \<psi>)
+ case (Cons a list)
+ then show ?thesis
+ by (cases "are_all_operators_applicable_in I a \<and> are_all_operator_effects_consistent a";
+ simp+)
+qed simp
+
+lemma trace_parallel_plan_sas_plus_length_gt_one_if:
+ assumes "k < length (trace_parallel_plan_sas_plus I \<psi>) - 1"
+ shows "1 < length (trace_parallel_plan_sas_plus I \<psi>)"
+ using assms
+ by linarith
+
+lemma length_trace_parallel_plan_sas_plus_lte_length_plan_plus_one:
+ shows "length (trace_parallel_plan_sas_plus I \<psi>) \<le> length \<psi> + 1"
+proof (induction \<psi> arbitrary: I)
+ case (Cons a \<psi>)
+ then show ?case
+ proof (cases "are_all_operators_applicable_in I a \<and> are_all_operator_effects_consistent a")
+ case True
+ let ?I' = "execute_parallel_operator_sas_plus I a"
+ {
+ have "trace_parallel_plan_sas_plus I (a # \<psi>) = I # trace_parallel_plan_sas_plus ?I' \<psi>"
+ using True
+ by auto
+ then have "length (trace_parallel_plan_sas_plus I (a # \<psi>))
+ = length (trace_parallel_plan_sas_plus ?I' \<psi>) + 1"
+ by simp
+ moreover have "length (trace_parallel_plan_sas_plus ?I' \<psi>) \<le> length \<psi> + 1"
+ using Cons.IH[of ?I']
+ by blast
+ ultimately have "length (trace_parallel_plan_sas_plus I (a # \<psi>)) \<le> length (a # \<psi>) + 1"
+ by simp
+ }
+ thus ?thesis
+ by blast
+ qed auto
+qed simp
+
+lemma plan_is_at_least_singleton_plan_if_trace_has_at_least_two_elements:
+ assumes "k < length (trace_parallel_plan_sas_plus I \<psi>) - 1"
+ obtains ops \<psi>' where "\<psi> = ops # \<psi>'"
+proof -
+ let ?\<tau> = "trace_parallel_plan_sas_plus I \<psi>"
+ have "length ?\<tau> \<le> length \<psi> + 1"
+ using length_trace_parallel_plan_sas_plus_lte_length_plan_plus_one
+ by fast
+ then have "0 < length \<psi>"
+ using trace_parallel_plan_sas_plus_length_gt_one_if[OF assms]
+ by fastforce
+ then obtain k' where "length \<psi> = Suc k'"
+ using gr0_implies_Suc
+ by meson
+ thus ?thesis using that
+ using length_Suc_conv[of \<psi> k']
+ by blast
+qed
+
+lemma trace_parallel_plan_sas_plus_step_implies_operator_execution_condition_holds:
+ assumes "k < length (trace_parallel_plan_sas_plus I \<pi>) - 1"
+ shows "are_all_operators_applicable_in (trace_parallel_plan_sas_plus I \<pi> ! k) (\<pi> ! k)
+ \<and> are_all_operator_effects_consistent (\<pi> ! k)"
+using assms
+proof (induction "\<pi>" arbitrary: I k)
+ \<comment> \<open> NOTE Base case yields contradiction with assumption and can be left to automation. \<close>
+ case (Cons a \<pi>)
+ then show ?case
+ proof (cases "are_all_operators_applicable_in I a \<and> are_all_operator_effects_consistent a")
+ case True
+ have trace_parallel_plan_sas_plus_cons: "trace_parallel_plan_sas_plus I (a # \<pi>)
+ = I # trace_parallel_plan_sas_plus (execute_parallel_operator_sas_plus I a) \<pi>"
+ using True
+ by simp
+ then show ?thesis
+ proof (cases "k")
+ case 0
+ have "trace_parallel_plan_sas_plus I (a # \<pi>) ! 0 = I"
+ using trace_parallel_plan_sas_plus_cons
+ by simp
+ moreover have "(a # \<pi>) ! 0 = a"
+ by simp
+ ultimately show ?thesis
+ using True 0
+ by presburger
+ next
+ case (Suc k')
+ have "trace_parallel_plan_sas_plus I (a # \<pi>) ! Suc k'
+ = trace_parallel_plan_sas_plus (execute_parallel_operator_sas_plus I a) \<pi> ! k'"
+ using trace_parallel_plan_sas_plus_cons
+ by simp
+ moreover have "(a # \<pi>) ! Suc k' = \<pi> ! k'"
+ by simp
+ moreover {
+ let ?I' = "execute_parallel_operator_sas_plus I a"
+ have "length (trace_parallel_plan_sas_plus I (a # \<pi>))
+ = 1 + length (trace_parallel_plan_sas_plus ?I' \<pi>)"
+ using trace_parallel_plan_sas_plus_cons
+ by auto
+ then have "k' < length (trace_parallel_plan_sas_plus ?I' \<pi>) - 1"
+ using Cons.prems Suc
+ unfolding Suc_eq_plus1
+ by fastforce
+ hence "are_all_operators_applicable_in
+ (trace_parallel_plan_sas_plus (execute_parallel_operator_sas_plus I a) \<pi> ! k')
+ (\<pi> ! k')
+ \<and> are_all_operator_effects_consistent (\<pi> ! k')"
+ using Cons.IH[of k' "execute_parallel_operator_sas_plus I a"] Cons.prems Suc trace_parallel_plan_sas_plus_cons
+ by simp
+ }
+ ultimately show ?thesis
+ using Suc
+ by argo
+ qed
+ next
+ case False
+ then have "trace_parallel_plan_sas_plus I (a # \<pi>) = [I]"
+ by force
+ then have "length (trace_parallel_plan_sas_plus I (a # \<pi>)) - 1 = 0"
+ by simp
+ \<comment> \<open> NOTE Thesis follows from contradiction with assumption. \<close>
+ then show ?thesis
+ using Cons.prems
+ by force
+ qed
+qed auto
+
+lemma trace_parallel_plan_sas_plus_prefix:
+ assumes "k < length (trace_parallel_plan_sas_plus I \<psi>)"
+ shows "trace_parallel_plan_sas_plus I \<psi> ! k = execute_parallel_plan_sas_plus I (take k \<psi>)"
+ using assms
+proof (induction \<psi> arbitrary: I k)
+ case (Cons a \<psi>)
+ then show ?case
+ proof (cases "are_all_operators_applicable_in I a \<and> are_all_operator_effects_consistent a")
+ case True
+ let ?\<sigma> = "trace_parallel_plan_sas_plus I (a # \<psi>)"
+ and ?I' = "execute_parallel_operator_sas_plus I a"
+ have \<sigma>_equals: "?\<sigma> = I # trace_parallel_plan_sas_plus ?I' \<psi>"
+ using True
+ by auto
+ then show ?thesis
+ proof (cases "k = 0")
+ case False
+ obtain k' where k_is_suc_of_k': "k = Suc k'"
+ using not0_implies_Suc[OF False]
+ by blast
+ then have "execute_parallel_plan_sas_plus I (take k (a # \<psi>))
+ = execute_parallel_plan_sas_plus ?I' (take k' \<psi>)"
+ using True
+ by simp
+ moreover have "trace_parallel_plan_sas_plus I (a # \<psi>) ! k
+ = trace_parallel_plan_sas_plus ?I' \<psi> ! k'"
+ using \<sigma>_equals k_is_suc_of_k'
+ by simp
+ moreover {
+ have "k' < length (trace_parallel_plan_sas_plus ?I' \<psi>)"
+ using Cons.prems \<sigma>_equals k_is_suc_of_k'
+ by force
+ hence "trace_parallel_plan_sas_plus ?I' \<psi> ! k'
+ = execute_parallel_plan_sas_plus ?I' (take k' \<psi>)"
+ using Cons.IH[of k' ?I']
+ by blast
+ }
+ ultimately show ?thesis
+ by presburger
+ qed simp
+ next
+ case operator_precondition_violated: False
+ then show ?thesis
+ proof (cases "k = 0")
+ case False
+ then have "trace_parallel_plan_sas_plus I (a # \<psi>) = [I]"
+ using operator_precondition_violated
+ by force
+ moreover have "execute_parallel_plan_sas_plus I (take k (a # \<psi>)) = I"
+ using Cons.prems operator_precondition_violated
+ by force
+ ultimately show ?thesis
+ using Cons.prems nth_Cons_0
+ by auto
+ qed simp
+ qed
+qed simp
+
+lemma trace_parallel_plan_sas_plus_step_effect_is:
+ assumes "k < length (trace_parallel_plan_sas_plus I \<psi>) - 1"
+ shows "trace_parallel_plan_sas_plus I \<psi> ! Suc k
+ = execute_parallel_operator_sas_plus (trace_parallel_plan_sas_plus I \<psi> ! k) (\<psi> ! k)"
+proof -
+ let ?\<tau> = "trace_parallel_plan_sas_plus I \<psi>"
+ let ?\<tau>\<^sub>k = "?\<tau> ! k"
+ and ?\<tau>\<^sub>k' = "?\<tau> ! Suc k"
+ \<comment> \<open> NOTE rewrite the goal using the subplan formulation to be able. This allows us to make the
+ initial state arbitrary. \<close>
+ {
+ have suc_k_lt_length_\<tau>: "Suc k < length ?\<tau>"
+ using assms
+ by linarith
+ hence "?\<tau>\<^sub>k' = execute_parallel_plan_sas_plus I (take (Suc k) \<psi>)"
+ using trace_parallel_plan_sas_plus_prefix[of "Suc k"]
+ by blast
+ } note rewrite_goal = this
+ have "execute_parallel_plan_sas_plus I (take (Suc k) \<psi>)
+ = execute_parallel_operator_sas_plus (trace_parallel_plan_sas_plus I \<psi> ! k) (\<psi> ! k)"
+ using assms
+ proof (induction k arbitrary: I \<psi>)
+ case 0
+ obtain ops \<psi>' where \<psi>_is: "\<psi> = ops # \<psi>'"
+ using plan_is_at_least_singleton_plan_if_trace_has_at_least_two_elements[OF "0.prems"]
+ by force
+ {
+ have "take (Suc 0) \<psi> = [\<psi> ! 0]"
+ using \<psi>_is
+ by simp
+ hence "execute_parallel_plan_sas_plus I (take (Suc 0) \<psi>)
+ = execute_parallel_plan_sas_plus I [\<psi> ! 0]"
+ by argo
+ }
+ moreover {
+ have "trace_parallel_plan_sas_plus I \<psi> ! 0 = I"
+ using trace_parallel_plan_sas_plus_head_is_initial_state.
+ moreover {
+ have "are_all_operators_applicable_in I (\<psi> ! 0)"
+ and "are_all_operator_effects_consistent (\<psi> ! 0)"
+ using trace_parallel_plan_sas_plus_step_implies_operator_execution_condition_holds[OF
+ "0.prems"] calculation
+ by argo+
+ then have "execute_parallel_plan_sas_plus I [\<psi> ! 0]
+ = execute_parallel_operator_sas_plus I (\<psi> ! 0)"
+ by simp
+ }
+ ultimately have "execute_parallel_operator_sas_plus (trace_parallel_plan_sas_plus I \<psi> ! 0)
+ (\<psi> ! 0)
+ = execute_parallel_plan_sas_plus I [\<psi> ! 0]"
+ by argo
+ }
+ ultimately show ?case
+ by argo
+ next
+ case (Suc k)
+ obtain ops \<psi>' where \<psi>_is: "\<psi> = ops # \<psi>'"
+ using plan_is_at_least_singleton_plan_if_trace_has_at_least_two_elements[OF Suc.prems]
+ by blast
+ let ?I' = "execute_parallel_operator_sas_plus I ops"
+ have "execute_parallel_plan_sas_plus I (take (Suc (Suc k)) \<psi>)
+ = execute_parallel_plan_sas_plus ?I' (take (Suc k) \<psi>')"
+ using Suc.prems \<psi>_is
+ by fastforce
+ moreover {
+ thm Suc.IH[of ]
+ have "length (trace_parallel_plan_sas_plus I \<psi>)
+ = 1 + length (trace_parallel_plan_sas_plus ?I' \<psi>')"
+ using \<psi>_is Suc.prems
+ by fastforce
+ moreover have "k < length (trace_parallel_plan_sas_plus ?I' \<psi>') - 1"
+ using Suc.prems calculation
+ by fastforce
+ ultimately have "execute_parallel_plan_sas_plus ?I' (take (Suc k) \<psi>') =
+ execute_parallel_operator_sas_plus (trace_parallel_plan_sas_plus ?I' \<psi>' ! k)
+ (\<psi>' ! k)"
+ using Suc.IH[of ?I' \<psi>']
+ by blast
+ }
+ moreover have "execute_parallel_operator_sas_plus (trace_parallel_plan_sas_plus ?I' \<psi>' ! k)
+ (\<psi>' ! k)
+ = execute_parallel_operator_sas_plus (trace_parallel_plan_sas_plus I \<psi> ! Suc k)
+ (\<psi> ! Suc k)"
+ using Suc.prems \<psi>_is
+ by auto
+ ultimately show ?case
+ by argo
+ qed
+ thus ?thesis
+ using rewrite_goal
+ by argo
+qed
+
+text \<open> Finally, we obtain the result corresponding to lemma
+\ref{isathm:parallel-solution-trace-strips} in the SAS+ case: it is equivalent to say that parallel
+SAS+ execution reaches the problem's goal state and that the last element of the corresponding
+trace satisfies the goal state. \<close>
+lemma execute_parallel_plan_sas_plus_reaches_goal_iff_goal_is_last_element_of_trace:
+ "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus I \<psi>
+ \<longleftrightarrow> G \<subseteq>\<^sub>m last (trace_parallel_plan_sas_plus I \<psi>)"
+proof -
+ let ?\<tau> = "trace_parallel_plan_sas_plus I \<psi>"
+ show ?thesis
+ proof (rule iffI)
+ assume "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus I \<psi>"
+ thus "G \<subseteq>\<^sub>m last ?\<tau>"
+ proof (induction \<psi> arbitrary: I)
+ \<comment> \<open> NOTE Base case follows from simplification. \<close>
+ case (Cons ops \<psi>)
+ show ?case
+ proof (cases "are_all_operators_applicable_in I ops
+ \<and> are_all_operator_effects_consistent ops")
+ case True
+ let ?s = "execute_parallel_operator_sas_plus I ops"
+ {
+ have "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus ?s \<psi>"
+ using True Cons.prems
+ by simp
+ hence "G \<subseteq>\<^sub>m last (trace_parallel_plan_sas_plus ?s \<psi>)"
+ using Cons.IH
+ by auto
+ }
+ moreover {
+ have "trace_parallel_plan_sas_plus I (ops # \<psi>)
+ = I # trace_parallel_plan_sas_plus ?s \<psi>"
+ using True
+ by simp
+ moreover have "trace_parallel_plan_sas_plus ?s \<psi> \<noteq> []"
+ using trace_parallel_plan_sas_plus.elims
+ by blast
+ ultimately have "last (trace_parallel_plan_sas_plus I (ops # \<psi>))
+ = last (trace_parallel_plan_sas_plus ?s \<psi>)"
+ using last_ConsR
+ by simp
+ }
+ ultimately show ?thesis
+ by argo
+ next
+ case False
+ then have "G \<subseteq>\<^sub>m I"
+ using Cons.prems
+ by force
+ thus ?thesis
+ using False
+ by force
+ qed
+ qed force
+ next
+ assume "G \<subseteq>\<^sub>m last ?\<tau>"
+ thus "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus I \<psi>"
+ proof (induction \<psi> arbitrary: I)
+ case (Cons ops \<psi>)
+ thus ?case
+ proof (cases "are_all_operators_applicable_in I ops
+ \<and> are_all_operator_effects_consistent ops")
+ case True
+ let ?s = "execute_parallel_operator_sas_plus I ops"
+ {
+ have "trace_parallel_plan_sas_plus I (ops # \<psi>)
+ = I # trace_parallel_plan_sas_plus ?s \<psi>"
+ using True
+ by simp
+ moreover have "trace_parallel_plan_sas_plus ?s \<psi> \<noteq> []"
+ using trace_parallel_plan_sas_plus.elims
+ by blast
+ ultimately have "last (trace_parallel_plan_sas_plus I (ops # \<psi>))
+ = last (trace_parallel_plan_sas_plus ?s \<psi>)"
+ using last_ConsR
+ by simp
+ hence "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus ?s \<psi>"
+ using Cons.IH[of ?s] Cons.prems
+ by argo
+ }
+ moreover have "execute_parallel_plan_sas_plus I (ops # \<psi>)
+ = execute_parallel_plan_sas_plus ?s \<psi>"
+ using True
+ by force
+ ultimately show ?thesis
+ by argo
+ next
+ case False
+ have "G \<subseteq>\<^sub>m I"
+ using Cons.prems False
+ by simp
+ thus ?thesis
+ using False
+ by force
+ qed
+ qed simp
+ qed
+qed
+
+lemma is_parallel_solution_for_problem_plan_operator_set:
+ (* TODO refactor move + make visible? *)
+ fixes \<Psi> :: "('v, 'd) sas_plus_problem"
+ assumes "is_parallel_solution_for_problem \<Psi> \<psi>"
+ shows "\<forall>ops \<in> set \<psi>. \<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using assms
+ unfolding is_parallel_solution_for_problem_def list_all_iff ListMem_iff operators_of_def
+ by presburger
+
+end
+
+
+subsection "Serializable Parallel Plans"
+
+text \<open> Again we want to establish conditions for the serializability of plans. Let
+\<^term>\<open>\<Psi>\<close> be a SAS+ problem instance and let \<^term>\<open>\<psi>\<close> be a serial solution. We obtain the following
+two important results, namely that
+\begin{enumerate}
+ \item the embedding \<^term>\<open>embed \<psi>\<close> of \<^term>\<open>\<psi>\<close> is a parallel solution for \<^term>\<open>\<Psi>\<close>
+(lemma \ref{isathm:serial-sas-plus-embedding}); and conversely that,
+ \item a parallel solution to \<^term>\<open>\<Psi>\<close> that has the form of an embedded serial plan can be
+concatenated to obtain a serial solution (lemma
+\ref{isathm:embedded-serial-solution-flattening-sas-plus}).
+\end{enumerate} \<close>
+
+
+context
+begin
+
+(* TODO refactor *)
+lemma execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus_i:
+ assumes "is_operator_applicable_in s op"
+ "are_operator_effects_consistent op op"
+ shows "s \<then>\<^sub>+ op = execute_parallel_operator_sas_plus s [op]"
+proof -
+ have "are_all_operators_applicable_in s [op]"
+ unfolding are_all_operators_applicable_in_def
+ SAS_Plus_Representation.execute_operator_sas_plus_def
+ is_operator_applicable_in_def SAS_Plus_Representation.is_operator_applicable_in_def
+ list_all_iff
+ using assms(1)
+ by fastforce
+ moreover have "are_all_operator_effects_consistent [op]"
+ unfolding are_all_operator_effects_consistent_def list_all_iff
+ using assms(2)
+ by fastforce
+ ultimately show ?thesis
+ unfolding execute_parallel_operator_sas_plus_def execute_operator_sas_plus_def
+ by simp
+qed
+
+lemma execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus_ii:
+ fixes I :: "('variable, 'domain) state"
+ assumes "\<forall>op \<in> set \<psi>. are_operator_effects_consistent op op"
+ and "G \<subseteq>\<^sub>m execute_serial_plan_sas_plus I \<psi>"
+ shows "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus I (embed \<psi>)"
+ using assms
+proof (induction \<psi> arbitrary: I)
+ case (Cons op \<psi>)
+ show ?case
+ proof (cases "are_all_operators_applicable_in I [op]")
+ case True
+ let ?J = "execute_operator_sas_plus I op"
+ let ?J' = "execute_parallel_operator_sas_plus I [op]"
+ have "SAS_Plus_Representation.is_operator_applicable_in I op"
+ using True
+ unfolding are_all_operators_applicable_in_def list_all_iff
+ by force
+ moreover have "G \<subseteq>\<^sub>m execute_serial_plan_sas_plus ?J \<psi>"
+ using Cons.prems(2) calculation(1)
+ by simp
+ moreover have "are_all_operator_effects_consistent [op]"
+ unfolding are_all_operator_effects_consistent_def list_all_iff Let_def
+ using Cons.prems(1)
+ by simp
+ moreover have "execute_parallel_plan_sas_plus I ([op] # embed \<psi>)
+ = execute_parallel_plan_sas_plus ?J' (embed \<psi>)"
+ using True calculation(3)
+ by simp
+ moreover {
+ have "is_operator_applicable_in I op"
+ "are_operator_effects_consistent op op"
+ using True Cons.prems(1)
+ unfolding are_all_operators_applicable_in_def
+ SAS_Plus_Representation.is_operator_applicable_in_def list_all_iff
+ by fastforce+
+ hence "?J = ?J'"
+ using execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus_i
+ calculation(1)
+ by blast
+ }
+ ultimately show ?thesis
+ using Cons.IH[of ?J] Cons.prems(1)
+ by simp
+ next
+ case False
+ moreover have "\<not>is_operator_applicable_in I op"
+ using calculation
+ unfolding are_all_operators_applicable_in_def
+ SAS_Plus_Representation.is_operator_applicable_in_def list_all_iff
+ by fastforce
+ moreover have "G \<subseteq>\<^sub>m I"
+ using Cons.prems(2) calculation(2)
+ unfolding is_operator_applicable_in_def
+ by simp
+ moreover have "execute_parallel_plan_sas_plus I ([op] # embed \<psi>) = I"
+ using calculation(1)
+ by fastforce
+ ultimately show ?thesis
+ by force
+ qed
+ qed simp
+
+lemma execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus_iii:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "is_serial_solution_for_problem \<Psi> \<psi>"
+ and "op \<in> set \<psi>"
+ shows "are_operator_effects_consistent op op"
+proof -
+ have "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using assms(2) assms(3)
+ unfolding is_serial_solution_for_problem_def Let_def list_all_iff ListMem_iff
+ by fastforce
+ then have "is_valid_operator_sas_plus \<Psi> op"
+ using is_valid_problem_sas_plus_then(2) assms(1, 3)
+ by auto
+ thus ?thesis
+ unfolding are_operator_effects_consistent_def Let_def list_all_iff ListMem_iff
+ using is_valid_operator_sas_plus_then(6)
+ by fast
+qed
+
+lemma execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus_iv:
+ fixes \<Psi> :: "('v, 'd) sas_plus_problem"
+ assumes "\<forall>op \<in> set \<psi>. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ shows "\<forall>ops \<in> set (embed \<psi>). \<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+proof -
+ let ?\<psi>' = "embed \<psi>"
+ have nb: "set ?\<psi>' = { [op] | op. op \<in> set \<psi> }"
+ by (induction \<psi>; force)
+ {
+ fix ops
+ assume "ops \<in> set ?\<psi>'"
+ moreover obtain op where "ops = [op]" and "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using assms(1) nb calculation
+ by blast
+ ultimately have "\<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ by fastforce
+ }
+ thus ?thesis..
+qed
+
+theorem execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "is_serial_solution_for_problem \<Psi> \<psi>"
+ shows "is_parallel_solution_for_problem \<Psi> (embed \<psi>)"
+proof -
+ let ?ops = "sas_plus_problem.operators_of \<Psi>"
+ and ?\<psi>' = "embed \<psi>"
+ {
+ thm execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus_ii[OF]
+ have "(\<Psi>)\<^sub>G\<^sub>+ \<subseteq>\<^sub>m execute_serial_plan_sas_plus ((\<Psi>)\<^sub>I\<^sub>+) \<psi>"
+ using assms(2)
+ unfolding is_serial_solution_for_problem_def Let_def
+ by simp
+ moreover have "\<forall>op \<in> set \<psi>. are_operator_effects_consistent op op"
+ using execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus_iii[OF assms]..
+ ultimately have "(\<Psi>)\<^sub>G\<^sub>+ \<subseteq>\<^sub>m execute_parallel_plan_sas_plus ((\<Psi>)\<^sub>I\<^sub>+) ?\<psi>'"
+ using execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus_ii
+ by blast
+ }
+ moreover {
+ have "\<forall>op \<in> set \<psi>. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using assms(2)
+ unfolding is_serial_solution_for_problem_def Let_def list_all_iff ListMem_iff
+ by fastforce
+ hence "\<forall>ops \<in> set ?\<psi>'. \<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus_iv
+ by blast
+ }
+ ultimately show ?thesis
+ unfolding is_parallel_solution_for_problem_def list_all_iff ListMem_iff Let_def goal_of_def
+ initial_of_def
+ by fastforce
+qed
+
+lemma flattening_lemma_i:
+ fixes \<Psi> :: "('v, 'd) sas_plus_problem"
+ assumes "\<forall>ops \<in> set \<pi>. \<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ shows "\<forall>op \<in> set (concat \<pi>). op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+proof -
+ {
+ fix op
+ assume "op \<in> set (concat \<pi>)"
+ moreover have "op \<in> (\<Union>ops \<in> set \<pi>. set ops)"
+ using calculation
+ unfolding set_concat.
+ then obtain ops where "ops \<in> set \<pi>" and "op \<in> set ops"
+ using UN_iff
+ by blast
+ ultimately have "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using assms
+ by blast
+ }
+ thus ?thesis..
+qed
+
+lemma flattening_lemma_ii:
+ fixes I :: "('variable, 'domain) state"
+ assumes "\<forall>ops \<in> set \<psi>. \<exists>op. ops = [op] \<and> is_valid_operator_sas_plus \<Psi> op "
+ and "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus I \<psi>"
+ shows "G \<subseteq>\<^sub>m execute_serial_plan_sas_plus I (concat \<psi>)"
+proof -
+ show ?thesis
+ using assms
+ proof (induction \<psi> arbitrary: I)
+ case (Cons ops \<psi>)
+ obtain op where ops_is: "ops = [op]" and is_valid_op: "is_valid_operator_sas_plus \<Psi> op"
+ using Cons.prems(1)
+ by auto
+ then show ?case
+ proof (cases "are_all_operators_applicable_in I ops")
+ case True
+ let ?J = "execute_parallel_operator_sas_plus I [op]"
+ and ?J' = "execute_operator_sas_plus I op"
+ have nb\<^sub>1: "is_operator_applicable_in I op"
+ using True ops_is
+ unfolding are_all_operators_applicable_in_def is_operator_applicable_in_def
+ list_all_iff
+ by force
+ have nb\<^sub>2: "are_operator_effects_consistent op op"
+ unfolding are_operator_effects_consistent_def list_all_iff Let_def
+ using is_valid_operator_sas_plus_then(6)[OF is_valid_op]
+ by blast
+ have "are_all_operator_effects_consistent ops"
+ using ops_is
+ unfolding are_all_operator_effects_consistent_def list_all_iff
+ using nb\<^sub>2
+ by force
+ moreover have "G \<subseteq>\<^sub>m execute_parallel_plan_sas_plus ?J \<psi>"
+ using Cons.prems(2) True calculation ops_is
+ by fastforce
+ moreover have "execute_serial_plan_sas_plus I (concat (ops # \<psi>))
+ = execute_serial_plan_sas_plus ?J' (concat \<psi>)"
+ using ops_is nb\<^sub>1 is_operator_applicable_in_def
+ by simp
+ moreover have "?J = ?J'"
+ using execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus_i[OF nb\<^sub>1 nb\<^sub>2]
+ by simp
+ ultimately show ?thesis
+ using Cons.IH[of ?J] Cons.prems(1)
+ by force
+ next
+ case False
+ moreover have "G \<subseteq>\<^sub>m I"
+ using Cons.prems(2) calculation
+ by fastforce
+ moreover {
+ have "\<not>is_operator_applicable_in I op"
+ using False ops_is
+ unfolding are_all_operators_applicable_in_def
+ is_operator_applicable_in_def list_all_iff
+ by force
+ moreover have "execute_serial_plan_sas_plus I (concat (ops # \<psi>))
+ = execute_serial_plan_sas_plus I (op # concat \<psi>)"
+ using ops_is
+ by force
+ ultimately have "execute_serial_plan_sas_plus I (concat (ops # \<psi>)) = I"
+ using False
+ unfolding is_operator_applicable_in_def
+ by fastforce
+ }
+ ultimately show ?thesis
+ by argo
+ qed
+ qed force
+qed
+
+lemma flattening_lemma:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "\<forall>ops \<in> set \<psi>. \<exists>op. ops = [op]"
+ and "is_parallel_solution_for_problem \<Psi> \<psi>"
+ shows "is_serial_solution_for_problem \<Psi> (concat \<psi>)"
+proof -
+ let ?\<psi>' = "concat \<psi>"
+ {
+ have "\<forall>ops \<in> set \<psi>. \<forall>op \<in> set ops. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using assms(3)
+ unfolding is_parallel_solution_for_problem_def list_all_iff ListMem_iff
+ by force
+ hence "\<forall>op \<in> set ?\<psi>'. op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using flattening_lemma_i
+ by blast
+ }
+ moreover {
+ {
+ fix ops
+ assume "ops \<in> set \<psi>"
+ moreover obtain op where "ops = [op]"
+ using assms(2) calculation
+ by blast
+ moreover have "op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+)"
+ using assms(3) calculation
+ unfolding is_parallel_solution_for_problem_def list_all_iff ListMem_iff
+ by force
+ moreover have "is_valid_operator_sas_plus \<Psi> op"
+ using assms(1) calculation(3)
+ unfolding is_valid_problem_sas_plus_def Let_def list_all_iff
+ ListMem_iff
+ by simp
+ ultimately have "\<exists>op. ops = [op] \<and> is_valid_operator_sas_plus \<Psi> op"
+ by blast
+ }
+ moreover have "(\<Psi>)\<^sub>G\<^sub>+ \<subseteq>\<^sub>m execute_parallel_plan_sas_plus ((\<Psi>)\<^sub>I\<^sub>+) \<psi>"
+ using assms(3)
+ unfolding is_parallel_solution_for_problem_def
+ by fastforce
+ ultimately have "(\<Psi>)\<^sub>G\<^sub>+ \<subseteq>\<^sub>m execute_serial_plan_sas_plus ((\<Psi>)\<^sub>I\<^sub>+) ?\<psi>'"
+ using flattening_lemma_ii
+ by blast
+ }
+ ultimately show "is_serial_solution_for_problem \<Psi> ?\<psi>'"
+ unfolding is_serial_solution_for_problem_def list_all_iff ListMem_iff
+ by fastforce
+qed
+end
+
+subsection "Auxiliary lemmata on SAS+"
+
+
+context
+begin
+
+\<comment> \<open> Relate the locale definition \<open>range_of\<close> with its corresponding implementation for valid
+operators and given an effect \<open>(v, a)\<close>. \<close>
+lemma is_valid_operator_sas_plus_then_range_of_sas_plus_op_is_set_range_of_op:
+ assumes "is_valid_operator_sas_plus \<Psi> op"
+ and "(v, a) \<in> set (precondition_of op) \<or> (v, a) \<in> set (effect_of op)"
+ shows "(\<R>\<^sub>+ \<Psi> v) = set (the (sas_plus_problem.range_of \<Psi> v))"
+proof -
+ consider (A) "(v, a) \<in> set (precondition_of op)"
+ | (B) "(v, a) \<in> set (effect_of op)"
+ using assms(2)..
+ thus ?thesis
+ proof (cases)
+ case A
+ then have "(\<R>\<^sub>+ \<Psi> v) \<noteq> {}" and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using assms
+ unfolding range_of_def
+ using is_valid_operator_sas_plus_then(2)
+ by fast+
+ thus ?thesis
+ unfolding range_of'_def option.case_eq_if
+ by auto
+ next
+ case B
+ then have "(\<R>\<^sub>+ \<Psi> v) \<noteq> {}" and "a \<in> \<R>\<^sub>+ \<Psi> v"
+ using assms
+ unfolding range_of_def
+ using is_valid_operator_sas_plus_then(4)
+ by fast+
+ thus ?thesis
+ unfolding range_of'_def option.case_eq_if
+ by auto
+ qed
+qed
+
+lemma set_the_range_of_is_range_of_sas_plus_if:
+ fixes \<Psi> :: "('v, 'd) sas_plus_problem"
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ "v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ shows "set (the (sas_plus_problem.range_of \<Psi> v)) = \<R>\<^sub>+ \<Psi> v"
+proof-
+ have "v \<in> set((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ using assms(2)
+ unfolding variables_of_def.
+ moreover have "(\<R>\<^sub>+ \<Psi> v) \<noteq> {}"
+ using assms(1) calculation is_valid_problem_sas_plus_then(1)
+ by blast
+ moreover have "sas_plus_problem.range_of \<Psi> v \<noteq> None"
+ and "sas_plus_problem.range_of \<Psi> v \<noteq> Some []"
+ using calculation(2) range_of_not_empty
+ unfolding range_of_def
+ by fast+
+ ultimately show ?thesis
+ unfolding option.case_eq_if range_of'_def
+ by force
+qed
+
+lemma sublocale_sas_plus_finite_domain_representation_ii:
+ fixes \<Psi>::"('v,'d) sas_plus_problem"
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "\<forall>v \<in> set ((\<Psi>)\<^sub>\<V>\<^sub>+). (\<R>\<^sub>+ \<Psi> v) \<noteq> {}"
+ and "\<forall>op \<in> set ((\<Psi>)\<^sub>\<O>\<^sub>+). is_valid_operator_sas_plus \<Psi> op"
+ and "dom ((\<Psi>)\<^sub>I\<^sub>+) = set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom ((\<Psi>)\<^sub>I\<^sub>+). the (((\<Psi>)\<^sub>I\<^sub>+) v) \<in> \<R>\<^sub>+ \<Psi> v"
+ and "dom ((\<Psi>)\<^sub>G\<^sub>+) \<subseteq> set ((\<Psi>)\<^sub>\<V>\<^sub>+)"
+ and "\<forall>v \<in> dom ((\<Psi>)\<^sub>G\<^sub>+). the (((\<Psi>)\<^sub>G\<^sub>+) v) \<in> \<R>\<^sub>+ \<Psi> v"
+ using is_valid_problem_sas_plus_then[OF assms]
+ by auto
+
+end
+
+end
\ No newline at end of file
diff --git a/thys/Verified_SAT_Based_AI_Planning/SAT_Plan_Base.thy b/thys/Verified_SAT_Based_AI_Planning/SAT_Plan_Base.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/SAT_Plan_Base.thy
@@ -0,0 +1,5449 @@
+(*
+ Author: Mohammad Abdulaziz, Fred Kurz
+*)
+theory SAT_Plan_Base
+ imports "List-Index.List_Index"
+ "Propositional_Proof_Systems.Formulas"
+ "STRIPS_Semantics"
+ "Map_Supplement" "List_Supplement"
+ "CNF_Semantics_Supplement" "CNF_Supplement"
+begin
+
+\<comment> \<open> Hide constant and notation for \isaname{Orderings.bot_class.bot} (\<open>\<bottom>\<close>) to prevent warnings. \<close>
+hide_const (open) Orderings.bot_class.bot
+no_notation Orderings.bot_class.bot ("\<bottom>")
+
+\<comment> \<open> Hide constant and notation for \isaname{Transitive_Closure.trancl} (\<open>(_\<^sup>+)\<close>) to prevent
+warnings. \<close>
+hide_const (open) Transitive_Closure.trancl
+no_notation Transitive_Closure.trancl ("(_\<^sup>+)" [1000] 999)
+
+\<comment> \<open> Hide constant and notation for \isaname{Relation.converse} (\<open>(_\<^sup>+)\<close>) to prevent
+warnings. \<close>
+hide_const (open) Relation.converse
+no_notation Relation.converse ("(_\<inverse>)" [1000] 999)
+
+section "The Basic SATPlan Encoding"
+text \<open> We now move on to the formalization of the basic SATPlan encoding (see
+\autoref{def:basic-sat-plan-encoding-strips-problem}).
+
+The two major results that we will obtain here are the soundness and completeness result outlined
+in \autoref{thm:soundness-and-completeness-satplan-base} in
+\autoref{sub:soundness-completeness-satplan}.
+
+Let in the following \<open>\<Phi> \<equiv> encode_to_sat \<Pi> t\<close> denote the SATPlan encoding for a STRIPS problem \<open>\<Pi>\<close>
+and makespan \<open>t\<close>. Let \<^term>\<open>k < t\<close> and \<open>I \<equiv> (\<Pi>)\<^sub>I\<close> be the initial state of \<open>\<Pi>\<close>, \<open>G \<equiv> (\<Pi>)\<^sub>G\<close> be
+its goal state, \<open>\<V> \<equiv> (\<Pi>)\<^sub>\<V>\<close> its variable set, and \<open>\<O> \<equiv> (\<Pi>)\<^sub>\<O>\<close> its operator set. \<close>
+subsection "Encoding Function Definitions"
+text \<open> Since the SATPlan encoding uses propositional variables for both operators and state
+variables of the problem as well as time points, we define a datatype using separate constructors
+---\<^term>\<open>State k n\<close> for state variables resp. \<^term>\<open>Operator k n\<close> for operator activation---to
+facilitate case distinction.
+The natural number values store the time index resp. the indexes of the variable or operator
+within their lists in the problem representation.
+% TODO Note on why formulas are used instead of CNF (simple representation and good basis; e.g.
+% export to cnf lists using CNF_Formulas.cnf_lists) \<close>
+
+datatype sat_plan_variable =
+ State nat nat
+ | Operator nat nat
+
+text \<open> A SATPlan formula is a regular propositional formula over SATPlan variables. We add a type
+synonym to improve readability. \<close>
+
+type_synonym sat_plan_formula = "sat_plan_variable formula"
+
+text \<open> We now continue with the concrete definitions used in the implementation of the SATPlan
+encoding. State variables are encoded as literals over SATPlan variables using the \<open>State\<close>
+constructor of \isaname{sat_plan_variable}. \<close>
+
+definition encode_state_variable
+ :: "nat \<Rightarrow> nat \<Rightarrow> bool option \<Rightarrow> sat_plan_variable formula"
+ where "encode_state_variable t k v \<equiv> case v of
+ Some True \<Rightarrow> Atom (State t k)
+ | Some False \<Rightarrow> \<^bold>\<not> (Atom (State t k))"
+
+text \<open> The initial state encoding (definition \ref{isadef:initial-state-encoding}) is a conjunction
+of state variable encodings \<^term>\<open>A \<equiv> encode_state_variable 0 n b\<close> with \<open>n \<equiv> index vs v\<close> and
+\<^term>\<open>b \<equiv> I v = Some True\<close> for all \<^term>\<open>v \<in> \<V>\<close>. As we can see below, the same function but
+substituting the initial state with the goal state and zero with the makespan \<^term>\<open>t\<close> produces the
+goal state encoding (\ref{isadef:goal-state-encoding}).
+Note that both functions construct a conjunction of clauses \<open>A \<^bold>\<or> \<bottom>\<close> for which it
+is easy to show that we can normalize to conjunctive normal form (CNF). \<close>
+
+definition encode_initial_state
+ :: "'variable strips_problem \<Rightarrow> sat_plan_variable formula" ("\<Phi>\<^sub>I _" 99)
+ where "encode_initial_state \<Pi>
+ \<equiv> let I = initial_of \<Pi>
+ ; vs = variables_of \<Pi>
+ in \<^bold>\<And>(map (\<lambda>v. encode_state_variable 0 (index vs v) (I v) \<^bold>\<or> \<bottom>)
+ (filter (\<lambda>v. I v \<noteq> None) vs))"
+
+definition encode_goal_state
+ :: "'variable strips_problem \<Rightarrow> nat \<Rightarrow> sat_plan_variable formula" ("\<Phi>\<^sub>G _" 99)
+ where "encode_goal_state \<Pi> t
+ \<equiv> let
+ vs = variables_of \<Pi>
+ ; G = goal_of \<Pi>
+ in \<^bold>\<And>(map (\<lambda>v. encode_state_variable t (index vs v) (G v) \<^bold>\<or> \<bottom>)
+ (filter (\<lambda>v. G v \<noteq> None) vs))"
+
+text \<open> Operator preconditions are encoded using activation-implies-precondition formulation as
+mentioned in \autoref{subsub:basic-sat-plan-encoding}: i.e. for each
+operator \<^term>\<open>op \<in> \<O>\<close> and \<^term>\<open>p \<in> set (precondition_of op)\<close> we have to encode
+ @{text[display, indent=4] "Atom (Operator k (index ops op)) \<^bold>\<rightarrow> Atom (State k (index vs v))"}
+We use the equivalent disjunction in the formalization to simplify conversion to CNF.
+
+\<close>
+
+definition encode_operator_precondition
+ :: "'variable strips_problem
+ \<Rightarrow> nat
+ \<Rightarrow> 'variable strips_operator
+ \<Rightarrow> sat_plan_variable formula"
+ where "encode_operator_precondition \<Pi> t op \<equiv> let
+ vs = variables_of \<Pi>
+ ; ops = operators_of \<Pi>
+ in \<^bold>\<And>(map (\<lambda>v.
+ \<^bold>\<not> (Atom (Operator t (index ops op))) \<^bold>\<or> Atom (State t (index vs v)))
+ (precondition_of op))"
+
+definition encode_all_operator_preconditions
+ :: "'variable strips_problem
+ \<Rightarrow> 'variable strips_operator list
+ \<Rightarrow> nat
+ \<Rightarrow> sat_plan_variable formula"
+ where "encode_all_operator_preconditions \<Pi> ops t \<equiv> let
+ l = List.product [0..<t] ops
+ in foldr (\<^bold>\<and>) (map (\<lambda>(t, op). encode_operator_precondition \<Pi> t op) l) (\<^bold>\<not>\<bottom>)"
+
+text \<open> Analogously to the operator precondition, add and delete effects of operators have to be
+implied by operator activation. That being said, we have to encode both positive and negative
+effects and the effect must be active at the following time point: i.e.
+ @{text[display, indent=4] "Atom (Operator k m) \<^bold>\<rightarrow> Atom (State (Suc k) n)"}
+for add effects respectively
+ @{text[display, indent=4] "Atom (Operator k m) \<^bold>\<rightarrow> \<^bold>\<not>Atom (State (Suc k) n)"}
+for delete effects. We again encode the implications as their equivalent disjunctions in
+definition \ref{isadef:operator-effect-encoding}. \<close>
+
+definition encode_operator_effect
+ :: "'variable strips_problem
+ \<Rightarrow> nat
+ \<Rightarrow> 'variable strips_operator
+ \<Rightarrow> sat_plan_variable formula"
+ where "encode_operator_effect \<Pi> t op
+ \<equiv> let
+ vs = variables_of \<Pi>
+ ; ops = operators_of \<Pi>
+ in \<^bold>\<And>(map (\<lambda>v.
+ \<^bold>\<not>(Atom (Operator t (index ops op)))
+ \<^bold>\<or> Atom (State (Suc t) (index vs v)))
+ (add_effects_of op)
+ @ map (\<lambda>v.
+ \<^bold>\<not>(Atom (Operator t (index ops op)))
+ \<^bold>\<or> \<^bold>\<not> (Atom (State (Suc t) (index vs v))))
+ (delete_effects_of op))"
+
+definition encode_all_operator_effects
+ :: "'variable strips_problem
+ \<Rightarrow> 'variable strips_operator list
+ \<Rightarrow> nat
+ \<Rightarrow> sat_plan_variable formula"
+ where "encode_all_operator_effects \<Pi> ops t
+ \<equiv> let l = List.product [0..<t] ops
+ in foldr (\<^bold>\<and>) (map (\<lambda>(t, op). encode_operator_effect \<Pi> t op) l) (\<^bold>\<not>\<bottom>)"
+
+definition encode_operators
+ :: "'variable strips_problem \<Rightarrow> nat \<Rightarrow> sat_plan_variable formula"
+ where "encode_operators \<Pi> t
+ \<equiv> let ops = operators_of \<Pi>
+ in encode_all_operator_preconditions \<Pi> ops t \<^bold>\<and> encode_all_operator_effects \<Pi> ops t"
+
+text \<open>
+
+Definitions \ref{isadef:negative-transition-frame-axiom-encoding} and
+\ref{isadef:positive-transition-frame-axiom-encoding} similarly encode the negative resp. positive
+transition frame axioms as disjunctions. \<close>
+
+definition encode_negative_transition_frame_axiom
+ :: "'variable strips_problem
+ \<Rightarrow> nat
+ \<Rightarrow> 'variable
+ \<Rightarrow> sat_plan_variable formula"
+ where "encode_negative_transition_frame_axiom \<Pi> t v
+ \<equiv> let vs = variables_of \<Pi>
+ ; ops = operators_of \<Pi>
+ ; deleting_operators = filter (\<lambda>op. ListMem v (delete_effects_of op)) ops
+ in \<^bold>\<not>(Atom (State t (index vs v)))
+ \<^bold>\<or> (Atom (State (Suc t) (index vs v))
+ \<^bold>\<or> \<^bold>\<Or> (map (\<lambda>op. Atom (Operator t (index ops op))) deleting_operators))"
+
+definition encode_positive_transition_frame_axiom
+ :: "'variable strips_problem
+ \<Rightarrow> nat
+ \<Rightarrow> 'variable
+ \<Rightarrow> sat_plan_variable formula"
+ where "encode_positive_transition_frame_axiom \<Pi> t v
+ \<equiv> let vs = variables_of \<Pi>
+ ; ops = operators_of \<Pi>
+ ; adding_operators = filter (\<lambda>op. ListMem v (add_effects_of op)) ops
+ in (Atom (State t (index vs v))
+ \<^bold>\<or> (\<^bold>\<not>(Atom (State (Suc t) (index vs v)))
+ \<^bold>\<or> \<^bold>\<Or>(map (\<lambda>op. Atom (Operator t (index ops op))) adding_operators)))"
+
+definition encode_all_frame_axioms
+ :: "'variable strips_problem \<Rightarrow> nat \<Rightarrow> sat_plan_variable formula"
+ where "encode_all_frame_axioms \<Pi> t
+ \<equiv> let l = List.product [0..<t] (variables_of \<Pi>)
+ in \<^bold>\<And>(map (\<lambda>(k, v). encode_negative_transition_frame_axiom \<Pi> k v) l
+ @ map (\<lambda>(k, v). encode_positive_transition_frame_axiom \<Pi> k v) l)"
+
+text \<open> Finally, the basic SATPlan encoding is the
+conjunction of the initial state, goal state, operator and frame axiom encoding for all time steps.
+The functions \isaname{encode_operators} and \isaname{encode_all_frame_axioms}\footnote{Not shown.}
+take care of mapping the operator precondition, effect and frame axiom encoding over all possible
+combinations of time point and operators resp. time points, variables, and operators. \<close>
+
+definition encode_problem ("\<Phi> _ _" 99)
+ where "encode_problem \<Pi> t
+ \<equiv> encode_initial_state \<Pi>
+ \<^bold>\<and> (encode_operators \<Pi> t
+ \<^bold>\<and> (encode_all_frame_axioms \<Pi> t
+ \<^bold>\<and> (encode_goal_state \<Pi> t)))"
+
+subsection "Decoding Function Definitions"
+text \<open> Decoding plans from a valuation \<^term>\<open>\<A>\<close> of a
+SATPlan encoding entails extracting all activated operators for all
+time points except the last one. We implement this by mapping over all \<^term>\<open>k < t\<close>
+ and extracting activated operators---i.e. operators for which the model valuates the respective
+operator encoding at time \<^term>\<open>k\<close> to true---into a parallel operator (see definition
+\ref{isadef:satplan-plan-decoding}).
+\footnote{This is handled by function \texttt{decode\_plan'} (not shown).} \<close>
+
+\<comment> \<open> Note that due to the implementation based on lists, we have to address the problem of duplicate
+operator declarations in the operator list of the problem. Since \<^term>\<open>index op = index op'\<close> for equal
+operators, the parallel operator obtained from \isaname{decode_plan'} will contain
+duplicates in case the problem's operator list does. We therefore remove duplicates first using
+\<^term>\<open>remdups ops\<close> and then filter out activated operators. \<close>
+definition decode_plan'
+ :: "'variable strips_problem
+ \<Rightarrow> sat_plan_variable valuation
+ \<Rightarrow> nat
+ \<Rightarrow> 'variable strips_operator list"
+ where "decode_plan' \<Pi> \<A> i
+ \<equiv> let ops = operators_of \<Pi>
+ ; vs = map (\<lambda>op. Operator i (index ops op)) (remdups ops)
+ in map (\<lambda>v. case v of Operator _ k \<Rightarrow> ops ! k) (filter \<A> vs)"
+
+
+\<comment> \<open> We decode maps over range \<open>0, \<dots>, t - 1\<close> because the last operator takes effect in \<^term>\<open>t\<close> and
+must therefore have been applied in step \<^term>\<open>t - 1\<close>. \<close>
+
+definition decode_plan
+ :: "'variable strips_problem
+ \<Rightarrow> sat_plan_variable valuation
+ \<Rightarrow> nat
+ \<Rightarrow> 'variable strips_parallel_plan" ("\<Phi>\<inverse> _ _ _" 99)
+ where "decode_plan \<Pi> \<A> t \<equiv> map (decode_plan' \<Pi> \<A>) [0..<t]"
+
+text \<open> Similarly to the operator decoding, we can decode a state at time \<^term>\<open>k\<close> from a valuation
+of of the SATPlan encoding \<^term>\<open>\<A>\<close> by constructing a map from list of assignments
+\<^term>\<open>(v, \<A> (State k (index vs v)))\<close> for all \<^term>\<open>v \<in> \<V>\<close>. \<close>
+
+definition decode_state_at
+ :: "'variable strips_problem
+ \<Rightarrow> sat_plan_variable valuation
+ \<Rightarrow> nat
+ \<Rightarrow> 'variable strips_state" ("\<Phi>\<^sub>S\<inverse> _ _ _" 99)
+ where "decode_state_at \<Pi> \<A> k
+ \<equiv> let
+ vs = variables_of \<Pi>
+ ; state_encoding_to_assignment = \<lambda>v. (v, \<A> (State k (index vs v)))
+ in map_of (map state_encoding_to_assignment vs)"
+
+text \<open> We continue by setting up the \isaname{sat_plan} context for the proofs of soundness and
+completeness. \<close>
+
+definition encode_transitions ::"'variable strips_problem \<Rightarrow> nat \<Rightarrow> sat_plan_variable formula" ("\<Phi>\<^sub>T _ _" 99) where
+ "encode_transitions \<Pi> t
+ \<equiv> SAT_Plan_Base.encode_operators \<Pi> t \<^bold>\<and>
+ SAT_Plan_Base.encode_all_frame_axioms \<Pi> t"
+
+\<comment> \<open> Immediately proof the sublocale proposition for strips in order to gain access to definitions
+and lemmas. \<close>
+
+\<comment> \<open> Setup simp rules. \<close>
+lemma [simp]:
+ "encode_transitions \<Pi> t
+ = SAT_Plan_Base.encode_operators \<Pi> t \<^bold>\<and>
+ SAT_Plan_Base.encode_all_frame_axioms \<Pi> t"
+ unfolding encode_problem_def encode_initial_state_def encode_transitions_def
+ encode_goal_state_def decode_plan_def decode_state_at_def
+ by simp+
+
+context
+begin
+
+lemma encode_state_variable_is_lit_plus_if:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "v \<in> dom s"
+ shows "is_lit_plus (encode_state_variable k (index (strips_problem.variables_of \<Pi>) v) (s v))"
+proof -
+ have "s v \<noteq> None"
+ using is_valid_problem_strips_initial_of_dom assms(2)
+ by blast
+ then consider (s_of_v_is_some_true) "s v = Some True"
+ | (s_of_v_is_some_false) "s v = Some False"
+ by fastforce
+ thus ?thesis
+ unfolding encode_state_variable_def
+ by (cases, simp+)
+qed
+
+lemma is_cnf_encode_initial_state:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "is_cnf (\<Phi>\<^sub>I \<Pi>)"
+proof -
+ let ?I = "(\<Pi>)\<^sub>I"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?l = "map (\<lambda>v. encode_state_variable 0 (index ?vs v) (?I v) \<^bold>\<or> \<bottom>)
+ (filter (\<lambda>v. ?I v \<noteq> None) ?vs)"
+ {
+ fix C
+ assume c_in_set_l:"C \<in> set ?l"
+ have "set ?l = (\<lambda>v. encode_state_variable 0 (index ?vs v) (?I v) \<^bold>\<or> \<bottom>) `
+ set (filter (\<lambda>v. ?I v \<noteq> None) ?vs)"
+ using set_map[of "\<lambda>v. encode_state_variable 0 (index ?vs v) (?I v) \<^bold>\<or> \<bottom>"
+ "filter (\<lambda>v. ?I v \<noteq> None) ?vs"]
+ by blast
+ then have "set ?l = (\<lambda>v. encode_state_variable 0 (index ?vs v) (?I v) \<^bold>\<or> \<bottom>) `
+ {v \<in> set ?vs. ?I v \<noteq> None}"
+ using set_filter[of "\<lambda>v. ?I v \<noteq> None" ?vs]
+ by argo
+ then obtain v
+ where c_is: "C = encode_state_variable 0 (index ?vs v) (?I v) \<^bold>\<or> \<bottom>"
+ and v_in_set_vs: "v \<in> set ?vs"
+ and I_of_v_is_not_None: "?I v \<noteq> None"
+ using c_in_set_l
+ by auto
+ (* TODO refactor. *)
+ {
+ have "v \<in> dom ?I"
+ using I_of_v_is_not_None
+ by blast
+ moreover have "is_lit_plus (encode_state_variable 0 (index ?vs v) (?I v))"
+ using encode_state_variable_is_lit_plus_if[OF _ calculation] assms(1)
+ by blast
+ moreover have "is_lit_plus \<bottom>"
+ by simp
+ ultimately have "is_disj C"
+ using c_is
+ by force
+ }
+ hence "is_cnf C"
+ unfolding encode_state_variable_def
+ using c_is
+ by fastforce
+ }
+ thus ?thesis
+ unfolding encode_initial_state_def SAT_Plan_Base.encode_initial_state_def Let_def initial_of_def
+ using is_cnf_BigAnd[of ?l]
+ by (smt is_cnf_BigAnd)
+qed
+
+lemma encode_goal_state_is_cnf:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "is_cnf (encode_goal_state \<Pi> t)"
+proof -
+ let ?I = "(\<Pi>)\<^sub>I"
+ and ?G = "(\<Pi>)\<^sub>G"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?l = "map (\<lambda>v. encode_state_variable t (index ?vs v) (?G v) \<^bold>\<or> \<bottom>)
+ (filter (\<lambda>v. ?G v \<noteq> None) ?vs)"
+ {
+ fix C
+ assume "C \<in> set ?l"
+ (* TODO refactor (lemma \<open>encode_goal_state_is_cnf_i\<close>) *)
+ moreover {
+ have "set ?l = (\<lambda>v. encode_state_variable t (index ?vs v) (?G v) \<^bold>\<or> \<bottom>)
+ ` set (filter (\<lambda>v. ?G v \<noteq> None) ?vs)"
+ unfolding set_map
+ by blast
+ then have "set ?l = { encode_state_variable t (index ?vs v) (?G v) \<^bold>\<or> \<bottom>
+ | v. v \<in> set ?vs \<and> ?G v \<noteq> None }"
+ by auto
+ }
+ moreover obtain v where C_is: "C = encode_state_variable t (index ?vs v) (?G v) \<^bold>\<or> \<bottom> "
+ and "v \<in> set ?vs"
+ and G_of_v_is_not_None: "?G v \<noteq> None"
+ using calculation(1)
+ by auto
+ (* TODO refactor. *)
+ moreover {
+ have "v \<in> dom ?G"
+ using G_of_v_is_not_None
+ by blast
+ moreover have "is_lit_plus (encode_state_variable t (index ?vs v) (?G v))"
+ using assms(1) calculation
+ by (simp add: encode_state_variable_is_lit_plus_if)
+ moreover have "is_lit_plus \<bottom>"
+ by simp
+ ultimately have "is_disj C"
+ unfolding C_is
+ by force
+ }
+ ultimately have "is_cnf C"
+ by simp
+ }
+ thus ?thesis
+ unfolding encode_goal_state_def SAT_Plan_Base.encode_goal_state_def Let_def
+ using is_cnf_BigAnd[of ?l]
+ by simp
+qed
+
+private lemma encode_operator_precondition_is_cnf:
+ "is_cnf (encode_operator_precondition \<Pi> k op)"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ let ?l = "map (\<lambda>v. \<^bold>\<not> (Atom (Operator k (index ?ops op))) \<^bold>\<or> Atom (State k (index ?vs v)))
+ (precondition_of op)"
+ {
+ have "set ?l = (\<lambda>v. \<^bold>\<not>(Atom (Operator k (index ?ops op))) \<^bold>\<or> Atom (State k (index ?vs v)))
+ ` set (precondition_of op)"
+ using set_map
+ by force
+ then have "set ?l = { \<^bold>\<not>(Atom (Operator k (index ?ops op))) \<^bold>\<or> Atom (State k (index ?vs v))
+ | v. v \<in> set (precondition_of op) }"
+ using setcompr_eq_image[of
+ "\<lambda>v. \<^bold>\<not>(Atom (Operator k (index ?ops op))) \<^bold>\<or> Atom (State k (index ?vs v))"
+ "\<lambda>v. v \<in> set (precondition_of op)"]
+ by simp
+ } note set_l_is = this
+ {
+ fix C
+ assume "C \<in> set ?l"
+ then obtain v
+ where "v \<in> set (precondition_of op)"
+ and "C = \<^bold>\<not>(Atom (Operator k (index ?ops op))) \<^bold>\<or> Atom (State k (index ?vs v))"
+ using set_l_is
+ by blast
+ hence "is_cnf C"
+ by simp
+ }
+ thus ?thesis
+ unfolding encode_operator_precondition_def
+ using is_cnf_BigAnd[of ?l]
+ by meson
+qed
+
+private lemma set_map_operator_precondition[simp]:
+ "set (map (\<lambda>(k, op). encode_operator_precondition \<Pi> k op) (List.product [0..<t] ops))
+ = { encode_operator_precondition \<Pi> k op | k op. (k, op) \<in> ({0..<t} \<times> set ops) }"
+proof -
+ let ?l' = "List.product [0..<t] ops"
+ let ?fs = "map (\<lambda>(k, op). encode_operator_precondition \<Pi> k op) ?l'"
+ have set_l'_is: "set ?l' = {0..<t} \<times> set ops"
+ by simp
+ moreover {
+ have "set ?fs = (\<lambda>(k, op). encode_operator_precondition \<Pi> k op)
+ ` ({0..<t} \<times> set ops)"
+ using set_map set_l'_is
+ by simp
+ also have "\<dots> = { encode_operator_precondition \<Pi> k op | k op. (k, op) \<in> {0..<t} \<times> set ops}"
+ using setcompr_eq_image
+ by fast
+ finally have "set ?fs = { encode_operator_precondition \<Pi> k op
+ | k op. (k, op) \<in> ({0..<t} \<times> set ops) }"
+ by blast
+ }
+ thus ?thesis
+ by blast
+qed
+
+private lemma is_cnf_encode_all_operator_preconditions:
+ "is_cnf (encode_all_operator_preconditions \<Pi> (strips_problem.operators_of \<Pi>) t)"
+proof -
+ let ?l' = "List.product [0..<t] (strips_problem.operators_of \<Pi>)"
+ let ?fs = "map (\<lambda>(k, op). encode_operator_precondition \<Pi> k op) ?l'"
+ have "\<forall>f \<in> set ?fs. is_cnf f"
+ using encode_operator_precondition_is_cnf
+ by fastforce
+ thus ?thesis
+ unfolding encode_all_operator_preconditions_def
+ using is_cnf_foldr_and_if[of ?fs]
+ by presburger
+qed
+
+(* TODO refactor Appendix *)
+private lemma set_map_or[simp]:
+ "set (map (\<lambda>v. A v \<^bold>\<or> B v) vs) = { A v \<^bold>\<or> B v | v. v \<in> set vs }"
+proof -
+ let ?l = "map (\<lambda>v. A v \<^bold>\<or> B v) vs"
+ have "set ?l = (\<lambda>v. A v \<^bold>\<or> B v) ` set vs"
+ using set_map
+ by force
+ thus ?thesis
+ using setcompr_eq_image
+ by auto
+qed
+
+private lemma encode_operator_effects_is_cnf_i:
+ "is_cnf (\<^bold>\<And>(map (\<lambda>v. (\<^bold>\<not> (Atom (Operator t (index (strips_problem.operators_of \<Pi>) op))))
+ \<^bold>\<or> Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))) (add_effects_of op)))"
+proof -
+ let ?fs = "map (\<lambda>v. \<^bold>\<not> (Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ \<^bold>\<or> Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))) (add_effects_of op)"
+ {
+ fix C
+ assume "C \<in> set ?fs"
+ then obtain v
+ where "v \<in> set (add_effects_of op)"
+ and "C = \<^bold>\<not>(Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ \<^bold>\<or> Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))"
+ by auto
+ hence "is_cnf C"
+ by fastforce
+ }
+ thus ?thesis
+ using is_cnf_BigAnd
+ by blast
+qed
+
+private lemma encode_operator_effects_is_cnf_ii:
+ "is_cnf (\<^bold>\<And>(map (\<lambda>v. \<^bold>\<not>(Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ \<^bold>\<or> \<^bold>\<not>(Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v)))) (delete_effects_of op)))"
+proof -
+ let ?fs = "map (\<lambda>v. \<^bold>\<not>(Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ \<^bold>\<or> \<^bold>\<not>(Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v)))) (delete_effects_of op)"
+ {
+ fix C
+ assume "C \<in> set ?fs"
+ then obtain v
+ where "v \<in> set (delete_effects_of op)"
+ and "C = \<^bold>\<not>(Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ \<^bold>\<or> \<^bold>\<not>(Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v)))"
+ by auto
+ hence "is_cnf C"
+ by fastforce
+ }
+ thus ?thesis
+ using is_cnf_BigAnd
+ by blast
+qed
+
+private lemma encode_operator_effect_is_cnf:
+ shows "is_cnf (encode_operator_effect \<Pi> t op)"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?fs = "map (\<lambda>v. \<^bold>\<not>(Atom (Operator t (index ?ops op)))
+ \<^bold>\<or> Atom (State (Suc t) (index ?vs v)))
+ (add_effects_of op)"
+ and ?fs' = "map (\<lambda>v. \<^bold>\<not>(Atom (Operator t (index ?ops op)))
+ \<^bold>\<or> \<^bold>\<not>(Atom (State (Suc t) (index ?vs v))))
+ (delete_effects_of op)"
+ have "encode_operator_effect \<Pi> t op = \<^bold>\<And>(?fs @ ?fs')"
+ unfolding encode_operator_effect_def[of \<Pi> t op]
+ by metis
+ moreover {
+ have "\<forall>f \<in> set ?fs. is_cnf f" "\<forall>f \<in> set ?fs'. is_cnf f"
+ using encode_operator_effects_is_cnf_i[of t \<Pi> op]
+ encode_operator_effects_is_cnf_ii[of t \<Pi> op]
+ by (simp+)
+ (* TODO slow. *)
+ hence "\<forall>f \<in> set (?fs @ ?fs'). is_cnf f"
+ by auto
+ }
+ ultimately show ?thesis
+ using is_cnf_BigAnd[of "?fs @ ?fs'"]
+ by presburger
+qed
+
+private lemma set_map_encode_operator_effect[simp]:
+ "set (map (\<lambda>(t, op). encode_operator_effect \<Pi> t op) (List.product [0..<t]
+ (strips_problem.operators_of \<Pi>)))
+ = { encode_operator_effect \<Pi> k op
+ | k op. (k, op) \<in> ({0..<t} \<times> set (strips_problem.operators_of \<Pi>)) }"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?fs = "map (\<lambda>(t, op). encode_operator_effect \<Pi> t op) (List.product [0..<t] ?ops)"
+ have "set ?fs = (\<lambda>(t, op). encode_operator_effect \<Pi> t op) ` ({0..<t} \<times> set ?ops)"
+ unfolding encode_operator_effect_def[of \<Pi> t]
+ by force
+ thus ?thesis
+ using setcompr_eq_image[of "\<lambda>(t, op). encode_operator_effect \<Pi> t op"
+ "\<lambda>(k, op). (k, op) \<in> {0..<t} \<times> set ?ops"]
+ by force
+qed
+
+private lemma encode_all_operator_effects_is_cnf:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "is_cnf (encode_all_operator_effects \<Pi> (strips_problem.operators_of \<Pi>) t)"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ let ?l = "List.product [0..<t] ?ops"
+ let ?fs = "map (\<lambda>(t, op). encode_operator_effect \<Pi> t op) ?l"
+ have "\<forall>f \<in> set ?fs. is_cnf f"
+ using encode_operator_effect_is_cnf
+ by force
+ thus ?thesis
+ unfolding encode_all_operator_effects_def
+ using is_cnf_foldr_and_if[of ?fs]
+ by presburger
+qed
+
+lemma encode_operators_is_cnf:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "is_cnf (encode_operators \<Pi> t)"
+ unfolding encode_operators_def
+ using is_cnf_encode_all_operator_preconditions[of \<Pi> t]
+ encode_all_operator_effects_is_cnf[OF assms, of t]
+ is_cnf.simps(1)[of "encode_all_operator_preconditions \<Pi> (strips_problem.operators_of \<Pi>) t"
+ "encode_all_operator_effects \<Pi> (strips_problem.operators_of \<Pi>) t"]
+ by meson
+
+\<comment> \<open> Simp flag alone did not do it, so we have to assign a name to this lemma as well. \<close>
+private lemma set_map_to_operator_atom[simp]:
+ "set (map (\<lambda>op. Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ (filter (\<lambda>op. ListMem v vs) (strips_problem.operators_of \<Pi>)))
+ = { Atom (Operator t (index (strips_problem.operators_of \<Pi>) op))
+ | op. op \<in> set (strips_problem.operators_of \<Pi>) \<and> v \<in> set vs }"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ {
+ have "set (filter (\<lambda>op. ListMem v vs) ?ops)
+ = { op \<in> set ?ops. ListMem v vs }"
+ using set_filter
+ by force
+ then have "set (filter (\<lambda>op. ListMem v vs) ?ops)
+ = { op. op \<in> set ?ops \<and> v \<in> set vs }"
+ using ListMem_iff[of v]
+ by blast
+ }
+ then have "set (map (\<lambda>op. Atom (Operator t (index ?ops op)))
+ (filter (\<lambda>op. ListMem v vs) ?ops))
+ = (\<lambda>op. Atom (Operator t (index ?ops op))) ` { op \<in> set ?ops. v \<in> set vs }"
+ using set_map[of "\<lambda>op. Atom (Operator t (index ?ops op))"]
+ by presburger
+ thus ?thesis
+ by blast
+qed
+
+(* TODO refactor \<open>Formula_Supplement\<close> *)
+lemma is_disj_big_or_if:
+ assumes "\<forall>f \<in> set fs. is_lit_plus f"
+ shows "is_disj \<^bold>\<Or>fs"
+ using assms
+proof (induction fs)
+ case (Cons f fs)
+ have "is_lit_plus f"
+ using Cons.prems
+ by simp
+ moreover have "is_disj \<^bold>\<Or>fs"
+ using Cons
+ by fastforce
+ ultimately show ?case
+ by simp
+qed simp
+
+lemma is_cnf_encode_negative_transition_frame_axiom:
+ shows "is_cnf (encode_negative_transition_frame_axiom \<Pi> t v)"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ let ?deleting = "filter (\<lambda>op. ListMem v (delete_effects_of op)) ?ops"
+ let ?fs = "map (\<lambda>op. Atom (Operator t (index ?ops op))) ?deleting"
+ and ?A = "(\<^bold>\<not>(Atom (State t (index ?vs v))))"
+ and ?B = "Atom (State (Suc t) (index ?vs v))"
+ {
+ fix f
+ assume "f \<in> set ?fs"
+ (* TODO slow. *)
+ then obtain op
+ where "op \<in> set ?ops"
+ and "v \<in> set (delete_effects_of op)"
+ and "f = Atom (Operator t (index ?ops op))"
+ using set_map_to_operator_atom[of t \<Pi> v]
+ by fastforce
+ hence "is_lit_plus f"
+ by simp
+ } note nb = this
+ {
+ have "is_disj \<^bold>\<Or>?fs"
+ using is_disj_big_or_if nb
+ by blast
+ then have "is_disj (?B \<^bold>\<or> \<^bold>\<Or>?fs)"
+ by force
+ then have "is_disj (?A \<^bold>\<or> (?B \<^bold>\<or> \<^bold>\<Or>?fs))"
+ by fastforce
+ hence "is_cnf (?A \<^bold>\<or> (?B \<^bold>\<or> \<^bold>\<Or>?fs))"
+ by fastforce
+ }
+ thus ?thesis
+ unfolding encode_negative_transition_frame_axiom_def
+ by meson
+qed
+
+lemma is_cnf_encode_positive_transition_frame_axiom:
+ shows "is_cnf (encode_positive_transition_frame_axiom \<Pi> t v)"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ let ?adding = "filter (\<lambda>op. ListMem v (add_effects_of op)) ?ops"
+ let ?fs = "map (\<lambda>op. Atom (Operator t (index ?ops op))) ?adding"
+ and ?A = "Atom (State t (index ?vs v))"
+ and ?B = "\<^bold>\<not>(Atom (State (Suc t) (index ?vs v)))"
+ {
+ fix f
+ assume "f \<in> set ?fs"
+ (* TODO slow. *)
+ then obtain op
+ where "op \<in> set ?ops"
+ and "v \<in> set (add_effects_of op)"
+ and "f = Atom (Operator t (index ?ops op))"
+ using set_map_to_operator_atom[of t \<Pi> v]
+ by fastforce
+ hence "is_lit_plus f"
+ by simp
+ } note nb = this
+ {
+ have "is_disj \<^bold>\<Or>?fs"
+ using is_disj_big_or_if nb
+ by blast
+ then have "is_disj (?B \<^bold>\<or> \<^bold>\<Or>?fs)"
+ by force
+ then have "is_disj (?A \<^bold>\<or> (?B \<^bold>\<or> \<^bold>\<Or>?fs))"
+ by fastforce
+ hence "is_cnf (?A \<^bold>\<or> (?B \<^bold>\<or> \<^bold>\<Or>?fs))"
+ by fastforce
+ }
+ thus ?thesis
+ unfolding encode_positive_transition_frame_axiom_def
+ by meson
+qed
+
+private lemma encode_all_frame_axioms_set[simp]:
+ "set (map (\<lambda>(k, v). encode_negative_transition_frame_axiom \<Pi> k v)
+ (List.product [0..<t] (strips_problem.variables_of \<Pi>))
+ @ (map (\<lambda>(k, v). encode_positive_transition_frame_axiom \<Pi> k v)
+ (List.product [0..<t] (strips_problem.variables_of \<Pi>))))
+ = { encode_negative_transition_frame_axiom \<Pi> k v
+ | k v. (k, v) \<in> ({0..<t} \<times> set (strips_problem.variables_of \<Pi>)) }
+ \<union> { encode_positive_transition_frame_axiom \<Pi> k v
+ | k v. (k, v) \<in> ({0..<t} \<times> set (strips_problem.variables_of \<Pi>)) }"
+proof -
+ let ?l = "List.product [0..<t] (strips_problem.variables_of \<Pi>)"
+ let ?A = "(\<lambda>(k, v). encode_negative_transition_frame_axiom \<Pi> k v) ` set ?l"
+ and ?B = "(\<lambda>(k, v). encode_positive_transition_frame_axiom \<Pi> k v) ` set ?l"
+ and ?fs = "map (\<lambda>(k, v). encode_negative_transition_frame_axiom \<Pi> k v) ?l
+ @ (map (\<lambda>(k, v). encode_positive_transition_frame_axiom \<Pi> k v) ?l)"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ have set_l_is: "set ?l = {0..<t} \<times> set ?vs"
+ by simp
+ have "set ?fs = ?A \<union> ?B"
+ using set_append
+ by force
+ moreover have "?A = { encode_negative_transition_frame_axiom \<Pi> k v
+ | k v. (k, v) \<in> ({0..<t} \<times> set ?vs) }"
+ using set_l_is setcompr_eq_image[of "\<lambda>(k, v). encode_negative_transition_frame_axiom \<Pi> k v"
+ "\<lambda>(k, v). (k, v) \<in> ({0..<t} \<times> set ?vs)"]
+ by fast
+ moreover have "?B = { encode_positive_transition_frame_axiom \<Pi> k v
+ | k v. (k, v) \<in> ({0..<t} \<times> set ?vs) }"
+ using set_l_is setcompr_eq_image[of "\<lambda>(k, v). encode_positive_transition_frame_axiom \<Pi> k v"
+ "\<lambda>(k, v). (k, v) \<in> ({0..<t} \<times> set ?vs)"]
+ by fast
+ ultimately show ?thesis
+ by argo
+qed
+
+(* rename \<open>is_cnf_encode_all_frame_axioms\<close>. *)
+lemma encode_frame_axioms_is_cnf:
+ shows "is_cnf (encode_all_frame_axioms \<Pi> t)"
+proof -
+ let ?l = "List.product [0..<t] (strips_problem.variables_of \<Pi>)"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?A = "{ encode_negative_transition_frame_axiom \<Pi> k v
+ | k v. (k, v) \<in> ({0..<t} \<times> set ?vs) }"
+ and ?B = "{ encode_positive_transition_frame_axiom \<Pi> k v
+ | k v. (k, v) \<in> ({0..<t} \<times> set ?vs) }"
+ and ?fs = "map (\<lambda>(k, v). encode_negative_transition_frame_axiom \<Pi> k v) ?l
+ @ (map (\<lambda>(k, v). encode_positive_transition_frame_axiom \<Pi> k v) ?l)"
+ {
+ fix f
+ assume "f \<in> set ?fs"
+ (* TODO slow. *)
+ then consider (f_encodes_negative_frame_axiom) "f \<in> ?A"
+ | (f_encodes_positive_frame_axiom) "f \<in> ?B"
+ by fastforce
+ hence "is_cnf f"
+ using is_cnf_encode_negative_transition_frame_axiom
+ is_cnf_encode_positive_transition_frame_axiom
+ by (smt mem_Collect_eq)
+ }
+ thus ?thesis
+ unfolding encode_all_frame_axioms_def
+ using is_cnf_BigAnd[of ?fs]
+ by meson
+qed
+
+lemma is_cnf_encode_problem:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "is_cnf (\<Phi> \<Pi> t)"
+proof -
+ have "is_cnf (\<Phi>\<^sub>I \<Pi>)"
+ using is_cnf_encode_initial_state assms
+ by auto
+ moreover have "is_cnf (encode_goal_state \<Pi> t)"
+ using encode_goal_state_is_cnf[OF assms]
+ by simp
+ moreover have "is_cnf (encode_operators \<Pi> t \<^bold>\<and> encode_all_frame_axioms \<Pi> t)"
+ using encode_operators_is_cnf[OF assms] encode_frame_axioms_is_cnf
+ unfolding encode_transitions_def
+ by simp
+ ultimately show ?thesis
+ unfolding encode_problem_def SAT_Plan_Base.encode_problem_def
+ encode_transitions_def encode_initial_state_def[symmetric] encode_goal_state_def[symmetric]
+ by simp
+qed
+
+lemma encode_problem_has_model_then_also_partial_encodings:
+ assumes "\<A> \<Turnstile> SAT_Plan_Base.encode_problem \<Pi> t"
+ shows "\<A> \<Turnstile> SAT_Plan_Base.encode_initial_state \<Pi>"
+ and "\<A> \<Turnstile> SAT_Plan_Base.encode_goal_state \<Pi> t"
+ and "\<A> \<Turnstile> SAT_Plan_Base.encode_operators \<Pi> t"
+ and "\<A> \<Turnstile> SAT_Plan_Base.encode_all_frame_axioms \<Pi> t"
+ using assms
+ unfolding SAT_Plan_Base.encode_problem_def
+ by simp+
+
+lemma cnf_of_encode_problem_structure:
+ shows "cnf (SAT_Plan_Base.encode_initial_state \<Pi>)
+ \<subseteq> cnf (SAT_Plan_Base.encode_problem \<Pi> t)"
+ and "cnf (SAT_Plan_Base.encode_goal_state \<Pi> t)
+ \<subseteq> cnf (SAT_Plan_Base.encode_problem \<Pi> t)"
+ and "cnf (SAT_Plan_Base.encode_operators \<Pi> t)
+ \<subseteq> cnf (SAT_Plan_Base.encode_problem \<Pi> t)"
+ and "cnf (SAT_Plan_Base.encode_all_frame_axioms \<Pi> t)
+ \<subseteq> cnf (SAT_Plan_Base.encode_problem \<Pi> t)"
+ unfolding SAT_Plan_Base.encode_problem_def
+ SAT_Plan_Base.encode_problem_def[of \<Pi> t] SAT_Plan_Base.encode_initial_state_def[of \<Pi>]
+ SAT_Plan_Base.encode_goal_state_def[of \<Pi> t] SAT_Plan_Base.encode_operators_def
+ SAT_Plan_Base.encode_all_frame_axioms_def[of \<Pi> t]
+ subgoal by auto
+ subgoal by force
+ subgoal by auto
+ subgoal by force
+ done
+
+\<comment> \<open> A technical lemma which shows a simpler form of the CNF of the initial state encoding. \<close>
+(* TODO generalize for more encodings? *)
+private lemma cnf_of_encode_initial_state_set_i:
+ shows "cnf (\<Phi>\<^sub>I \<Pi>) = \<Union> { cnf (encode_state_variable 0
+ (index (strips_problem.variables_of \<Pi>) v) (((\<Pi>)\<^sub>I) v))
+ | v. v \<in> set (strips_problem.variables_of \<Pi>) \<and> ((\<Pi>)\<^sub>I) v \<noteq> None }"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?I = "strips_problem.initial_of \<Pi>"
+ let ?ls = "map (\<lambda>v. encode_state_variable 0 (index ?vs v) (?I v) \<^bold>\<or> \<bottom>)
+ (filter (\<lambda>v. ?I v \<noteq> None) ?vs)"
+ {
+ have "cnf ` set ?ls = cnf ` (\<lambda>v. encode_state_variable 0 (index ?vs v) (?I v) \<^bold>\<or> \<bottom>)
+ ` set (filter (\<lambda>v. ?I v \<noteq> None) ?vs)"
+ using set_map[of "\<lambda>v. encode_state_variable 0 (index ?vs v) (?I v) \<^bold>\<or> \<bottom>"]
+ by presburger
+ also have "\<dots> = (\<lambda>v. cnf (encode_state_variable 0 (index ?vs v) (?I v) \<^bold>\<or> \<bottom>))
+ ` set (filter (\<lambda>v. ?I v \<noteq> None) ?vs)"
+ using image_comp
+ by blast
+ also have "\<dots> = (\<lambda>v. cnf (encode_state_variable 0 (index ?vs v) (?I v)))
+ ` { v \<in> set ?vs. ?I v \<noteq> None }"
+ using set_filter[of "\<lambda>v. ?I v \<noteq> None" ?vs]
+ by auto
+ finally have "cnf ` set ?ls = { cnf (encode_state_variable 0 (index ?vs v) (?I v))
+ | v. v \<in> set ?vs \<and> ?I v \<noteq> None }"
+ using setcompr_eq_image[of "\<lambda>v. cnf (encode_state_variable 0 (index ?vs v) (?I v))"]
+ by presburger
+ }
+ moreover have "cnf (\<Phi>\<^sub>I \<Pi>) = \<Union> (cnf ` set ?ls)"
+ unfolding encode_initial_state_def SAT_Plan_Base.encode_initial_state_def
+ using cnf_BigAnd[of ?ls]
+ by meson
+ ultimately show ?thesis
+ by auto
+qed
+
+\<comment> \<open> A simplification lemma for the above one. \<close>
+(* TODO Replace above lemma with this?. *)
+corollary cnf_of_encode_initial_state_set_ii:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "cnf (\<Phi>\<^sub>I \<Pi>) = (\<Union>v \<in> set (strips_problem.variables_of \<Pi>). {{
+ literal_formula_to_literal (encode_state_variable 0 (index (strips_problem.variables_of \<Pi>) v)
+ (strips_problem.initial_of \<Pi> v)) }})"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?I = "strips_problem.initial_of \<Pi>"
+ have nb\<^sub>1: "{ v. v \<in> set ?vs \<and> ?I v \<noteq> None } = set ?vs"
+ using is_valid_problem_strips_initial_of_dom assms(1)
+ by auto
+ (* TODO generalize and refactor. *)
+ {
+ fix v
+ assume "v \<in> set ?vs"
+ then have "?I v \<noteq> None"
+ using is_valid_problem_strips_initial_of_dom assms(1)
+ by auto
+ then consider (I_v_is_Some_True) "?I v = Some True"
+ | (I_v_is_Some_False) "?I v = Some False"
+ by fastforce
+ hence "cnf (encode_state_variable 0 (index ?vs v) (?I v))
+ = {{ literal_formula_to_literal (encode_state_variable 0 (index ?vs v) (?I v)) }}"
+ unfolding encode_state_variable_def
+ by (cases, simp+)
+ } note nb\<^sub>2 = this
+ {
+ have "{ cnf (encode_state_variable 0 (index ?vs v) (?I v)) | v. v \<in> set ?vs \<and> ?I v \<noteq> None }
+ = (\<lambda>v. cnf (encode_state_variable 0 (index ?vs v) (?I v))) ` set ?vs"
+ using setcompr_eq_image[of "\<lambda>v. cnf (encode_state_variable 0 (index ?vs v) (?I v))"
+ "\<lambda>v. v \<in> set ?vs \<and> ?I v \<noteq> None"] using nb\<^sub>1
+ by presburger
+ hence "{ cnf (encode_state_variable 0 (index ?vs v) (?I v)) | v. v \<in> set ?vs \<and> ?I v \<noteq> None }
+ = (\<lambda>v. {{ literal_formula_to_literal (encode_state_variable 0 (index ?vs v) (?I v)) }})
+ ` set ?vs"
+ using nb\<^sub>2
+ by force
+ }
+ thus ?thesis
+ using cnf_of_encode_initial_state_set_i
+ by (smt Collect_cong)
+qed
+
+(* TODO \<open>\<exists>!\<close> is superfluous now? rm? + Above lemma basically covers this one. *)
+lemma cnf_of_encode_initial_state_set:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "v \<in> dom (strips_problem.initial_of \<Pi>)"
+ shows "strips_problem.initial_of \<Pi> v = Some True \<longrightarrow> (\<exists>!C. C \<in> cnf (\<Phi>\<^sub>I \<Pi>)
+ \<and> C = { (State 0 (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ })"
+ and "strips_problem.initial_of \<Pi> v = Some False \<longrightarrow> (\<exists>!C. C \<in> cnf (\<Phi>\<^sub>I \<Pi>)
+ \<and> C = { (State 0 (index (strips_problem.variables_of \<Pi>) v))\<inverse> })"
+proof -
+ let ?I = "(\<Pi>)\<^sub>I"
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ let ?\<Phi>\<^sub>I = "\<Phi>\<^sub>I \<Pi>"
+ have nb\<^sub>1: "cnf (\<Phi>\<^sub>I \<Pi>) = \<Union> { cnf (encode_state_variable 0 (index ?vs v)
+ (strips_problem.initial_of \<Pi> v)) | v. v \<in> set ?vs \<and> ?I v \<noteq> None }"
+ using cnf_of_encode_initial_state_set_i
+ by blast
+ {
+ have "v \<in> set ?vs"
+ using is_valid_problem_strips_initial_of_dom assms(1, 2)
+ by blast
+ hence "v \<in> { v. v \<in> set ?vs \<and> ?I v \<noteq> None }"
+ using assms(2)
+ by auto
+ } note nb\<^sub>2 = this
+ show "strips_problem.initial_of \<Pi> v = Some True \<longrightarrow> (\<exists>!C. C \<in> cnf (\<Phi>\<^sub>I \<Pi>)
+ \<and> C = { (State 0 (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ })"
+ and "strips_problem.initial_of \<Pi> v = Some False \<longrightarrow> (\<exists>!C. C \<in> cnf (\<Phi>\<^sub>I \<Pi>)
+ \<and> C = { (State 0 (index (strips_problem.variables_of \<Pi>) v))\<inverse> })"
+ proof (auto)
+ assume i_v_is_some_true: "strips_problem.initial_of \<Pi> v = Some True"
+ then have "{ (State 0 (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }
+ \<in> cnf (encode_state_variable 0 (index (strips_problem.variables_of \<Pi>) v) (?I v))"
+ unfolding encode_state_variable_def
+ using i_v_is_some_true
+ by auto
+ thus "{ (State 0 (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }
+ \<in> cnf (\<Phi>\<^sub>I \<Pi>)"
+ using nb\<^sub>1 nb\<^sub>2
+ by auto
+ next
+ assume i_v_is_some_false: "strips_problem.initial_of \<Pi> v = Some False"
+ then have "{ (State 0 (index (strips_problem.variables_of \<Pi>) v))\<inverse> }
+ \<in> cnf (encode_state_variable 0 (index (strips_problem.variables_of \<Pi>) v) (?I v))"
+ unfolding encode_state_variable_def
+ using i_v_is_some_false
+ by auto
+ thus "{ (State 0 (index (strips_problem.variables_of \<Pi>) v))\<inverse> }
+ \<in> cnf (\<Phi>\<^sub>I \<Pi>)"
+ using nb\<^sub>1 nb\<^sub>2
+ by auto
+ qed
+qed
+
+lemma cnf_of_operator_encoding_structure:
+ "cnf (encode_operators \<Pi> t) = cnf (encode_all_operator_preconditions \<Pi>
+ (strips_problem.operators_of \<Pi>) t)
+ \<union> cnf (encode_all_operator_effects \<Pi> (strips_problem.operators_of \<Pi>) t)"
+ unfolding encode_operators_def
+ using cnf.simps(5)
+ by metis
+
+corollary cnf_of_operator_precondition_encoding_subset_encoding:
+ "cnf (encode_all_operator_preconditions \<Pi> (strips_problem.operators_of \<Pi>) t)
+ \<subseteq> cnf (\<Phi> \<Pi> t)"
+ using cnf_of_operator_encoding_structure cnf_of_encode_problem_structure subset_trans
+ unfolding encode_problem_def
+ by blast
+
+(* TODO refactor \<open>CNF_Supplement\<close> *)
+lemma cnf_foldr_and[simp]:
+ "cnf (foldr (\<^bold>\<and>) fs (\<^bold>\<not>\<bottom>)) = (\<Union>f \<in> set fs. cnf f)"
+proof (induction fs)
+ case (Cons f fs)
+ have ih: "cnf (foldr (\<^bold>\<and>) fs (\<^bold>\<not>\<bottom>)) = (\<Union>f \<in> set fs. cnf f)"
+ using Cons.IH
+ by blast
+ {
+ have "cnf (foldr (\<^bold>\<and>) (f # fs) (\<^bold>\<not>\<bottom>)) = cnf (f \<^bold>\<and> foldr (\<^bold>\<and>) fs (\<^bold>\<not>\<bottom>))"
+ by simp
+ also have "\<dots> = cnf f \<union> cnf (foldr (\<^bold>\<and>) fs (\<^bold>\<not>\<bottom>))"
+ by force
+ finally have "cnf (foldr (\<^bold>\<and>) (f # fs) (\<^bold>\<not>\<bottom>)) = cnf f \<union> (\<Union>f \<in> set fs. cnf f)"
+ using ih
+ by argo
+ }
+ thus ?case
+ by auto
+qed simp
+
+(* TODO rm (unused)? *)
+private lemma cnf_of_encode_operator_precondition[simp]:
+ "cnf (encode_operator_precondition \<Pi> t op) = (\<Union>v \<in> set (precondition_of op).
+ {{(Operator t (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State t (index (strips_problem.variables_of \<Pi>) v))\<^sup>+}})"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?\<Phi>\<^sub>P = "encode_operator_precondition \<Pi> t op"
+ let ?fs = "map (\<lambda>v. \<^bold>\<not> (Atom (Operator t (index ?ops op))) \<^bold>\<or> Atom (State t (index ?vs v)))
+ (precondition_of op)"
+ and ?A = "(\<lambda>v. \<^bold>\<not> (Atom (Operator t (index ?ops op))) \<^bold>\<or> Atom (State t (index ?vs v)))
+ ` set (precondition_of op)"
+ have "cnf (encode_operator_precondition \<Pi> t op) = cnf (\<^bold>\<And>?fs)"
+ unfolding encode_operator_precondition_def
+ by presburger
+ also have "\<dots> = \<Union> (cnf ` set ?fs)"
+ using cnf_BigAnd
+ by blast
+ also have "\<dots> = \<Union>(cnf ` ?A)"
+ using set_map[of "\<lambda>v. \<^bold>\<not> (Atom (Operator t (index ?ops op))) \<^bold>\<or> Atom (State t (index ?vs v))"
+ "precondition_of op"]
+ by argo
+ also have "\<dots> = (\<Union>v \<in> set (precondition_of op).
+ cnf (\<^bold>\<not>(Atom (Operator t (index ?ops op))) \<^bold>\<or> Atom (State t (index ?vs v))))"
+ by blast
+ (* TODO slow. *)
+ finally show ?thesis
+ by auto
+qed
+
+(* TODO Shorten proof. *)
+lemma cnf_of_encode_all_operator_preconditions_structure[simp]:
+ "cnf (encode_all_operator_preconditions \<Pi> (strips_problem.operators_of \<Pi>) t)
+ = (\<Union>(t, op) \<in> ({..<t} \<times> set (operators_of \<Pi>)).
+ (\<Union>v \<in> set (precondition_of op).
+ {{(Operator t (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State t (index (strips_problem.variables_of \<Pi>) v))\<^sup>+}}))"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ let ?l = "List.product [0..<t] ?ops"
+ and ?\<Phi>\<^sub>P = "encode_all_operator_preconditions \<Pi> (strips_problem.operators_of \<Pi>) t"
+ let ?A = "set (map (\<lambda>(t, op). encode_operator_precondition \<Pi> t op) ?l)"
+ {
+ have "set ?l = {0..<t} \<times> set ((\<Pi>)\<^sub>\<O>)"
+ by auto
+ then have "?A = (\<lambda>(t, op). encode_operator_precondition \<Pi> t op) ` ({0..<t} \<times> set ((\<Pi>)\<^sub>\<O>))"
+ using set_map
+ by force
+ } note nb = this
+ have "cnf ?\<Phi>\<^sub>P = cnf (foldr (\<^bold>\<and>) (map (\<lambda>(t, op). encode_operator_precondition \<Pi> t op) ?l) (\<^bold>\<not>\<bottom>))"
+ unfolding encode_all_operator_preconditions_def
+ by presburger
+ also have "\<dots> = (\<Union>f \<in> ?A. cnf f)"
+ by simp
+ (* TODO slow. *)
+ also have "\<dots> = (\<Union>(k, op) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<O>)).
+ cnf (encode_operator_precondition \<Pi> k op))"
+ using nb
+ by fastforce
+ (* TODO very slow. *)
+ finally show ?thesis
+ by fastforce
+ qed
+
+corollary cnf_of_encode_all_operator_preconditions_contains_clause_if:
+ fixes \<Pi>::"'variable STRIPS_Representation.strips_problem"
+ assumes "is_valid_problem_strips (\<Pi>::'variable STRIPS_Representation.strips_problem)"
+ and "k < t"
+ and "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ and "v \<in> set (precondition_of op)"
+ shows "{ (Operator k (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State k (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }
+ \<in> cnf (encode_all_operator_preconditions \<Pi> (strips_problem.operators_of \<Pi>) t)"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?\<Phi>\<^sub>P = "encode_all_operator_preconditions \<Pi> ?ops t"
+ and ?C = "{ (Operator k (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State k (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }"
+ {
+ have nb: "(k, op) \<in> {..<t} \<times> set ((\<Pi>)\<^sub>\<O>)"
+ using assms(2, 3)
+ by blast
+ moreover {
+ have "?C \<in> (\<Union>v\<in>set (precondition_of op).
+ {{(Operator k (index (strips_problem.operators_of \<Pi>) op))\<inverse>,
+ (State k (index (strips_problem.variables_of \<Pi>) v))\<^sup>+}})"
+ using UN_iff[where A="set (precondition_of op)"
+ and B="\<lambda>v. {{(Operator t (index (strips_problem.operators_of \<Pi>) op))\<inverse>,
+ (State t (index (strips_problem.variables_of \<Pi>) v))\<^sup>+}}"] assms(4)
+ by blast
+ hence "\<exists>x\<in>{..<t} \<times> set ((\<Pi>)\<^sub>\<O>).
+ ?C \<in> (case x of (k, op) \<Rightarrow> \<Union>v\<in>set (precondition_of op).
+ {{(Operator k (index (strips_problem.operators_of \<Pi>) op))\<inverse>,
+ (State k (index (strips_problem.variables_of \<Pi>) v))\<^sup>+}})"
+ using nb
+ by blast
+ }
+ ultimately have "?C \<in> (\<Union>(t, op) \<in> ({..<t} \<times> set ((\<Pi>)\<^sub>\<O>)).
+ (\<Union>v \<in> set (precondition_of op).
+ {{ (Operator t (index ?ops op))\<inverse>, (State t (index ?vs v))\<^sup>+ }}))"
+ by blast
+ }
+ thus ?thesis
+ using cnf_of_encode_all_operator_preconditions_structure[of \<Pi> t]
+ by argo
+qed
+
+corollary cnf_of_encode_all_operator_effects_subset_cnf_of_encode_problem:
+ "cnf (encode_all_operator_effects \<Pi> (strips_problem.operators_of \<Pi>) t)
+ \<subseteq> cnf (\<Phi> \<Pi> t)"
+ using cnf_of_encode_problem_structure(3) cnf_of_operator_encoding_structure
+ unfolding encode_problem_def
+ by blast
+
+private lemma cnf_of_encode_operator_effect_structure[simp]:
+ "cnf (encode_operator_effect \<Pi> t op)
+ = (\<Union>v \<in> set (add_effects_of op). {{ (Operator t (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }})
+ \<union> (\<Union>v \<in> set (delete_effects_of op).
+ {{ (Operator t (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))\<inverse> }})"
+proof -
+ let ?fs\<^sub>1 = "map (\<lambda>v. \<^bold>\<not>(Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ \<^bold>\<or> Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v)))
+ (add_effects_of op)"
+ and ?fs\<^sub>2 = "map (\<lambda>v. \<^bold>\<not>(Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ \<^bold>\<or> \<^bold>\<not> (Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))))
+ (delete_effects_of op)"
+ {
+ have "cnf ` set ?fs\<^sub>1 = cnf
+ ` (\<lambda>v. \<^bold>\<not>(Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ \<^bold>\<or> Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))) ` set (add_effects_of op)"
+ using set_map
+ by force
+ also have "\<dots> = (\<lambda>v. cnf (\<^bold>\<not>(Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ \<^bold>\<or> Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))))
+ ` set (add_effects_of op)"
+ using image_comp
+ by blast
+ (* TODO slow. *)
+ finally have "cnf ` set ?fs\<^sub>1 = (\<lambda>v. {{ (Operator t (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }}) ` set (add_effects_of op)"
+ by auto
+ } note nb\<^sub>1 = this
+ {
+ have "cnf ` set ?fs\<^sub>2 = cnf ` (\<lambda>v. \<^bold>\<not>(Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ \<^bold>\<or> \<^bold>\<not>(Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))))
+ ` set (delete_effects_of op)"
+ using set_map
+ by force
+ also have "\<dots> = (\<lambda>v. cnf (\<^bold>\<not>(Atom (Operator t (index (strips_problem.operators_of \<Pi>) op)))
+ \<^bold>\<or> \<^bold>\<not> (Atom (State (Suc t) (index (strips_problem.variables_of \<Pi>) v)))))
+ ` set (delete_effects_of op)"
+ using image_comp
+ by blast
+ (* TODO slow. *)
+ finally have "cnf ` set ?fs\<^sub>2 = (\<lambda>v. {{ (Operator t (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))\<inverse> }})
+ ` set (delete_effects_of op)"
+ by auto
+ } note nb\<^sub>2 = this
+ {
+ have "cnf (encode_operator_effect \<Pi> t op) = \<Union>(cnf ` set (?fs\<^sub>1 @ ?fs\<^sub>2))"
+ unfolding encode_operator_effect_def
+ using cnf_BigAnd[of "?fs\<^sub>1 @ ?fs\<^sub>2"]
+ by meson
+ also have "\<dots> = \<Union>(cnf ` set ?fs\<^sub>1 \<union> cnf ` set ?fs\<^sub>2)"
+ using set_append[of "?fs\<^sub>1" "?fs\<^sub>2"] image_Un[of cnf "set ?fs\<^sub>1" "set ?fs\<^sub>2"]
+ by argo
+ also have "\<dots> = \<Union>(cnf ` set ?fs\<^sub>1) \<union> \<Union>(cnf ` set ?fs\<^sub>2)"
+ using Union_Un_distrib[of "cnf ` set ?fs\<^sub>1" "cnf ` set ?fs\<^sub>2"]
+ by argo
+ (* TODO slow. *)
+ finally have "cnf (encode_operator_effect \<Pi> t op)
+ = (\<Union>v \<in> set (add_effects_of op).
+ {{ (Operator t (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }})
+ \<union> (\<Union>v \<in> set (delete_effects_of op).
+ {{ (Operator t (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc t) (index (strips_problem.variables_of \<Pi>) v))\<inverse> }})"
+ using nb\<^sub>1 nb\<^sub>2
+ by argo
+ }
+ thus ?thesis
+ by blast
+qed
+
+lemma cnf_of_encode_all_operator_effects_structure:
+ "cnf (encode_all_operator_effects \<Pi> (strips_problem.operators_of \<Pi>) t)
+ = (\<Union>(k, op) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<O>)).
+ (\<Union>v \<in> set (add_effects_of op).
+ {{ (Operator k (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }}))
+ \<union> (\<Union>(k, op) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<O>)).
+ (\<Union>v \<in> set (delete_effects_of op).
+ {{ (Operator k (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<inverse> }}))"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?\<Phi>\<^sub>E = "encode_all_operator_effects \<Pi> ?ops t"
+ and ?l = "List.product [0..<t] ?ops"
+ let ?fs = "map (\<lambda>(t, op). encode_operator_effect \<Pi> t op) ?l"
+ have nb: "set (List.product [0..<t] ?ops) = {0..<t} \<times> set ?ops"
+ by simp
+ {
+ have "cnf ` set ?fs = cnf ` (\<lambda>(k, op). encode_operator_effect \<Pi> k op) ` ({0..<t} \<times> set ?ops)"
+ by force
+ also have "\<dots> = (\<lambda>(k, op). cnf (encode_operator_effect \<Pi> k op)) ` ({0..<t} \<times> set ?ops)"
+ using image_comp
+ by fast
+ (* TODO slow. *)
+ finally have "cnf ` set ?fs = (\<lambda>(k, op).
+ (\<Union>v \<in> set (add_effects_of op).
+ {{ (Operator k (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }})
+ \<union> (\<Union>v \<in> set (delete_effects_of op).
+ {{ (Operator k (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<inverse> }}))
+ ` ({0..<t} \<times> set ?ops)"
+ using cnf_of_encode_operator_effect_structure
+ by auto
+ }
+ (* TODO slow. *)
+ thus ?thesis
+ unfolding encode_all_operator_effects_def
+ using cnf_BigAnd[of ?fs]
+ by auto
+qed
+
+corollary cnf_of_operator_effect_encoding_contains_add_effect_clause_if:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "k < t"
+ and "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ and "v \<in> set (add_effects_of op)"
+ shows "{ (Operator k (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }
+ \<in> cnf (encode_all_operator_effects \<Pi> (strips_problem.operators_of \<Pi>) t)"
+proof -
+ let ?\<Phi>\<^sub>E = "encode_all_operator_effects \<Pi> (strips_problem.operators_of \<Pi>) t"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?Add = "\<Union>(k, op)\<in>{0..<t} \<times> set ((\<Pi>)\<^sub>\<O>).
+ \<Union>v\<in>set (add_effects_of op). {{ (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+}}"
+ let ?C = "{ (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }"
+ have "?Add \<subseteq> cnf ?\<Phi>\<^sub>E"
+ using cnf_of_encode_all_operator_effects_structure[of \<Pi> t] Un_upper1[of "?Add"]
+ by presburger
+ moreover {
+ have "?C \<in> {{ (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }}"
+ using assms(4)
+ by blast
+ then have "?C \<in> (\<Union>v\<in>set (add_effects_of op).
+ {{ (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+}})"
+ using Complete_Lattices.UN_iff[of "?C" "\<lambda>v. {{ (Operator k (index ?ops op))\<inverse>
+ , (State (Suc k) (index ?vs v))\<^sup>+}}" "set (add_effects_of op)"]
+ using assms(4)
+ by blast
+ moreover have "(k, op) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<O>))"
+ using assms(2, 3)
+ by fastforce
+ (* TODO slow step. *)
+ ultimately have "?C \<in> ?Add"
+ by blast
+ }
+ ultimately show ?thesis
+ using subset_eq[of "?Add" "cnf ?\<Phi>\<^sub>E"]
+ by meson
+qed
+
+corollary cnf_of_operator_effect_encoding_contains_delete_effect_clause_if:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "k < t"
+ and "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ and "v \<in> set (delete_effects_of op)"
+ shows "{ (Operator k (index (strips_problem.operators_of \<Pi>) op))\<inverse>
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<inverse> }
+ \<in> cnf (encode_all_operator_effects \<Pi> (strips_problem.operators_of \<Pi>) t)"
+proof -
+ let ?\<Phi>\<^sub>E = "encode_all_operator_effects \<Pi> (strips_problem.operators_of \<Pi>) t"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?Delete = "(\<Union>(k, op)\<in>{0..<t} \<times> set ((\<Pi>)\<^sub>\<O>).
+ \<Union>v\<in>set (delete_effects_of op).
+ {{ (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse> }})"
+ let ?C = "{ (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse> }"
+ have "?Delete \<subseteq> cnf ?\<Phi>\<^sub>E"
+ using cnf_of_encode_all_operator_effects_structure[of \<Pi> t] Un_upper2[of "?Delete"]
+ by presburger
+ moreover {
+ have "?C \<in> (\<Union>v \<in> set (delete_effects_of op).
+ {{ (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse> }})"
+ using assms(4)
+ by blast
+ moreover have "(k, op) \<in> {0..<t} \<times> set ?ops"
+ using assms(2, 3)
+ by force
+ (* TODO slow step. *)
+ ultimately have "?C \<in> ?Delete"
+ by fastforce
+ }
+ (* TODO slow step. *)
+ ultimately show ?thesis
+ using subset_eq[of "?Delete" "cnf ?\<Phi>\<^sub>E"]
+ by meson
+qed
+
+(* TODO refactor \<open>CNF_Supplement\<close>. *)
+private lemma cnf_of_big_or_of_literal_formulas_is[simp]:
+ assumes "\<forall>f \<in> set fs. is_literal_formula f"
+ shows "cnf (\<^bold>\<Or>fs) = {{ literal_formula_to_literal f | f. f \<in> set fs }}"
+ using assms
+proof (induction fs)
+ case (Cons f fs)
+ {
+ have is_literal_formula_f: "is_literal_formula f"
+ using Cons.prems(1)
+ by simp
+ then have "cnf f = {{ literal_formula_to_literal f }}"
+ using cnf_of_literal_formula
+ by blast
+ } note nb\<^sub>1 = this
+ {
+ have "\<forall>f' \<in> set fs. is_literal_formula f'"
+ using Cons.prems
+ by fastforce
+ hence "cnf (\<^bold>\<Or>fs) = {{ literal_formula_to_literal f | f. f \<in> set fs }}"
+ using Cons.IH
+ by argo
+ } note nb\<^sub>2 = this
+ {
+ have "cnf (\<^bold>\<Or>(f # fs)) = (\<lambda>(g, h). g \<union> h)
+ ` ({{ literal_formula_to_literal f}}
+ \<times> {{ literal_formula_to_literal f' | f'. f' \<in> set fs }})"
+ using nb\<^sub>1 nb\<^sub>2
+ by simp
+ also have "\<dots> = {{ literal_formula_to_literal f}
+ \<union> { literal_formula_to_literal f' | f'. f' \<in> set fs }}"
+ by fast
+ finally have "cnf (\<^bold>\<Or>(f # fs)) = {{ literal_formula_to_literal f' | f'. f' \<in> set (f # fs) }}"
+ by fastforce
+ }
+ thus ?case .
+qed simp
+
+private lemma set_filter_op_list_mem_vs[simp]:
+ "set (filter (\<lambda>op. ListMem v vs) ops) = { op. op \<in> set ops \<and> v \<in> set vs }"
+ using set_filter[of "\<lambda>op. ListMem v vs" ops] ListMem_iff
+ by force
+
+private lemma cnf_of_positive_transition_frame_axiom:
+ "cnf (encode_positive_transition_frame_axiom \<Pi> k v)
+ = {{ (State k (index (strips_problem.variables_of \<Pi>) v))\<^sup>+
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<inverse> }
+ \<union> { (Operator k (index (strips_problem.operators_of \<Pi>) op))\<^sup>+
+ | op. op \<in> set (strips_problem.operators_of \<Pi>) \<and> v \<in> set (add_effects_of op) }}"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ let ?adding_operators = "filter (\<lambda>op. ListMem v (add_effects_of op)) ?ops"
+ let ?fs = "map (\<lambda>op. Atom (Operator k (index ?ops op))) ?adding_operators"
+ {
+ have "set ?fs = (\<lambda>op. Atom (Operator k (index ?ops op))) ` set ?adding_operators"
+ using set_map[of "\<lambda>op. Atom (Operator k (index ?ops op))" "?adding_operators"]
+ by blast
+ (* TODO slow. *)
+ then have "literal_formula_to_literal ` set ?fs
+ = (\<lambda>op. (Operator k (index ?ops op))\<^sup>+) ` set ?adding_operators"
+ using image_comp[of literal_formula_to_literal "\<lambda>op. Atom (Operator k (index ?ops op))"
+ "set ?adding_operators"]
+ by simp
+ also have "\<dots> = (\<lambda>op. (Operator k (index ?ops op))\<^sup>+)
+ ` { op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }"
+ using set_filter_op_list_mem_vs[of v _ ?ops]
+ by auto
+ (* TODO slow. *)
+ finally have "literal_formula_to_literal ` set ?fs
+ = { (Operator k (index ?ops op))\<^sup>+ | op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }"
+ using setcompr_eq_image[of "\<lambda>op. (Operator k (index ?ops op))\<^sup>+"
+ "\<lambda>op. op \<in>set ?adding_operators"]
+ by blast
+ (* TODO slow. *)
+ hence "cnf (\<^bold>\<Or>?fs) = {{ (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }}"
+ using cnf_of_big_or_of_literal_formulas_is[of ?fs]
+ setcompr_eq_image[of literal_formula_to_literal "\<lambda>f. f \<in> set ?fs"]
+ by force
+ }
+ (* TODO slow. *)
+ then have "cnf (\<^bold>\<not>(Atom (State (Suc k) (index ?vs v))) \<^bold>\<or> \<^bold>\<Or>?fs)
+ = {{ (State (Suc k) (index ?vs v))\<inverse> } \<union> { (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }}"
+ by force
+ (* TODO slow. *)
+ then have "cnf ((Atom (State k (index ?vs v)) \<^bold>\<or> (\<^bold>\<not>(Atom (State (Suc k) (index ?vs v))) \<^bold>\<or> \<^bold>\<Or>?fs)))
+ = {{ (State k (index ?vs v))\<^sup>+ }
+ \<union> { (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> { (Operator k (index ?ops op))\<^sup>+ | op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }}"
+ by simp
+ (* TODO No idea why this is necessary (apparently only metis unfolds the definition properly). *)
+ moreover have "cnf (encode_positive_transition_frame_axiom \<Pi> k v)
+ = cnf ((Atom (State k (index ?vs v)) \<^bold>\<or> (\<^bold>\<not>(Atom (State (Suc k) (index ?vs v))) \<^bold>\<or> \<^bold>\<Or>?fs)))"
+ unfolding encode_positive_transition_frame_axiom_def
+ by metis
+ (* TODO slow. *)
+ ultimately show ?thesis
+ by blast
+qed
+
+private lemma cnf_of_negative_transition_frame_axiom:
+ "cnf (encode_negative_transition_frame_axiom \<Pi> k v)
+ = {{ (State k (index (strips_problem.variables_of \<Pi>) v))\<inverse>
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }
+ \<union> { (Operator k (index (strips_problem.operators_of \<Pi>) op))\<^sup>+
+ | op. op \<in> set (strips_problem.operators_of \<Pi>) \<and> v \<in> set (delete_effects_of op) }}"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ let ?deleting_operators = "filter (\<lambda>op. ListMem v (delete_effects_of op)) ?ops"
+ let ?fs = "map (\<lambda>op. Atom (Operator k (index ?ops op))) ?deleting_operators"
+ {
+ have "set ?fs = (\<lambda>op. Atom (Operator k (index ?ops op))) ` set ?deleting_operators"
+ using set_map[of "\<lambda>op. Atom (Operator k (index ?ops op))" "?deleting_operators"]
+ by blast
+ (* TODO slow. *)
+ then have "literal_formula_to_literal ` set ?fs
+ = (\<lambda>op. (Operator k (index ?ops op))\<^sup>+) ` set ?deleting_operators"
+ using image_comp[of literal_formula_to_literal "\<lambda>op. Atom (Operator k (index ?ops op))"
+ "set ?deleting_operators"]
+ by simp
+ also have "\<dots> = (\<lambda>op. (Operator k (index ?ops op))\<^sup>+)
+ ` { op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op) }"
+ using set_filter_op_list_mem_vs[of v _ ?ops]
+ by auto
+ (* TODO slow. *)
+ finally have "literal_formula_to_literal ` set ?fs
+ = { (Operator k (index ?ops op))\<^sup>+ | op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op) }"
+ using setcompr_eq_image[of "\<lambda>op. (Operator k (index ?ops op))\<^sup>+"
+ "\<lambda>op. op \<in>set ?deleting_operators"]
+ by blast
+ (* TODO slow. *)
+ hence "cnf (\<^bold>\<Or>?fs) = {{ (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op) }}"
+ using cnf_of_big_or_of_literal_formulas_is[of ?fs]
+ setcompr_eq_image[of literal_formula_to_literal "\<lambda>f. f \<in> set ?fs"]
+ by force
+ }
+ (* TODO slow. *)
+ then have "cnf (Atom (State (Suc k) (index ?vs v)) \<^bold>\<or> \<^bold>\<Or>?fs)
+ = {{ (State (Suc k) (index ?vs v))\<^sup>+ } \<union> { (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op) }}"
+ by force
+ (* TODO slow. *)
+ then have "cnf ((\<^bold>\<not>(Atom (State k (index ?vs v))) \<^bold>\<or> (Atom (State (Suc k) (index ?vs v)) \<^bold>\<or> \<^bold>\<Or>?fs)))
+ = {{ (State k (index ?vs v))\<inverse> }
+ \<union> { (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> { (Operator k (index ?ops op))\<^sup>+ | op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op) }}"
+ by simp
+ (* TODO unfold Let_def + remove metis. *)
+ moreover have "cnf (encode_negative_transition_frame_axiom \<Pi> k v)
+ = cnf ((\<^bold>\<not>(Atom (State k (index ?vs v))) \<^bold>\<or> (Atom (State (Suc k) (index ?vs v)) \<^bold>\<or> \<^bold>\<Or>?fs)))"
+ unfolding encode_negative_transition_frame_axiom_def
+ by metis
+ (* TODO slow. *)
+ ultimately show ?thesis
+ by blast
+qed
+
+lemma cnf_of_encode_all_frame_axioms_structure:
+ "cnf (encode_all_frame_axioms \<Pi> t)
+ = \<Union>(\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ {{{ (State k (index (strips_problem.variables_of \<Pi>) v))\<^sup>+
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<inverse> }
+ \<union> {(Operator k (index (strips_problem.operators_of \<Pi>) op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (add_effects_of op) }}})
+ \<union> \<Union>(\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ {{{ (State k (index (strips_problem.variables_of \<Pi>) v))\<inverse>
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }
+ \<union> { (Operator k (index (strips_problem.operators_of \<Pi>) op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (delete_effects_of op) }}})"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?\<Phi>\<^sub>F = "encode_all_frame_axioms \<Pi> t"
+ let ?l = "List.product [0..<t] ?vs"
+ let ?fs = "map (\<lambda>(k, v). encode_negative_transition_frame_axiom \<Pi> k v) ?l
+ @ map (\<lambda>(k, v). encode_positive_transition_frame_axiom \<Pi> k v) ?l"
+ {
+ let ?A = "{ encode_negative_transition_frame_axiom \<Pi> k v
+ | k v. (k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)) }"
+ and ?B = "{ encode_positive_transition_frame_axiom \<Pi> k v
+ | k v. (k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)) }"
+ have set_l: "set ?l = {..<t} \<times> set ((\<Pi>)\<^sub>\<V>)"
+ using set_product
+ by force
+ (* TODO slow *)
+ have "set ?fs = ?A \<union> ?B"
+ unfolding set_append set_map
+ using encode_all_frame_axioms_set
+ by force
+ then have "cnf ` set ?fs = cnf ` ?A \<union> cnf ` ?B"
+ using image_Un[of cnf "?A" "?B"]
+ by argo
+ moreover {
+ have "?A = (\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ { encode_negative_transition_frame_axiom \<Pi> k v })"
+ by blast
+ then have "cnf ` ?A = (\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ { cnf (encode_negative_transition_frame_axiom \<Pi> k v) })"
+ by blast
+ hence "cnf ` ?A = (\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ {{{ (State k (index ?vs v))\<inverse>
+ , (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> {(Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op)}}})"
+ using cnf_of_negative_transition_frame_axiom[of \<Pi>]
+ by presburger
+ }
+ moreover {
+ have "?B = (\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ { encode_positive_transition_frame_axiom \<Pi> k v})"
+ by blast
+ then have "cnf ` ?B = (\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ { cnf (encode_positive_transition_frame_axiom \<Pi> k v) })"
+ by blast
+ hence "cnf ` ?B = (\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ {{{ (State k (index ?vs v))\<^sup>+
+ , (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> {(Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }}})"
+ using cnf_of_positive_transition_frame_axiom[of \<Pi>]
+ by presburger
+ }
+ (* TODO slow *)
+ ultimately have "cnf ` set ?fs
+ = (\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ {{{ (State k (index ?vs v))\<^sup>+
+ , (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> {(Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (add_effects_of op) }}})
+ \<union> (\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ {{{ (State k (index ?vs v))\<inverse>
+ , (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> {(Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (delete_effects_of op)}}})"
+ unfolding set_append set_map
+ by force
+ }
+ then have "cnf (encode_all_frame_axioms \<Pi> t)
+ = \<Union>((\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ {{{ (State k (index ?vs v))\<^sup>+
+ , (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> {(Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (add_effects_of op) }}})
+ \<union> (\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ {{{ (State k (index ?vs v))\<inverse>
+ , (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> {(Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (delete_effects_of op)}}}))"
+ unfolding encode_all_frame_axioms_def Let_def
+ using cnf_BigAnd[of ?fs]
+ by argo
+ thus ?thesis
+ using Union_Un_distrib[of
+ "(\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ {{{ (State k (index ?vs v))\<^sup>+
+ , (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> {(Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (add_effects_of op) }}})"
+ "(\<Union>(k, v) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<V>)).
+ {{{ (State k (index ?vs v))\<inverse>
+ , (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> {(Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (delete_effects_of op)}}})"]
+ by argo
+qed
+
+\<comment> \<open> A technical lemma used in \isaname{cnf_of_encode_goal_state_set}. \<close>
+private lemma cnf_of_encode_goal_state_set_i:
+ "cnf ((\<Phi>\<^sub>G \<Pi>) t ) = \<Union>({ cnf (encode_state_variable t
+ (index (strips_problem.variables_of \<Pi>) v) (((\<Pi>)\<^sub>G) v))
+ | v. v \<in> set ((\<Pi>)\<^sub>\<V>) \<and> ((\<Pi>)\<^sub>G) v \<noteq> None })"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?G = "(\<Pi>)\<^sub>G"
+ and ?\<Phi>\<^sub>G = "(\<Phi>\<^sub>G \<Pi>) t"
+ let ?fs = "map (\<lambda>v. encode_state_variable t (index ?vs v) (?G v) \<^bold>\<or> \<bottom>)
+ (filter (\<lambda>v. ?G v \<noteq> None) ?vs)"
+ {
+ have "cnf ` set ?fs = cnf ` (\<lambda>v. encode_state_variable t (index ?vs v) (?G v) \<^bold>\<or> \<bottom>)
+ ` { v | v. v \<in> set ?vs \<and> ?G v \<noteq> None }"
+ unfolding set_map
+ by force
+ also have "\<dots> = (\<lambda>v. cnf (encode_state_variable t (index ?vs v) (?G v) \<^bold>\<or> \<bottom>))
+ ` { v | v. v \<in> set ?vs \<and> ?G v \<noteq> None }"
+ using image_comp[of cnf "(\<lambda>v. encode_state_variable t (index ?vs v) (?G v) \<^bold>\<or> \<bottom>)"
+ "{ v | v. v \<in> set ?vs \<and> ?G v \<noteq> None }"]
+ by fast
+ finally have "cnf ` set ?fs = { cnf (encode_state_variable t (index ?vs v) (?G v))
+ | v. v \<in> set ?vs \<and> ?G v \<noteq> None }"
+ unfolding setcompr_eq_image[of "\<lambda>v. cnf (encode_state_variable t (index ?vs v) (?G v) \<^bold>\<or> \<bottom>)"]
+ by auto
+ }
+ moreover have "cnf ((\<Phi>\<^sub>G \<Pi>) t) = \<Union> (cnf ` set ?fs)"
+ unfolding encode_goal_state_def SAT_Plan_Base.encode_goal_state_def Let_def
+ using cnf_BigAnd[of ?fs]
+ by force
+ ultimately show ?thesis
+ by simp
+qed
+
+\<comment> \<open> A simplification lemma for the above one. \<close>
+(* TODO Replace above lemma with this?. *)
+corollary cnf_of_encode_goal_state_set_ii:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "cnf ((\<Phi>\<^sub>G \<Pi>) t) = \<Union>({{{ literal_formula_to_literal
+ (encode_state_variable t (index (strips_problem.variables_of \<Pi>) v) (((\<Pi>)\<^sub>G) v)) }}
+ | v. v \<in> set ((\<Pi>)\<^sub>\<V>) \<and> ((\<Pi>)\<^sub>G) v \<noteq> None })"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?G = "(\<Pi>)\<^sub>G"
+ and ?\<Phi>\<^sub>G = "(\<Phi>\<^sub>G \<Pi>) t"
+ {
+ fix v
+ assume "v \<in> { v | v. v \<in> set ((\<Pi>)\<^sub>\<V>) \<and> ?G v \<noteq> None }"
+ then have "v \<in> set ((\<Pi>)\<^sub>\<V>)" and G_of_v_is_not_None: "?G v \<noteq> None"
+ by fast+
+ then consider (A) "?G v = Some True"
+ | (B) "?G v = Some False"
+ by fastforce
+ hence "cnf (encode_state_variable t (index ?vs v) (?G v))
+ = {{ literal_formula_to_literal (encode_state_variable t (index ?vs v) (?G v)) }}"
+ unfolding encode_state_variable_def
+ by (cases, force+)
+ } note nb = this
+ have "cnf ?\<Phi>\<^sub>G = \<Union>({ cnf (encode_state_variable t (index ?vs v) (?G v))
+ | v. v \<in> set ((\<Pi>)\<^sub>\<V>) \<and> ?G v \<noteq> None })"
+ unfolding cnf_of_encode_goal_state_set_i
+ by blast
+ also have "\<dots> = \<Union>((\<lambda>v. cnf (encode_state_variable t (index ?vs v) (((\<Pi>)\<^sub>G) v)))
+ ` { v | v. v \<in> set ((\<Pi>)\<^sub>\<V>) \<and> ((\<Pi>)\<^sub>G) v \<noteq> None })"
+ using setcompr_eq_image[of
+ "\<lambda>v. cnf (encode_state_variable t (index ?vs v) (((\<Pi>)\<^sub>G) v))"
+ "\<lambda>v. v \<in> set ((\<Pi>)\<^sub>\<V>) \<and> ((\<Pi>)\<^sub>G) v \<noteq> None"]
+ by presburger
+ also have "\<dots> = \<Union>((\<lambda>v. {{ literal_formula_to_literal
+ (encode_state_variable t (index ?vs v) (?G v)) }})
+ ` { v. v \<in> set ((\<Pi>)\<^sub>\<V>) \<and> ((\<Pi>)\<^sub>G) v \<noteq> None })"
+ using nb
+ by simp
+ finally show ?thesis
+ unfolding nb
+ by auto
+qed
+
+\<comment> \<open> This lemma essentially states that the cnf for the cnf formula for the encoding has a
+clause for each variable whose state is defined in the goal state with the corresponding literal. \<close>
+(* TODO is \<open>\<exists>!\<close> still needed? *)
+lemma cnf_of_encode_goal_state_set:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "v \<in> dom ((\<Pi>)\<^sub>G)"
+ shows "((\<Pi>)\<^sub>G) v = Some True \<longrightarrow> (\<exists>!C. C \<in> cnf ((\<Phi>\<^sub>G \<Pi>) t)
+ \<and> C = { (State t (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ })"
+ and "((\<Pi>)\<^sub>G) v = Some False \<longrightarrow> (\<exists>!C. C \<in> cnf ((\<Phi>\<^sub>G \<Pi>) t)
+ \<and> C = { (State t (index (strips_problem.variables_of \<Pi>) v))\<inverse> })"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?G = "(\<Pi>)\<^sub>G"
+ and ?\<Phi>\<^sub>G = "(\<Phi>\<^sub>G \<Pi>) t"
+ have nb\<^sub>1: "cnf ?\<Phi>\<^sub>G = \<Union> { cnf (encode_state_variable t (index ?vs v)
+ (?G v)) | v. v \<in> set ((\<Pi>)\<^sub>\<V>) \<and> ?G v \<noteq> None }"
+ unfolding cnf_of_encode_goal_state_set_i
+ by auto
+ have nb\<^sub>2: "v \<in> { v. v \<in> set ((\<Pi>)\<^sub>\<V>) \<and> ?G v \<noteq> None }"
+ using is_valid_problem_dom_of_goal_state_is assms(1, 2)
+ by auto
+ have nb\<^sub>3: "cnf (encode_state_variable t (index (strips_problem.variables_of \<Pi>) v) (((\<Pi>)\<^sub>G) v))
+ \<subseteq> (\<Union>{ cnf (encode_state_variable t (index ?vs v)
+ (?G v)) | v. v \<in> set ((\<Pi>)\<^sub>\<V>) \<and> ?G v \<noteq> None })"
+ using UN_upper[OF nb\<^sub>2, of "\<lambda>v. cnf (encode_state_variable t (index ?vs v) (?G v))"] nb\<^sub>2
+ by blast
+ show "((\<Pi>)\<^sub>G) v = Some True \<longrightarrow> (\<exists>!C. C \<in> cnf ((\<Phi>\<^sub>G \<Pi>) t)
+ \<and> C = { (State t (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ })"
+ and "((\<Pi>)\<^sub>G) v = Some False \<longrightarrow> (\<exists>!C. C \<in> cnf ((\<Phi>\<^sub>G \<Pi>) t)
+ \<and> C = { (State t (index (strips_problem.variables_of \<Pi>) v))\<inverse> })"
+ using nb\<^sub>3
+ unfolding nb\<^sub>1 encode_state_variable_def
+ by auto+
+qed
+
+end
+
+
+text \<open> We omit the proofs that the partial encoding functions produce formulas in CNF form due to
+their more technical nature.
+The following sublocale proof confirms that definition \ref{isadef:encode-problem-sat-plan-base}
+encodes a valid problem \<^term>\<open>\<Pi>\<close> into a formula that can be transformed to CNF
+(\<^term>\<open>is_cnf (\<Phi> \<Pi> t)\<close>) and that its CNF has the required form. \<close>
+
+
+subsection "Soundness of the Basic SATPlan Algorithm"
+
+
+lemma valuation_models_encoding_cnf_formula_equals:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "\<A> \<Turnstile> \<Phi> \<Pi> t = cnf_semantics \<A> (cnf (\<Phi> \<Pi> t))"
+proof -
+ let ?\<Phi> = "\<Phi> \<Pi> t"
+ {
+ have "is_cnf ?\<Phi>"
+ using is_cnf_encode_problem[OF assms].
+ hence "is_nnf ?\<Phi>"
+ using is_nnf_cnf
+ by blast
+ }
+ thus ?thesis
+ using cnf_semantics[of ?\<Phi> \<A>]
+ by blast
+qed
+
+(* TODO refactor *)
+corollary valuation_models_encoding_cnf_formula_equals_corollary:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "\<A> \<Turnstile> (\<Phi> \<Pi> t)
+ = (\<forall>C \<in> cnf (\<Phi> \<Pi> t). \<exists>L \<in> C. lit_semantics \<A> L)"
+ using valuation_models_encoding_cnf_formula_equals[OF assms]
+ unfolding cnf_semantics_def clause_semantics_def encode_problem_def
+ by presburger
+
+\<comment> \<open> A couple of technical lemmas about \<open>decode_plan\<close>. \<close>
+lemma decode_plan_length:
+ assumes "\<pi> = \<Phi>\<inverse> \<Pi> \<nu> t"
+ shows "length \<pi> = t"
+ using assms
+ unfolding decode_plan_def SAT_Plan_Base.decode_plan_def
+ by simp
+
+lemma decode_plan'_set_is[simp]:
+ "set (decode_plan' \<Pi> \<A> k)
+ = { (strips_problem.operators_of \<Pi>) ! (index (strips_problem.operators_of \<Pi>) op)
+ | op. op \<in> set (strips_problem.operators_of \<Pi>)
+ \<and> \<A> (Operator k (index (strips_problem.operators_of \<Pi>) op)) }"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ let ?f = "\<lambda>op. Operator k (index ?ops op)"
+ let ?vs = "map ?f ?ops"
+ {
+ have "set (filter \<A> ?vs) = set (map ?f (filter (\<A> \<circ> ?f) ?ops))"
+ unfolding filter_map[of \<A> "\<lambda>op. Operator k (index ?ops op)" ?ops]..
+ hence "set (filter \<A> ?vs) = (\<lambda>op. Operator k (index ?ops op)) `
+ { op \<in> set ?ops. \<A> (Operator k (index ?ops op)) }"
+ unfolding set_map set_filter
+ by simp
+ }
+ have "set (decode_plan' \<Pi> \<A> k) = (\<lambda>v. case v of Operator k i \<Rightarrow> ?ops ! i)
+ ` (\<lambda>op. Operator k (index ?ops op)) ` { op \<in> set ?ops. \<A> (Operator k (index ?ops op)) }"
+ unfolding decode_plan'_def set_map Let_def
+ by auto
+ also have "\<dots> = (\<lambda>op. case Operator k (index ?ops op) of Operator k i \<Rightarrow> ?ops ! i)
+ ` { op \<in> set ?ops. \<A> (Operator k (index ?ops op)) }"
+ unfolding image_comp comp_apply
+ by argo
+ also have "\<dots> = (\<lambda>op. ?ops ! (index ?ops op))
+ ` { op \<in> set ?ops. \<A> (Operator k (index ?ops op)) }"
+ by force
+ finally show ?thesis
+ by blast
+qed
+
+lemma decode_plan_set_is[simp]:
+ "set (\<Phi>\<inverse> \<Pi> \<A> t) = (\<Union>k \<in> {..<t}. { decode_plan' \<Pi> \<A> k })"
+ unfolding decode_plan_def SAT_Plan_Base.decode_plan_def set_map
+ using atLeast_upt
+ by blast
+
+lemma decode_plan_step_element_then_i:
+ assumes "k < t"
+ shows "set ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)
+ = { (strips_problem.operators_of \<Pi>) ! (index (strips_problem.operators_of \<Pi>) op)
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> \<A> (Operator k (index (strips_problem.operators_of \<Pi>) op)) }"
+proof -
+ have "(\<Phi>\<inverse> \<Pi> \<A> t) ! k = decode_plan' \<Pi> \<A> k"
+ unfolding decode_plan_def SAT_Plan_Base.decode_plan_def
+ using assms
+ by simp
+ thus ?thesis
+ by force
+qed
+
+\<comment> \<open> Show that each operator $op$ in the $k$-th parallel operator in a decoded parallel plan is
+contained within the problem's operator set and the valuation is true for the corresponding SATPlan
+variable. \<close>
+lemma decode_plan_step_element_then:
+ fixes \<Pi>::"'a strips_problem"
+ assumes "k < t"
+ and "op \<in> set ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+ shows "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ and "\<A> (Operator k (index (strips_problem.operators_of \<Pi>) op))"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ let ?Ops = "{ ?ops ! (index ?ops op)
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> \<A> (Operator k (index ?ops op)) }"
+ have "op \<in> ?Ops"
+ using assms(2)
+ unfolding decode_plan_step_element_then_i[OF assms(1)] assms
+ by blast
+ moreover have "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ and "\<A> (Operator k (index ?ops op))"
+ using calculation
+ by fastforce+
+ ultimately show "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ and "\<A> (Operator k (index ?ops op))"
+ by blast+
+qed
+
+\<comment> \<open> Show that the \<open>k\<close>-th parallel operators of the decoded plan are distinct lists (i.e. do not
+contain duplicates). \<close>
+lemma decode_plan_step_distinct:
+ assumes "k < t"
+ shows "distinct ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?\<pi>\<^sub>k = "(\<Phi>\<inverse> \<Pi> \<A> t) ! k"
+ let ?f = "\<lambda>op. Operator k (index ?ops op)"
+ and ?g = "\<lambda>v. case v of Operator _ k \<Rightarrow> ?ops ! k"
+ let ?vs = "map ?f (remdups ?ops)"
+ have nb\<^sub>1: "?\<pi>\<^sub>k = decode_plan' \<Pi> \<A> k"
+ unfolding decode_plan_def SAT_Plan_Base.decode_plan_def
+ using assms
+ by fastforce
+ {
+ have "distinct (remdups ?ops)"
+ by blast
+ moreover have "inj_on ?f (set (remdups ?ops))"
+ unfolding inj_on_def
+ by fastforce
+ ultimately have "distinct ?vs"
+ using distinct_map
+ by blast
+ } note nb\<^sub>2 = this
+ {
+ have "inj_on ?g (set ?vs)"
+ unfolding inj_on_def
+ by fastforce
+ hence "distinct (map ?g ?vs)"
+ using distinct_map nb\<^sub>2
+ by blast
+ }
+ thus ?thesis
+ using distinct_map_filter[of ?g ?vs \<A>]
+ unfolding nb\<^sub>1 decode_plan'_def Let_def
+ by argo
+qed
+
+lemma decode_state_at_valid_variable:
+ fixes \<Pi> :: "'a strips_problem"
+ assumes "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k) v \<noteq> None"
+ shows "v \<in> set ((\<Pi>)\<^sub>\<V>)"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ let ?f = "\<lambda>v. (v,\<A> (State k (index ?vs v)))"
+ {
+ have "fst ` set (map ?f ?vs) = fst ` (\<lambda>v. (v,\<A> (State k (index ?vs v)))) ` set ?vs"
+ by force
+ also have "\<dots> = (\<lambda>v. fst (v,\<A> (State k (index ?vs v)))) ` set ?vs"
+ by blast
+ finally have "fst ` set (map ?f ?vs) = set ?vs"
+ by auto
+ }
+ moreover have "\<not>v \<notin> fst ` set (map ?f ?vs)"
+ using map_of_eq_None_iff[of "map ?f ?vs" v] assms
+ unfolding decode_state_at_def SAT_Plan_Base.decode_state_at_def
+ by meson
+ ultimately show ?thesis
+ by fastforce
+qed
+
+\<comment> \<open> Show that there exists an equivalence between a model \<open>\<A>\<close> of the (CNF of the) encoded
+problem and the state at step \<open>k\<close> decoded from the encoded problem. \<close>
+lemma decode_state_at_encoding_variables_equals_some_of_valuation_if:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ and "k \<le> t"
+ and "v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ shows "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k) v
+ = Some (\<A> (State k (index (strips_problem.variables_of \<Pi>) v)))"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ let ?l = "map (\<lambda>x. (x,\<A> (State k (index ?vs x)))) ?vs"
+ have "set ?vs \<noteq> {}"
+ using assms(4)
+ by fastforce
+ then have "map_of ?l v = Some (\<A> (State k (index ?vs v)))"
+ using map_of_from_function_graph_is_some_if[of ?vs v
+ "\<lambda>v. \<A> (State k (index ?vs v))"] assms(4)
+ by fastforce
+ thus ?thesis
+ unfolding decode_state_at_def SAT_Plan_Base.decode_state_at_def
+ by meson
+qed
+
+lemma decode_state_at_dom:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "dom (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k) = set ((\<Pi>)\<^sub>\<V>)"
+proof-
+ let ?s = "\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ have "dom ?s = fst ` set (map (\<lambda>v. (v, \<A> (State k (index ?vs v)))) ?vs)"
+ unfolding decode_state_at_def SAT_Plan_Base.decode_state_at_def
+ using dom_map_of_conv_image_fst[of "(map (\<lambda>v. (v, \<A> (State k (index ?vs v)))) ?vs)"]
+ by meson
+ also have "\<dots> = fst ` (\<lambda>v. (v, \<A> (State k (index ?vs v)))) ` set ((\<Pi>)\<^sub>\<V>)"
+ using set_map[of "(\<lambda>v. (v, \<A> (State k (index ?vs v))))" ?vs]
+ by simp
+ also have "\<dots> = (fst \<circ> (\<lambda>v. (v, \<A> (State k (index ?vs v))))) ` set ((\<Pi>)\<^sub>\<V>)"
+ using image_comp[of fst "(\<lambda>v. (v, \<A> (State k (index ?vs v))))"]
+ by presburger
+ finally show ?thesis
+ by force
+qed
+
+(* TODO shorten the proof (there are a lot of duplicate parts still!). *)
+lemma decode_state_at_initial_state:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ shows "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> 0) = (\<Pi>)\<^sub>I"
+proof -
+ let ?I = "(\<Pi>)\<^sub>I"
+ let ?s = "\<Phi>\<^sub>S\<inverse> \<Pi> \<A> 0"
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ let ?\<Phi> = "\<Phi> \<Pi> t"
+ let ?\<Phi>\<^sub>I = "\<Phi>\<^sub>I \<Pi>"
+ {
+ have "is_cnf ?\<Phi>\<^sub>I" and "cnf ?\<Phi>\<^sub>I \<subseteq> cnf ?\<Phi>"
+ subgoal
+ using is_cnf_encode_initial_state[OF assms(1)]
+ by simp
+ subgoal
+ using cnf_of_encode_problem_structure(1)
+ unfolding encode_initial_state_def encode_problem_def
+ by blast
+ done
+ then have "cnf_semantics \<A> (cnf ?\<Phi>\<^sub>I)"
+ using cnf_semantics_monotonous_in_cnf_subsets_if is_cnf_encode_problem[OF assms(1)]
+ assms(2)
+ by blast
+ hence "\<forall>C \<in> cnf ?\<Phi>\<^sub>I. clause_semantics \<A> C"
+ unfolding cnf_semantics_def encode_initial_state_def
+ by blast
+ } note nb\<^sub>1 = this
+ {
+ (* TODO refactor. *)
+ {
+ fix v
+ assume v_in_dom_i: "v \<in> dom ?I"
+ moreover {
+ have v_in_variable_set: "v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ using is_valid_problem_strips_initial_of_dom assms(1) v_in_dom_i
+ by auto
+ hence "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> 0) v = Some (\<A> (State 0 (index ?vs v)))"
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if[OF
+ assms(1, 2) _ v_in_variable_set]
+ by fast
+ } note nb\<^sub>2 = this
+ consider (v_initially_true) "?I v = Some True"
+ | (v_initially_false) "?I v = Some False"
+ using v_in_dom_i
+ by fastforce
+ hence "?I v = ?s v"
+ proof (cases)
+ case v_initially_true
+ then obtain C
+ where "C \<in> cnf ?\<Phi>\<^sub>I"
+ and c_is: "C = { (State 0 (index ?vs v))\<^sup>+ }"
+ using cnf_of_encode_initial_state_set v_in_dom_i assms(1)
+ by fastforce
+ hence "\<A> (State 0 (index ?vs v)) = True"
+ using nb\<^sub>1
+ unfolding clause_semantics_def
+ by fastforce
+ thus ?thesis
+ using nb\<^sub>2 v_initially_true
+ by presburger
+ next
+ case v_initially_false
+ (* TODO slow *)
+ then obtain C
+ where "C \<in> cnf ?\<Phi>\<^sub>I"
+ and c_is: "C = { (State 0 (index ?vs v))\<inverse> }"
+ using cnf_of_encode_initial_state_set assms(1) v_in_dom_i
+ by fastforce
+ hence "\<A> (State 0 (index ?vs v)) = False"
+ using nb\<^sub>1
+ unfolding clause_semantics_def
+ by fastforce
+ thus ?thesis
+ using nb\<^sub>2 v_initially_false
+ by presburger
+ qed
+ }
+ hence "?I \<subseteq>\<^sub>m ?s"
+ using map_le_def
+ by blast
+ } moreover {
+ {
+ fix v
+ assume v_in_dom_s: "v \<in> dom ?s"
+ then have v_in_set_vs: "v \<in> set ?vs"
+ using decode_state_at_dom[OF assms(1)]
+ by simp
+ have v_in_dom_I: "v \<in> dom ?I"
+ using is_valid_problem_strips_initial_of_dom assms(1) v_in_set_vs
+ by auto
+ have s_v_is: "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> 0) v = Some (\<A> (State 0 (index ?vs v)))"
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if assms(1, 2)
+ v_in_set_vs
+ by (metis le0)
+ consider (s_v_is_some_true) "?s v = Some True"
+ | (s_v_is_some_false) "?s v = Some False"
+ using v_in_dom_s
+ by fastforce
+ hence "?s v = ?I v"
+ proof (cases)
+ case s_v_is_some_true
+ then have \<A>_of_s_v: "lit_semantics \<A> ((State 0 (index ?vs v))\<^sup>+)"
+ using s_v_is
+ by fastforce
+ consider (I_v_is_some_true) "?I v = Some True"
+ | (I_v_is_some_false) "?I v = Some False"
+ using v_in_dom_I
+ by fastforce
+ thus ?thesis
+ proof (cases)
+ case I_v_is_some_true
+ then show ?thesis
+ using s_v_is_some_true
+ by argo
+ next
+ case I_v_is_some_false
+ (* TODO slow *)
+ then obtain C
+ where C_in_encode_initial_state: "C \<in> cnf ?\<Phi>\<^sub>I"
+ and C_is: "C = { (State 0 (index ?vs v))\<inverse> }"
+ using cnf_of_encode_initial_state_set assms(1) v_in_dom_I
+ by fastforce
+ hence "lit_semantics \<A> ((State 0 (index ?vs v))\<inverse>)"
+ using nb\<^sub>1
+ unfolding clause_semantics_def
+ by fast
+ thus ?thesis
+ using \<A>_of_s_v
+ by fastforce
+ qed
+ next
+ case s_v_is_some_false
+ then have \<A>_of_s_v: "lit_semantics \<A> ((State 0 (index ?vs v))\<inverse>)"
+ using s_v_is
+ by fastforce
+ consider (I_v_is_some_true) "?I v = Some True"
+ | (I_v_is_some_false) "?I v = Some False"
+ using v_in_dom_I
+ by fastforce
+ thus ?thesis
+ proof (cases)
+ case I_v_is_some_true
+ then obtain C
+ where C_in_encode_initial_state: "C \<in> cnf ?\<Phi>\<^sub>I"
+ and C_is: "C = { (State 0 (index ?vs v))\<^sup>+ }"
+ using cnf_of_encode_initial_state_set assms(1) v_in_dom_I
+ by fastforce
+ hence "lit_semantics \<A> ((State 0 (index ?vs v))\<^sup>+)"
+ using nb\<^sub>1
+ unfolding clause_semantics_def
+ by fast
+ thus ?thesis
+ using \<A>_of_s_v
+ by fastforce
+ next
+ case I_v_is_some_false
+ thus ?thesis
+ using s_v_is_some_false
+ by presburger
+ qed
+ qed
+ }
+ hence "?s \<subseteq>\<^sub>m ?I"
+ using map_le_def
+ by blast
+ } ultimately show ?thesis
+ using map_le_antisym
+ by blast
+qed
+
+lemma decode_state_at_goal_state:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ shows "(\<Pi>)\<^sub>G \<subseteq>\<^sub>m \<Phi>\<^sub>S\<inverse> \<Pi> \<A> t"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?G = "(\<Pi>)\<^sub>G"
+ and ?G' = "\<Phi>\<^sub>S\<inverse> \<Pi> \<A> t"
+ and ?\<Phi> = "\<Phi> \<Pi> t"
+ and ?\<Phi>\<^sub>G = "(\<Phi>\<^sub>G \<Pi>) t"
+ {
+ have "is_cnf ?\<Phi>\<^sub>G" and "cnf ?\<Phi>\<^sub>G \<subseteq> cnf ?\<Phi>"
+ subgoal
+ using encode_goal_state_is_cnf[OF assms(1)]
+ by simp
+ subgoal
+ using cnf_of_encode_problem_structure(2)
+ unfolding encode_goal_state_def encode_problem_def
+ by blast
+ done
+ then have "cnf_semantics \<A> (cnf ?\<Phi>\<^sub>G)"
+ using cnf_semantics_monotonous_in_cnf_subsets_if is_cnf_encode_problem[OF assms(1)]
+ assms(2)
+ by blast
+ hence "\<forall>C \<in> cnf ?\<Phi>\<^sub>G. clause_semantics \<A> C"
+ unfolding cnf_semantics_def encode_initial_state_def
+ by blast
+ } note nb\<^sub>1 = this
+ (* TODO refactor. *)
+ {
+ fix v
+ assume "v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ moreover have "set ?vs \<noteq> {}"
+ using calculation(1)
+ by fastforce
+ moreover have "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> t)
+ = map_of (map (\<lambda>v. (v, \<A> (State t (index ?vs v)))) ?vs)"
+ unfolding decode_state_at_def SAT_Plan_Base.decode_state_at_def
+ by metis
+ (* TODO slow. *)
+ ultimately have "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> t) v = Some (\<A> (State t (index ?vs v)))"
+ using map_of_from_function_graph_is_some_if
+ by fastforce
+ } note nb\<^sub>2 = this
+ {
+ fix v
+ assume v_in_dom_G: "v \<in> dom ?G"
+ then have v_in_vs: "v \<in> set ?vs"
+ using is_valid_problem_dom_of_goal_state_is assms(1)
+ by auto
+ then have decode_state_at_is: "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> t) v = Some (\<A> (State t (index ?vs v)))"
+ using nb\<^sub>2
+ by fastforce
+ consider (A) "?G v = Some True"
+ | (B) "?G v = Some False"
+ using v_in_dom_G
+ by fastforce
+ hence "?G v = ?G' v"
+ proof (cases)
+ case A
+ {
+ obtain C where "C \<subseteq> cnf ?\<Phi>\<^sub>G" and "C = {{ (State t (index ?vs v))\<^sup>+ }}"
+ using cnf_of_encode_goal_state_set(1)[OF assms(1) v_in_dom_G] A
+ by auto
+ then have "{ (State t (index ?vs v))\<^sup>+ } \<in> cnf ?\<Phi>\<^sub>G"
+ by blast
+ then have "clause_semantics \<A> { (State t (index ?vs v))\<^sup>+ }"
+ using nb\<^sub>1
+ by blast
+ then have "lit_semantics \<A> ((State t (index ?vs v))\<^sup>+)"
+ unfolding clause_semantics_def
+ by blast
+ hence "\<A> (State t (index ?vs v)) = True"
+ by force
+ }
+ thus ?thesis
+ using decode_state_at_is A
+ by presburger
+ next
+ case B
+ {
+ obtain C where "C \<subseteq> cnf ?\<Phi>\<^sub>G" and "C = {{ (State t (index ?vs v))\<inverse> }}"
+ using cnf_of_encode_goal_state_set(2)[OF assms(1) v_in_dom_G] B
+ by auto
+ then have "{ (State t (index ?vs v))\<inverse> } \<in> cnf ?\<Phi>\<^sub>G"
+ by blast
+ then have "clause_semantics \<A> { (State t (index ?vs v))\<inverse> }"
+ using nb\<^sub>1
+ by blast
+ then have "lit_semantics \<A> ((State t (index ?vs v))\<inverse>)"
+ unfolding clause_semantics_def
+ by blast
+ hence "\<A> (State t (index ?vs v)) = False"
+ by simp
+ }
+ thus ?thesis
+ using decode_state_at_is B
+ by presburger
+ qed
+ }
+ thus ?thesis
+ using map_le_def
+ by blast
+qed
+
+\<comment> \<open> Show that the operator activation implies precondition constraints hold at every time step
+of the decoded plan. \<close>
+lemma decode_state_at_preconditions:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ and "k < t"
+ and "op \<in> set ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+ and "v \<in> set (precondition_of op)"
+ shows "\<A> (State k (index (strips_problem.variables_of \<Pi>) v))"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?\<Phi> = "\<Phi> \<Pi> t"
+ and ?\<Phi>\<^sub>O = "encode_operators \<Pi> t"
+ and ?\<Phi>\<^sub>P = "encode_all_operator_preconditions \<Pi> ?ops t"
+ {
+ have "\<A> (Operator k (index ?ops op))"
+ and "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using decode_plan_step_element_then[OF assms(3, 4)]
+ by blast+
+ moreover obtain C
+ where clause_is_in_operator_encoding: "C \<in> cnf ?\<Phi>\<^sub>P"
+ and "C = { (Operator k (index ?ops op))\<inverse>,
+ (State k (index ?vs v))\<^sup>+ }"
+ using cnf_of_encode_all_operator_preconditions_contains_clause_if[OF assms(1, 3)
+ calculation(2) assms(5)]
+ by blast
+ moreover have clause_semantics_\<A>_\<Phi>\<^sub>P: "\<forall>C \<in> cnf ?\<Phi>\<^sub>P. clause_semantics \<A> C"
+ using cnf_semantics_monotonous_in_cnf_subsets_if[OF assms(2)
+ is_cnf_encode_problem[OF assms(1)]
+ cnf_of_operator_precondition_encoding_subset_encoding]
+ unfolding cnf_semantics_def
+ by blast
+ (* TODO slow step *)
+ ultimately have "lit_semantics \<A> (Pos (State k (index ?vs v)))"
+ unfolding clause_semantics_def
+ by fastforce
+ }
+ thus ?thesis
+ unfolding lit_semantics_def
+ by fastforce
+qed
+
+\<comment> \<open> This lemma shows that for a problem encoding with makespan zero for which a model exists,
+the goal state encoding must be subset of the initial state encoding. In this case, the state
+variable encodings for the goal state are included in the initial state encoding. \<close>
+(* TODO simplify/refactor proof. *)
+lemma encode_problem_parallel_correct_i:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> 0"
+ shows "cnf ((\<Phi>\<^sub>G \<Pi>) 0) \<subseteq> cnf (\<Phi>\<^sub>I \<Pi>)"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?I = "(\<Pi>)\<^sub>I"
+ and ?G = "(\<Pi>)\<^sub>G"
+ and ?\<Phi>\<^sub>I = "\<Phi>\<^sub>I \<Pi>"
+ and ?\<Phi>\<^sub>G = "(\<Phi>\<^sub>G \<Pi>) 0"
+ and ?\<Phi> = "\<Phi> \<Pi> 0"
+ (* TODO refactor and generalize for all partial encodings? *)
+ \<comment> \<open> Show that the model of the encoding is also a model of the partial encodings. \<close>
+ have \<A>_models_\<Phi>\<^sub>I: "\<A> \<Turnstile> ?\<Phi>\<^sub>I" and \<A>_models_\<Phi>\<^sub>G: "\<A> \<Turnstile> ?\<Phi>\<^sub>G"
+ using assms(2) encode_problem_has_model_then_also_partial_encodings(1, 2)
+ unfolding encode_problem_def encode_initial_state_def encode_goal_state_def
+ by blast+
+ \<comment> \<open> Show that every clause in the CNF of the goal state encoding @{text "\<Phi>\<^sub>G"} is also in
+ the CNF of the initial state encoding @{text "\<Phi>\<^sub>I"} thus making it a subset. We can conclude this
+ from the fact that both @{text "\<Phi>\<^sub>I"} and @{text "\<Phi>\<^sub>G"} contain singleton clauses—which must all
+ be evaluated to true by the given model \<open>\<A>\<close>—and the similar structure of the clauses in both
+ partial encodings.
+
+ By extension, if we decode the goal state @{text "G"} and the initial state @{text "I"} from a
+ model of the encoding, @{text "G v = I v"} must hold for variable @{text "v"} in the domain of
+ the goal state. \<close>
+ {
+ fix C'
+ assume C'_in_cnf_\<Phi>\<^sub>G: "C' \<in> cnf ?\<Phi>\<^sub>G"
+ then obtain v
+ where v_in_vs: "v \<in> set ?vs"
+ and G_of_v_is_not_None: "?G v \<noteq> None"
+ and C'_is: "C' = { literal_formula_to_literal (encode_state_variable 0 (index ?vs v)
+ (?G v)) }"
+ using cnf_of_encode_goal_state_set_ii[OF assms(1)]
+ by auto
+ obtain C
+ where C_in_cnf_\<Phi>\<^sub>I: "C \<in> cnf ?\<Phi>\<^sub>I"
+ and C_is: "C = { literal_formula_to_literal (encode_state_variable 0 (index ?vs v)
+ (?I v)) }"
+ using cnf_of_encode_initial_state_set_ii[OF assms(1)] v_in_vs
+ by auto
+ {
+ let ?L = "literal_formula_to_literal (encode_state_variable 0 (index ?vs v) (?I v))"
+ have "{ ?L } \<in> cnf ?\<Phi>\<^sub>I"
+ using C_in_cnf_\<Phi>\<^sub>I C_is
+ by blast
+ hence "lit_semantics \<A> ?L"
+ using model_then_all_singleton_clauses_modelled[OF
+ is_cnf_encode_initial_state[OF assms(1)]_ \<A>_models_\<Phi>\<^sub>I]
+ by blast
+ } note lit_semantics_\<A>_L = this
+ {
+ let ?L' = "literal_formula_to_literal (encode_state_variable 0 (index ?vs v) (?G v))"
+ have "{ ?L' } \<in> cnf ?\<Phi>\<^sub>G"
+ using C'_in_cnf_\<Phi>\<^sub>G C'_is
+ by blast
+ hence "lit_semantics \<A> ?L'"
+ using model_then_all_singleton_clauses_modelled[OF
+ encode_goal_state_is_cnf[OF assms(1)]_ \<A>_models_\<Phi>\<^sub>G]
+ by blast
+ } note lit_semantics_\<A>_L' = this
+ {
+ have "?I v = ?G v"
+ proof (rule ccontr)
+ assume contradiction: "?I v \<noteq> ?G v"
+ moreover have "?I v \<noteq> None"
+ using v_in_vs is_valid_problem_strips_initial_of_dom assms(1)
+ by auto
+ ultimately consider (A) "?I v = Some True \<and> ?G v = Some False"
+ | (B) "?I v = Some False \<and> ?G v = Some True"
+ using G_of_v_is_not_None
+ by force
+ thus False
+ using lit_semantics_\<A>_L lit_semantics_\<A>_L'
+ unfolding encode_state_variable_def
+ by (cases, fastforce+)
+ qed
+ }
+ hence "C' \<in> cnf ?\<Phi>\<^sub>I"
+ using C_is C_in_cnf_\<Phi>\<^sub>I C'_is C'_in_cnf_\<Phi>\<^sub>G
+ by argo
+ }
+ thus ?thesis
+ by blast
+qed
+
+\<comment> \<open> Show that the encoding secures that for every parallel operator \<open>ops\<close>
+decoded from the plan at every time step \<open>t < length pi\<close> the following hold:
+\begin{enumerate}
+\item \<open>ops\<close> is applicable, and
+\item the effects of \<open>ops\<close> are consistent.
+\end{enumerate}\<close>
+lemma encode_problem_parallel_correct_ii:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ and "k < length (\<Phi>\<inverse> \<Pi> \<A> t)"
+ shows "are_all_operators_applicable (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k)
+ ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+ and "are_all_operator_effects_consistent ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?\<pi> = "\<Phi>\<inverse> \<Pi> \<A> t"
+ and ?s = "\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k"
+ let ?\<Phi> = "\<Phi> \<Pi> t"
+ and ?\<Phi>\<^sub>E = "encode_all_operator_effects \<Pi> ?ops t"
+ have k_lt_t: "k < t"
+ using decode_plan_length assms(3)
+ by metis
+ {
+ {
+ fix op v
+ assume op_in_kth_of_decoded_plan_set: "op \<in> set (?\<pi> ! k)"
+ and v_in_precondition_set: "v \<in> set (precondition_of op)"
+ {
+ have "\<A> (Operator k (index ?ops op))"
+ using decode_plan_step_element_then[OF k_lt_t op_in_kth_of_decoded_plan_set]
+ by blast
+ hence "\<A> (State k (index ?vs v))"
+ using decode_state_at_preconditions[
+ OF assms(1, 2) _ op_in_kth_of_decoded_plan_set v_in_precondition_set] k_lt_t
+ by blast
+ }
+ moreover have "k \<le> t"
+ using k_lt_t
+ by auto
+ moreover {
+ have "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using decode_plan_step_element_then[OF k_lt_t op_in_kth_of_decoded_plan_set]
+ by simp
+ then have "v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ using is_valid_problem_strips_operator_variable_sets(1) assms(1)
+ v_in_precondition_set
+ by auto
+ }
+ ultimately have "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k) v = Some True"
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if[OF assms(1, 2)]
+ by presburger
+ }
+ hence "are_all_operators_applicable ?s (?\<pi> ! k)"
+ using are_all_operators_applicable_set[of ?s "?\<pi> ! k"]
+ by blast
+ } moreover {
+ {
+ fix op\<^sub>1 op\<^sub>2
+ assume op\<^sub>1_in_k_th_of_decoded_plan: "op\<^sub>1 \<in> set ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+ and op\<^sub>2_in_k_th_of_decoded_plan: "op\<^sub>2 \<in> set ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+ have op\<^sub>1_in_set_ops: "op\<^sub>1 \<in> set ((\<Pi>)\<^sub>\<O>)"
+ and op\<^sub>2_in_set_ops: "op\<^sub>2 \<in> set ((\<Pi>)\<^sub>\<O>)"
+ and op\<^sub>1_active_at_k: "\<not>lit_semantics \<A> ((Operator k (index ?ops op\<^sub>1))\<inverse>)"
+ and op\<^sub>2_active_at_k: "\<not>lit_semantics \<A> ((Operator k (index ?ops op\<^sub>2))\<inverse>)"
+ subgoal
+ using decode_plan_step_element_then[OF k_lt_t op\<^sub>1_in_k_th_of_decoded_plan]
+ by simp
+ subgoal
+ using decode_plan_step_element_then[OF k_lt_t op\<^sub>2_in_k_th_of_decoded_plan]
+ by force
+ subgoal
+ using decode_plan_step_element_then[OF k_lt_t op\<^sub>1_in_k_th_of_decoded_plan]
+ by simp
+ subgoal
+ using decode_plan_step_element_then[OF k_lt_t op\<^sub>2_in_k_th_of_decoded_plan]
+ by simp
+ done
+ (* TODO the following two blocks could be contracted and refactored into a single lemma. *)
+ {
+ fix v
+ assume v_in_add_effects_set_of_op\<^sub>1: "v \<in> set (add_effects_of op\<^sub>1)"
+ and v_in_delete_effects_set_of_op\<^sub>2: "v \<in> set (delete_effects_of op\<^sub>2)"
+ let ?C\<^sub>1 = "{(Operator k (index ?ops op\<^sub>1))\<inverse>,
+ (State (Suc k) (index ?vs v))\<^sup>+}"
+ and ?C\<^sub>2 = "{(Operator k (index ?ops op\<^sub>2))\<inverse>,
+ (State (Suc k) (index ?vs v))\<inverse>}"
+ have "?C\<^sub>1 \<in> cnf ?\<Phi>\<^sub>E" and "?C\<^sub>2 \<in> cnf ?\<Phi>\<^sub>E"
+ subgoal
+ using cnf_of_operator_effect_encoding_contains_add_effect_clause_if[OF
+ assms(1) k_lt_t op\<^sub>1_in_set_ops v_in_add_effects_set_of_op\<^sub>1]
+ by blast
+ subgoal
+ using cnf_of_operator_effect_encoding_contains_delete_effect_clause_if[OF
+ assms(1) k_lt_t op\<^sub>2_in_set_ops v_in_delete_effects_set_of_op\<^sub>2]
+ by blast
+ done
+ then have "?C\<^sub>1 \<in> cnf ?\<Phi>" and "?C\<^sub>2 \<in> cnf ?\<Phi>"
+ using cnf_of_encode_all_operator_effects_subset_cnf_of_encode_problem
+ by blast+
+ then have C\<^sub>1_true: "clause_semantics \<A> ?C\<^sub>1" and C\<^sub>2_true: "clause_semantics \<A> ?C\<^sub>2"
+ using valuation_models_encoding_cnf_formula_equals[OF assms(1)] assms(2)
+ unfolding cnf_semantics_def
+ by blast+
+ have "lit_semantics \<A> ((State (Suc k) (index ?vs v))\<^sup>+)"
+ and "lit_semantics \<A> ((State (k + 1) (index ?vs v))\<inverse>)"
+ subgoal
+ using op\<^sub>1_active_at_k C\<^sub>1_true
+ unfolding clause_semantics_def
+ by blast
+ subgoal
+ using op\<^sub>2_active_at_k C\<^sub>2_true
+ unfolding clause_semantics_def
+ by fastforce
+ done
+ hence False
+ by auto
+ } moreover {
+ fix v
+ assume v_in_delete_effects_set_of_op\<^sub>1: "v \<in> set (delete_effects_of op\<^sub>1)"
+ and v_in_add_effects_set_of_op\<^sub>2: "v \<in> set (add_effects_of op\<^sub>2)"
+ let ?C\<^sub>1 = "{(Operator k (index ?ops op\<^sub>1))\<inverse>, (State (Suc k) (index ?vs v))\<inverse>}"
+ and ?C\<^sub>2 = "{(Operator k (index ?ops op\<^sub>2))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+}"
+ have "?C\<^sub>1 \<in> cnf ?\<Phi>\<^sub>E" and "?C\<^sub>2 \<in> cnf ?\<Phi>\<^sub>E"
+ subgoal
+ using cnf_of_operator_effect_encoding_contains_delete_effect_clause_if[OF
+ assms(1) k_lt_t op\<^sub>1_in_set_ops v_in_delete_effects_set_of_op\<^sub>1]
+ by fastforce
+ subgoal
+ using cnf_of_operator_effect_encoding_contains_add_effect_clause_if[OF
+ assms(1) k_lt_t op\<^sub>2_in_set_ops v_in_add_effects_set_of_op\<^sub>2]
+ by simp
+ done
+ then have "?C\<^sub>1 \<in> cnf ?\<Phi>" and "?C\<^sub>2 \<in> cnf ?\<Phi>"
+ using cnf_of_encode_all_operator_effects_subset_cnf_of_encode_problem
+ by blast+
+ then have C\<^sub>1_true: "clause_semantics \<A> ?C\<^sub>1" and C\<^sub>2_true: "clause_semantics \<A> ?C\<^sub>2"
+ using valuation_models_encoding_cnf_formula_equals[OF assms(1)] assms(2)
+ unfolding cnf_semantics_def
+ by blast+
+ have "lit_semantics \<A> ((State (Suc k) (index ?vs v))\<inverse>)"
+ and "lit_semantics \<A> ((State (k + 1) (index ?vs v))\<^sup>+)"
+ subgoal
+ using op\<^sub>1_active_at_k C\<^sub>1_true
+ unfolding clause_semantics_def
+ by blast
+ subgoal
+ using op\<^sub>2_active_at_k C\<^sub>2_true
+ unfolding clause_semantics_def
+ by fastforce
+ done
+ hence False
+ by simp
+ }
+ ultimately have "set (add_effects_of op\<^sub>1) \<inter> set (delete_effects_of op\<^sub>2) = {}"
+ and "set (delete_effects_of op\<^sub>1) \<inter> set (add_effects_of op\<^sub>2) = {}"
+ by blast+
+ }
+ hence "are_all_operator_effects_consistent (?\<pi> ! k)"
+ using are_all_operator_effects_consistent_set[of "?\<pi> ! k"]
+ by blast
+ }
+ ultimately show "are_all_operators_applicable ?s (?\<pi> ! k)"
+ and "are_all_operator_effects_consistent (?\<pi> ! k)"
+ by blast+
+qed
+
+\<comment> \<open> Show that for all operators \<open>op\<close> at timestep \<open>k\<close> of the plan
+\<open>\<Phi>\<inverse> \<Pi> \<A> t\<close> decoded from the model \<open>\<A>\<close>, both add effects as
+well as delete effects will hold in the next timestep \<open>Suc k\<close>. \<close>
+lemma encode_problem_parallel_correct_iii:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ and "k < length (\<Phi>\<inverse> \<Pi> \<A> t)"
+ and "op \<in> set ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+ shows "v \<in> set (add_effects_of op)
+ \<longrightarrow> (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> (Suc k)) v = Some True"
+ and "v \<in> set (delete_effects_of op)
+ \<longrightarrow> (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> (Suc k)) v = Some False"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?\<Phi>\<^sub>F = "encode_all_operator_effects \<Pi> ?ops t"
+ and ?A = "(\<Union>(t, op)\<in>{0..<t} \<times> set ((\<Pi>)\<^sub>\<O>).
+ {{{ (Operator t (index ?ops op))\<inverse>, (State (Suc t) (index ?vs v))\<^sup>+ }}
+ | v. v \<in> set (add_effects_of op)})"
+ and ?B = "(\<Union>(t, op)\<in>{0..<t} \<times> set ((\<Pi>)\<^sub>\<O>).
+ {{{ (Operator t (index ?ops op))\<inverse>,
+ (State (Suc t) (index ?vs v))\<inverse> }}
+ | v. v \<in> set (delete_effects_of op)})"
+ have k_lt_t: "k < t"
+ using decode_plan_length assms(3)
+ by metis
+ have op_is_valid: "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using decode_plan_step_element_then[OF k_lt_t assms(4)]
+ by blast
+ have k_op_included: "(k, op) \<in> ({0..<t} \<times> set ((\<Pi>)\<^sub>\<O>))"
+ using k_lt_t op_is_valid
+ by fastforce
+ thus "v \<in> set (add_effects_of op)
+ \<longrightarrow> (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> (Suc k)) v = Some True"
+ and "v \<in> set (delete_effects_of op)
+ \<longrightarrow> (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> (Suc k)) v = Some False"
+ proof (auto)
+ assume v_is_add_effect: "v \<in> set (add_effects_of op)"
+ have "\<A> (Operator k (index ?ops op))"
+ using decode_plan_step_element_then[OF k_lt_t assms(4)]
+ by blast
+ moreover {
+ have "{{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+}}
+ \<in> {{{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+}}
+ | v. v \<in> set (add_effects_of op)}"
+ using v_is_add_effect
+ by blast
+ (* TODO slow. *)
+ then have "{{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+}} \<in> ?A"
+ using k_op_included cnf_of_operator_encoding_structure
+ UN_iff[of "{{(Operator t (index ?ops op))\<inverse>, (State (Suc t) (index ?vs v))\<^sup>+}}"
+ _ "{0..<t} \<times> set ((\<Pi>)\<^sub>\<O>)"]
+ by blast
+ (* TODO slow. *)
+ then have "{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+} \<in> \<Union> ?A"
+ using Union_iff[of "{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+}"]
+ by blast
+ (* TODO slow. *)
+ moreover have "\<Union>?A \<subseteq> cnf ?\<Phi>\<^sub>F"
+ using cnf_of_encode_all_operator_effects_structure
+ by blast
+ ultimately have "{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+} \<in> cnf ?\<Phi>\<^sub>F"
+ using in_mono[of "\<Union>?A" "cnf ?\<Phi>\<^sub>F"]
+ by presburger
+ }
+ (* TODO slow. *)
+ ultimately have "\<A> (State (Suc k) (index ?vs v))"
+ using cnf_of_encode_all_operator_effects_subset_cnf_of_encode_problem
+ assms(2)[unfolded valuation_models_encoding_cnf_formula_equals_corollary[OF assms(1)]]
+ unfolding Bex_def
+ by fastforce
+ thus "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> (Suc k)) v = Some True"
+ using assms(1) assms(2)
+ decode_state_at_encoding_variables_equals_some_of_valuation_if
+ is_valid_problem_strips_operator_variable_sets(2) k_lt_t op_is_valid subsetD
+ v_is_add_effect
+ by fastforce
+ next
+ assume v_is_delete_effect: "v \<in> set (delete_effects_of op)"
+ have "\<A> (Operator k (index ?ops op))"
+ using decode_plan_step_element_then[OF k_lt_t assms(4)]
+ by blast
+ moreover {
+ have "{{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse>}}
+ \<in> {{{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse>}}
+ | v. v \<in> set (delete_effects_of op)}"
+ using v_is_delete_effect
+ by blast
+ (* TODO slow. *)
+ then have "{{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse>}} \<in> ?B"
+ using k_op_included cnf_of_encode_all_operator_effects_structure
+ UN_iff[of "{{(Operator t (index ?ops op))\<inverse>, (State (Suc t) (index ?vs v))\<^sup>+}}"
+ _ "{0..<t} \<times> set ((\<Pi>)\<^sub>\<O>)"]
+ by blast
+ (* TODO slow. *)
+ then have "{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse>} \<in> \<Union> ?B"
+ using Union_iff[of "{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse>}"]
+ by blast
+ (* TODO slow. *)
+ moreover have "\<Union>?B \<subseteq> cnf ?\<Phi>\<^sub>F"
+ using cnf_of_encode_all_operator_effects_structure Un_upper2[of "\<Union>?B" "\<Union>?A"]
+ by fast
+ ultimately have "{(Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse>} \<in> cnf ?\<Phi>\<^sub>F"
+ using in_mono[of "\<Union>?B" "cnf ?\<Phi>\<^sub>F"]
+ by presburger
+ }
+ (* TODO slow. *)
+ ultimately have "\<not>\<A> (State (Suc k) (index ?vs v))"
+ using cnf_of_encode_all_operator_effects_subset_cnf_of_encode_problem
+ valuation_models_encoding_cnf_formula_equals_corollary[OF assms(1)] assms(2)
+ by fastforce
+ moreover have "Suc k \<le> t"
+ using k_lt_t
+ by fastforce
+ moreover have "v \<in> set((\<Pi>)\<^sub>\<V>)"
+ using v_is_delete_effect is_valid_problem_strips_operator_variable_sets(3) assms(1)
+ op_is_valid
+ by auto
+ ultimately show "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> (Suc k)) v = Some False"
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if[OF assms(1, 2)]
+ by auto
+ qed
+qed
+
+\<comment> \<open> In broad strokes, this lemma shows that the operator frame axioms ensure that state is
+propagated—i.e. the valuation of a variable does not change inbetween time steps—, if there is
+no operator active which has an effect on a given variable a: i.e.
+
+ \begin{align*}
+ \mathcal A &\vDash (\lnot a_i \land a_{i+1})
+ \longrightarrow \bigvee\{op_i, k: op_i \text{ has add effect } a\}\\
+ \mathcal A &\vDash (a_i \land \lnot a_{i+1})
+ \longrightarrow \bigvee\{op_i, k: op_i \text{ has delete effect } a\}
+ \end{align*}
+
+Now, if the disjunctions are empty—i.e. if no operator which is activated at time step $k$ has
+either a positive or negative effect—, we have by simplification
+
+ \begin{align*}
+ \mathcal A \vDash \lnot(\lnot a_i \land a_{i+1})
+ &\equiv \mathcal A \vDash a_i \lor \lnot a_{i+1}\\
+ \mathcal A \vDash \lnot(a_i \land \lnot a_{i+1})
+ &\equiv \mathcal A \vDash \lnot a_i \lor a_{i+1}
+ \end{align*}
+
+hence
+
+ \begin{align*}
+ \mathcal A &\vDash (\lnot a_i \lor a_{i+1}) \land (a_i \lor \lnot a_{i+1})\\
+ \leadsto \mathcal A &\vDash \{\{\lnot a_i, a_{i+1}\}, \{a_i, \lnot a_{i+1}\}\}
+ \end{align*}
+
+The lemma characterizes this simplification.
+\footnote{This part of the soundness proof is only treated very briefly in
+\cite[theorem 3.1, p.1044]{DBLP:journals/ai/RintanenHN06}} \<close>
+lemma encode_problem_parallel_correct_iv:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ and "k < t"
+ and "v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ and "\<not>(\<exists>op \<in> set ((\<Phi>\<inverse> \<Pi> \<A> t) ! k).
+ v \<in> set (add_effects_of op) \<or> v \<in> set (delete_effects_of op))"
+ shows "cnf_semantics \<A> {{ (State k (index (strips_problem.variables_of \<Pi>) v))\<inverse>
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }}"
+ and "cnf_semantics \<A> {{ (State k (index (strips_problem.variables_of \<Pi>) v))\<^sup>+
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<inverse> }}"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ let ?\<Phi> = "\<Phi> \<Pi> t"
+ and ?\<Phi>\<^sub>F = "encode_all_frame_axioms \<Pi> t"
+ and ?\<pi>\<^sub>k = "(\<Phi>\<inverse> \<Pi> \<A> t) ! k"
+ and ?A = "\<Union>(k, v) \<in> ({0..<t} \<times> set ?vs).
+ {{{ (State k (index ?vs v))\<^sup>+, (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> {(Operator k (index ?ops op))\<^sup>+ | op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }}}"
+ and ?B = "\<Union>(k, v) \<in> ({0..<t} \<times> set ?vs).
+ {{{ (State k (index ?vs v))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> { (Operator k (index ?ops op))\<^sup>+ | op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op) }}}"
+ and ?C = "{ (State k (index ?vs v))\<^sup>+, (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> {(Operator k (index ?ops op))\<^sup>+ | op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }"
+ and ?C' = "{ (State k (index ?vs v))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> { (Operator k (index ?ops op))\<^sup>+ | op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op) }"
+ (* TODO refactor (next two blocks)? *)
+ have k_v_included: "(k, v) \<in> ({..<t} \<times> set ((\<Pi>)\<^sub>\<V>))"
+ using assms(3, 4)
+ by blast
+ have operator_encoding_subset_encoding: "cnf ?\<Phi>\<^sub>F \<subseteq> cnf ?\<Phi>"
+ using cnf_of_encode_problem_structure(4)
+ unfolding encode_problem_def
+ by fast
+ \<comment> \<open> Given the premise that no operator in \<open>\<pi>\<^sub>k\<close> exists with add-effect respectively delete
+effect \<open>v\<close>, we have the following situation for the EPC (effect precondition) sets:
+ \begin{itemize}
+ \item assuming \<open>op\<close> is in \<open>set ?ops\<close>, either \<open>op\<close> is in \<open>\<pi>\<^sub>k\<close> (then it doesn't have effect on \<open>v\<close>
+ and therefore is not in either of the sets), or if is not, then
+ \<open>\<A> (Operator k (index ?ops op) = \<bottom>\<close> by definition of \<open>decode_plan\<close>; moreover,
+ \item assuming \<open>op\<close> is not in \<open>set ?ops\<close>—this is implicitely encoded as \<open>Operator k
+ (length ?ops)\<close> and \<open>\<A> (Operator k (length ?ops))\<close> may or may not be true—, then it's not
+ in either of the sets.
+ \end{itemize}.
+Altogether, we have the situation that the sets only have members \<open>Operator k (index ?ops op)\<close>
+with \<open>\<A> (Operator k (index ?ops op)) = \<bottom>\<close>, hence the clause can be reduced to the state
+variable literals.
+
+More concretely, the following proof block shows that the following two conditions hold for the
+operators:
+
+ @{text[display, indent=4] "\<forall>op. op \<in> { ((Operator k (index ?ops op))\<^sup>+)
+ | op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op)}
+ \<longrightarrow> \<not>lit_semantics \<A> op" }
+
+and
+
+ @{text[display, indent=4] "\<forall>op. op \<in> { ((Operator k (index ?ops op))\<^sup>+)
+ | op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op)}
+ \<longrightarrow> \<not>lit_semantics \<A> op" }
+
+Hence, the operators are irrelevant for \<open>cnf_semantics \<A> { C }\<close> where \<open>C\<close> is
+a clause encoding a positive or negative transition frame axiom for a given variable \<open>v\<close> of the
+problem. \<close>
+ (* TODO refactor. *)
+ {
+ let ?add = "{ ((Operator k (index ?ops op))\<^sup>+)
+ | op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }"
+ and ?delete = "{ ((Operator k (index ?ops op))\<^sup>+)
+ | op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op) }"
+ {
+ fix op
+ assume operator_encoding_in_add: "(Operator k (index ?ops op))\<^sup>+ \<in> ?add"
+ hence "\<not>lit_semantics \<A> ((Operator k (index ?ops op))\<^sup>+)"
+ proof (cases "op \<in> set ?\<pi>\<^sub>k")
+ case True
+ then have "v \<notin> set (add_effects_of op)"
+ using assms(5)
+ by simp
+ then have "(Operator k (index ?ops op))\<^sup>+ \<notin> ?add"
+ by fastforce
+ thus ?thesis
+ using operator_encoding_in_add
+ by blast
+ next
+ case False
+ then show ?thesis
+ proof (cases "op \<in> set ?ops")
+ case True
+ {
+ let ?A = "{ ?ops ! index ?ops op |op.
+ op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> \<A> (Operator k (index ?ops op))}"
+ assume "lit_semantics \<A> ((Operator k (index ?ops op))\<^sup>+)"
+ moreover have operator_active_at_k: "\<A> (Operator k (index ?ops op))"
+ using calculation
+ by auto
+ moreover have "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using True
+ by force
+ moreover have "(?ops ! index ?ops op) \<in> ?A"
+ using calculation(2, 3)
+ by blast
+ ultimately have "op \<in> set ?\<pi>\<^sub>k"
+ using decode_plan_step_element_then_i[OF assms(3)]
+ by auto
+ hence False
+ using False
+ by blast
+ }
+ thus ?thesis
+ by blast
+ next
+ case False
+ then have "op \<notin> {op \<in> set ?ops. v \<in> set (add_effects_of op)}"
+ by blast
+ moreover have "?add =
+ (\<lambda>op. (Operator k (index ?ops op))\<^sup>+)
+ ` { op \<in> set ?ops. v \<in> set (add_effects_of op) }"
+ using setcompr_eq_image[of "\<lambda>op. (Operator k (index ?ops op))\<^sup>+"
+ "\<lambda>op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op)"]
+ by blast
+ (* TODO slow. *)
+ ultimately have "(Operator k (index ?ops op))\<^sup>+ \<notin> ?add"
+ by force
+ thus ?thesis using operator_encoding_in_add
+ by blast
+ qed
+ qed
+ } moreover {
+ fix op
+ assume operator_encoding_in_delete: "((Operator k (index ?ops op))\<^sup>+) \<in> ?delete"
+ hence "\<not>lit_semantics \<A> ((Operator k (index ?ops op))\<^sup>+)"
+ proof (cases "op \<in> set ?\<pi>\<^sub>k")
+ case True
+ then have "v \<notin> set (delete_effects_of op)"
+ using assms(5)
+ by simp
+ then have "(Operator k (index ?ops op))\<^sup>+ \<notin> ?delete"
+ by fastforce
+ thus ?thesis
+ using operator_encoding_in_delete
+ by blast
+ next
+ case False
+ then show ?thesis
+ proof (cases "op \<in> set ?ops")
+ case True
+ {
+ let ?A = "{ ?ops ! index ?ops op |op.
+ op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> \<A> (Operator k (index ?ops op))}"
+ assume "lit_semantics \<A> ((Operator k (index ?ops op))\<^sup>+)"
+ moreover have operator_active_at_k: "\<A> (Operator k (index ?ops op))"
+ using calculation
+ by auto
+ moreover have "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using True
+ by force
+ moreover have "(?ops ! index ?ops op) \<in> ?A"
+ using calculation(2, 3)
+ by blast
+ ultimately have "op \<in> set ?\<pi>\<^sub>k"
+ using decode_plan_step_element_then_i[OF assms(3)]
+ by auto
+ hence False
+ using False
+ by blast
+ }
+ thus ?thesis
+ by blast
+ next
+ case False
+ then have "op \<notin> { op \<in> set ?ops. v \<in> set (delete_effects_of op) }"
+ by blast
+ moreover have "?delete =
+ (\<lambda>op. (Operator k (index ?ops op))\<^sup>+)
+ ` { op \<in> set ?ops. v \<in> set (delete_effects_of op) }"
+ using setcompr_eq_image[of "\<lambda>op. (Operator k (index ?ops op))\<^sup>+"
+ "\<lambda>op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op)"]
+ by blast
+ (* TODO slow. *)
+ ultimately have "(Operator k (index ?ops op))\<^sup>+ \<notin> ?delete"
+ by force
+ thus ?thesis using operator_encoding_in_delete
+ by blast
+ qed
+ qed
+ }
+ ultimately have "\<forall>op. op \<in> ?add \<longrightarrow> \<not>lit_semantics \<A> op"
+ and "\<forall>op. op \<in> ?delete \<longrightarrow> \<not>lit_semantics \<A> op"
+ by blast+
+ } note nb = this
+ {
+ let ?Ops = "{ (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }"
+ have "?Ops \<subseteq> ?C"
+ by blast
+ moreover have "?C - ?Ops = { (State k (index ?vs v))\<^sup>+ , (State (Suc k) (index ?vs v))\<inverse> }"
+ by fast
+ moreover have "\<forall>L \<in> ?Ops. \<not> lit_semantics \<A> L"
+ using nb(1)
+ by blast
+ (* TODO slow. *)
+ ultimately have "clause_semantics \<A> ?C
+ = clause_semantics \<A> { (State k (index ?vs v))\<^sup>+, (State (Suc k) (index ?vs v))\<inverse> }"
+ using lit_semantics_reducible_to_subset_if[of ?Ops ?C]
+ by presburger
+ } moreover {
+ let ?Ops' = "{ (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op) }"
+ have "?Ops' \<subseteq> ?C'"
+ by blast
+ moreover have "?C' - ?Ops' = { (State k (index ?vs v))\<inverse> , (State (Suc k) (index ?vs v))\<^sup>+ }"
+ by fast
+ moreover have "\<forall>L \<in> ?Ops'. \<not> lit_semantics \<A> L"
+ using nb(2)
+ by blast
+ (* TODO slow. *)
+ ultimately have "clause_semantics \<A> ?C'
+ = clause_semantics \<A> { (State k (index ?vs v))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }"
+ using lit_semantics_reducible_to_subset_if[of ?Ops' ?C']
+ by presburger
+ } moreover {
+ have cnf_semantics_\<A>_\<Phi>:"cnf_semantics \<A> (cnf ?\<Phi>)"
+ using valuation_models_encoding_cnf_formula_equals[OF assms(1)] assms(2)
+ by blast
+ have k_v_included: "(k, v) \<in> ({..<t} \<times> set ((\<Pi>)\<^sub>\<V>))"
+ using assms(3, 4)
+ by blast
+ (* TODO slow. *)
+ have c_in_un_a: "?C \<in> \<Union>?A" and c'_in_un_b: "?C' \<in> \<Union>?B"
+ using k_v_included
+ by force+
+ (* TODO slow. *)
+ then have "?C \<in> cnf ?\<Phi>\<^sub>F" and "?C' \<in> cnf ?\<Phi>\<^sub>F"
+ subgoal
+ using cnf_of_encode_all_frame_axioms_structure UnI1[of "?C" "\<Union>?A" "\<Union>?B"] c_in_un_a
+ by metis
+ subgoal
+ using cnf_of_encode_all_frame_axioms_structure UnI2[of "?C'" "\<Union>?B" "\<Union>?A"] c'_in_un_b
+ by metis
+ done
+ then have "{ ?C } \<subseteq> cnf ?\<Phi>\<^sub>F" and c'_subset_frame_axiom_encoding: "{ ?C' } \<subseteq> cnf ?\<Phi>\<^sub>F"
+ by blast+
+ then have "{ ?C } \<subseteq> cnf ?\<Phi>" and "{ ?C' } \<subseteq> cnf ?\<Phi>"
+ subgoal
+ using operator_encoding_subset_encoding
+ by fast
+ subgoal
+ using c'_subset_frame_axiom_encoding operator_encoding_subset_encoding
+ by fast
+ done
+ (* TODO slow. *)
+ hence "cnf_semantics \<A> { ?C }" and "cnf_semantics \<A> { ?C' }"
+ using cnf_semantics_\<A>_\<Phi> model_for_cnf_is_model_of_all_subsets
+ by fastforce+
+ }
+ ultimately show "cnf_semantics \<A> {{ (State k (index ?vs v))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }}"
+ and "cnf_semantics \<A> {{ (State k (index ?vs v))\<^sup>+, (State (Suc k) (index ?vs v))\<inverse> }}"
+ unfolding cnf_semantics_def
+ by blast+
+qed
+
+lemma encode_problem_parallel_correct_v:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ and "k < length (\<Phi>\<inverse> \<Pi> \<A> t)"
+ shows "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> (Suc k)) = execute_parallel_operator (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k) ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?\<pi> = "\<Phi>\<inverse> \<Pi> \<A> t"
+ and ?s\<^sub>k = "\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k"
+ and ?s\<^sub>k' = "\<Phi>\<^sub>S\<inverse> \<Pi> \<A> (Suc k)"
+ let ?t\<^sub>k' = "execute_parallel_operator ?s\<^sub>k (?\<pi> ! k)"
+ and ?\<pi>\<^sub>k = "?\<pi> ! k"
+ have k_lt_t: "k < t" and k_lte_t: "k \<le> t" and suc_k_lte_t: "Suc k \<le> t"
+ using decode_plan_length[of ?\<pi> \<Pi> \<A> t] assms(3)
+ by (argo, fastforce+)
+ then have operator_preconditions_hold:
+ "are_all_operators_applicable ?s\<^sub>k ?\<pi>\<^sub>k \<and> are_all_operator_effects_consistent ?\<pi>\<^sub>k"
+ using encode_problem_parallel_correct_ii[OF assms(1, 2, 3)]
+ by blast
+ \<comment> \<open> We show the goal in classical fashion by proving that
+ @{text[display, indent=4] "\<Phi>\<^sub>S\<inverse> \<Pi> \<A> (Suc k) v
+ = execute_parallel_operator (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k)
+ ((\<Phi>\<inverse> \<Pi> \<A> t) ! k) v"}
+ ---i.e. the state decoded at time \<open>k + 1\<close> is equivalent to the state obtained by executing the
+ parallel operator \<open>(\<Phi>\<inverse> \<Pi> \<A> t) ! k\<close> on the previous state
+ \<open>\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k\<close>—for all variables \<open>v\<close> given \<open>k < t\<close>, a model \<open>\<A>\<close>,
+ and makespan \<open>t\<close>. \<close>
+ moreover {
+ {
+ fix v
+ assume v_in_dom_s\<^sub>k':"v \<in> dom ?s\<^sub>k'"
+ then have s\<^sub>k'_not_none: "?s\<^sub>k' v \<noteq> None"
+ by blast
+ hence "?s\<^sub>k' v = ?t\<^sub>k' v"
+ proof (cases "\<exists>op \<in> set ?\<pi>\<^sub>k. v \<in> set (add_effects_of op) \<or> v \<in> set (delete_effects_of op)")
+ case True
+ then obtain op
+ where op_in_\<pi>\<^sub>k: "op \<in> set ?\<pi>\<^sub>k"
+ and "v \<in> set (add_effects_of op) \<or> v \<in> set (delete_effects_of op)"
+ by blast
+ then consider (v_is_add_effect) "v \<in> set (add_effects_of op)"
+ | (v_is_delete_effect) "v \<in> set (delete_effects_of op)"
+ by blast
+ then show ?thesis
+ proof (cases)
+ case v_is_add_effect
+ then have "?s\<^sub>k' v = Some True"
+ using encode_problem_parallel_correct_iii(1)[OF assms(1, 2, 3) op_in_\<pi>\<^sub>k]
+ v_is_add_effect
+ by blast
+ moreover have "are_all_operators_applicable (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k) ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+ and "are_all_operator_effects_consistent ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+ using operator_preconditions_hold v_is_add_effect
+ by blast+
+ moreover have "?t\<^sub>k' v = Some True"
+ using execute_parallel_operator_positive_effect_if[of
+ "\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k" "(\<Phi>\<inverse> \<Pi> \<A> t) ! k"] op_in_\<pi>\<^sub>k
+ v_is_add_effect calculation(2, 3)
+ by blast
+ ultimately show ?thesis
+ by argo
+ next
+ case v_is_delete_effect
+ then have "?s\<^sub>k' v = Some False"
+ using encode_problem_parallel_correct_iii(2)[OF assms(1, 2, 3) op_in_\<pi>\<^sub>k]
+ v_is_delete_effect
+ by blast
+ moreover have "are_all_operators_applicable (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k) ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+ and "are_all_operator_effects_consistent ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+ using operator_preconditions_hold
+ by blast+
+ moreover have "?t\<^sub>k' v = Some False"
+ using execute_parallel_operator_effect(2) op_in_\<pi>\<^sub>k
+ v_is_delete_effect calculation(2, 3)
+ by fast
+ moreover have "?t\<^sub>k' v = Some False"
+ by (meson execute_parallel_operator_negative_effect_if op_in_\<pi>\<^sub>k operator_preconditions_hold v_is_delete_effect)
+ ultimately show ?thesis
+ by argo
+ qed
+ next
+ case False
+ (* TODO slow. *)
+ then have "?t\<^sub>k' v = ?s\<^sub>k v"
+ using execute_parallel_operator_no_effect_if
+ by fastforce
+ moreover {
+ have v_in_set_vs: "v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ using decode_state_at_valid_variable[OF s\<^sub>k'_not_none].
+ then have state_propagation_positive:
+ "cnf_semantics \<A> {{(State k (index ?vs v))\<inverse>
+ , (State (Suc k) (index ?vs v))\<^sup>+}}"
+ and state_propagation_negative:
+ "cnf_semantics \<A> {{(State k (index ?vs v))\<^sup>+
+ , (State (Suc k) (index ?vs v))\<inverse>}}"
+ using encode_problem_parallel_correct_iv[OF assms(1, 2) k_lt_t _ False]
+ by fastforce+
+ consider (s\<^sub>k'_v_positive) "?s\<^sub>k' v = Some True"
+ | (s\<^sub>k'_v_negative) "?s\<^sub>k' v = Some False"
+ using s\<^sub>k'_not_none
+ by fastforce
+ hence "?s\<^sub>k' v = ?s\<^sub>k v"
+ proof (cases)
+ case s\<^sub>k'_v_positive
+ then have "lit_semantics \<A> ((State (Suc k) (index ?vs v))\<^sup>+)"
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if[OF
+ assms(1, 2) suc_k_lte_t v_in_set_vs]
+ by fastforce
+ (* TODO slow. *)
+ then have "lit_semantics \<A> ((State k (index ?vs v))\<^sup>+)"
+ using state_propagation_negative
+ unfolding cnf_semantics_def clause_semantics_def
+ by fastforce
+ then show ?thesis
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if[OF
+ assms(1, 2) k_lte_t v_in_set_vs] s\<^sub>k'_v_positive
+ by fastforce
+ next
+ case s\<^sub>k'_v_negative
+ then have "\<not>lit_semantics \<A> ((State (Suc k) (index ?vs v))\<^sup>+)"
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if[
+ OF assms(1, 2) suc_k_lte_t v_in_set_vs]
+ by fastforce
+ (* TODO slow. *)
+ then have "\<not>lit_semantics \<A> ((State k (index ?vs v))\<^sup>+)"
+ using state_propagation_positive
+ unfolding cnf_semantics_def clause_semantics_def
+ by fastforce
+ then show ?thesis
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if[OF
+ assms(1, 2) k_lte_t v_in_set_vs] s\<^sub>k'_v_negative
+ by fastforce
+ qed
+ }
+ ultimately show ?thesis
+ by argo
+ qed
+ }
+ hence "?s\<^sub>k' \<subseteq>\<^sub>m ?t\<^sub>k'"
+ using map_le_def
+ by blast
+ }
+ moreover {
+ {
+ fix v
+ assume "v \<in> dom ?t\<^sub>k'"
+ then have t\<^sub>k'_not_none: "?t\<^sub>k' v \<noteq> None"
+ by blast
+ {
+ {
+ assume contradiction: "v \<notin> set ((\<Pi>)\<^sub>\<V>)"
+ then have "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k) v = None"
+ using decode_state_at_valid_variable
+ by fastforce
+ then obtain op
+ where op_in: "op \<in> set ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+ and v_is_or: "v \<in> set (add_effects_of op)
+ \<or> v \<in> set (delete_effects_of op)"
+ using execute_parallel_operators_strips_none_if_contraposition[OF
+ t\<^sub>k'_not_none]
+ by blast
+ have op_in: "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using op_in decode_plan_step_element_then(1) k_lt_t
+ by blast
+ consider (A) "v \<in> set (add_effects_of op)"
+ | (B) "v \<in> set (delete_effects_of op)"
+ using v_is_or
+ by blast
+ hence False
+ proof (cases)
+ case A
+ then have "v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ using is_valid_problem_strips_operator_variable_sets(2)[OF
+ assms(1)] op_in A
+ by blast
+ thus False
+ using contradiction
+ by blast
+ next
+ case B
+ then have "v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ using is_valid_problem_strips_operator_variable_sets(3)[OF
+ assms(1)] op_in B
+ by blast
+ thus False
+ using contradiction
+ by blast
+ qed
+ }
+ }
+ hence v_in_set_vs: "v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ by blast
+ hence "?t\<^sub>k' v = ?s\<^sub>k' v"
+ proof (cases "(\<exists>op\<in>set ?\<pi>\<^sub>k. v \<in> set (add_effects_of op) \<or> v \<in> set (delete_effects_of op))")
+ case True
+ then obtain op
+ where op_in_set_\<pi>\<^sub>k: "op \<in> set ?\<pi>\<^sub>k"
+ and v_options: "v \<in> set (add_effects_of op) \<or> v \<in> set (delete_effects_of op)"
+ by blast
+ then have "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using decode_plan_step_element_then[OF k_lt_t]
+ by blast
+ then consider (v_is_add_effect) "v \<in> set (add_effects_of op)"
+ | (v_is_delete_effect) "v \<in> set (delete_effects_of op)"
+ using v_options
+ by blast
+ thus ?thesis
+ proof (cases)
+ case v_is_add_effect
+ then have "?t\<^sub>k' v = Some True"
+ using execute_parallel_operator_positive_effect_if[OF _ _ op_in_set_\<pi>\<^sub>k]
+ operator_preconditions_hold
+ by blast
+ moreover have "?s\<^sub>k' v = Some True"
+ using encode_problem_parallel_correct_iii(1)[OF assms(1, 2, 3) op_in_set_\<pi>\<^sub>k]
+ v_is_add_effect
+ by blast
+ ultimately show ?thesis
+ by argo
+ next
+ case v_is_delete_effect
+ then have "?t\<^sub>k' v = Some False"
+ using execute_parallel_operator_negative_effect_if[OF _ _ op_in_set_\<pi>\<^sub>k]
+ operator_preconditions_hold
+ by blast
+ moreover have "?s\<^sub>k' v = Some False"
+ using encode_problem_parallel_correct_iii(2)[OF assms(1, 2, 3) op_in_set_\<pi>\<^sub>k]
+ v_is_delete_effect
+ by blast
+ ultimately show ?thesis
+ by argo
+ qed
+ next
+ case False
+ have state_propagation_positive:
+ "cnf_semantics \<A> {{(State k (index ?vs v))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+}}"
+ and state_propagation_negative:
+ "cnf_semantics \<A> {{(State k (index ?vs v))\<^sup>+, (State (Suc k) (index ?vs v))\<inverse>}}"
+ using encode_problem_parallel_correct_iv[OF assms(1, 2) k_lt_t v_in_set_vs
+ False]
+ by blast+
+ {
+ have all_op_in_set_\<pi>\<^sub>k_have_no_effect:
+ "\<forall>op \<in> set ?\<pi>\<^sub>k. v \<notin> set (add_effects_of op) \<and> v \<notin> set (delete_effects_of op)"
+ using False
+ by blast
+ then have "?t\<^sub>k' v = ?s\<^sub>k v"
+ using execute_parallel_operator_no_effect_if[OF all_op_in_set_\<pi>\<^sub>k_have_no_effect]
+ by blast
+ } note t\<^sub>k'_equals_s\<^sub>k = this
+ {
+ have "?s\<^sub>k v \<noteq> None"
+ using t\<^sub>k'_not_none t\<^sub>k'_equals_s\<^sub>k
+ by argo
+ then consider (s\<^sub>k_v_is_some_true) "?s\<^sub>k v = Some True"
+ | (s\<^sub>k_v_is_some_false) "?s\<^sub>k v = Some False"
+ by fastforce
+ }
+ then show ?thesis
+ proof (cases)
+ case s\<^sub>k_v_is_some_true
+ moreover {
+ have "lit_semantics \<A> ((State k (index ?vs v))\<^sup>+)"
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if[OF
+ assms(1, 2) k_lte_t v_in_set_vs] s\<^sub>k_v_is_some_true
+ by simp
+ then have "lit_semantics \<A> ((State (Suc k) (index ?vs v))\<^sup>+)"
+ using state_propagation_positive
+ unfolding cnf_semantics_def clause_semantics_def
+ by fastforce
+ then have "?s\<^sub>k' v = Some True"
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if[OF
+ assms(1, 2) suc_k_lte_t v_in_set_vs]
+ by fastforce
+ }
+ ultimately show ?thesis
+ using t\<^sub>k'_equals_s\<^sub>k
+ by simp
+ next
+ case s\<^sub>k_v_is_some_false
+ moreover {
+ have "lit_semantics \<A> ((State k (index ?vs v))\<inverse>)"
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if[OF
+ assms(1, 2) k_lte_t v_in_set_vs] s\<^sub>k_v_is_some_false
+ by simp
+ then have "lit_semantics \<A> ((State (Suc k) (index ?vs v))\<inverse>)"
+ using state_propagation_negative
+ unfolding cnf_semantics_def clause_semantics_def
+ by fastforce
+ then have "?s\<^sub>k' v = Some False"
+ using decode_state_at_encoding_variables_equals_some_of_valuation_if[OF
+ assms(1, 2) suc_k_lte_t v_in_set_vs]
+ by fastforce
+ }
+ ultimately show ?thesis
+ using t\<^sub>k'_equals_s\<^sub>k
+ by simp
+ qed
+ qed
+ }
+ hence "?t\<^sub>k' \<subseteq>\<^sub>m ?s\<^sub>k'"
+ using map_le_def
+ by blast
+ }
+ ultimately show ?thesis
+ using map_le_antisym
+ by blast
+qed
+
+lemma encode_problem_parallel_correct_vi:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ and "k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) (\<Phi>\<inverse> \<Pi> \<A> t))"
+ shows "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) (\<Phi>\<inverse> \<Pi> \<A> t) ! k
+ = \<Phi>\<^sub>S\<inverse> \<Pi> \<A> k"
+ using assms
+proof -
+ let ?I = "(\<Pi>)\<^sub>I"
+ and ?\<pi> = "\<Phi>\<inverse> \<Pi> \<A> t"
+ let ?\<tau> = "trace_parallel_plan_strips ?I ?\<pi>"
+ show ?thesis
+ using assms
+ proof (induction k)
+ case 0
+ hence "?\<tau> ! 0 = ?I"
+ using trace_parallel_plan_strips_head_is_initial_state
+ by blast
+ moreover have "\<Phi>\<^sub>S\<inverse> \<Pi> \<A> 0 = ?I"
+ using decode_state_at_initial_state[OF assms(1, 2)]
+ by simp
+ ultimately show ?case
+ by simp
+ next
+ case (Suc k)
+ let ?\<tau>\<^sub>k = "trace_parallel_plan_strips ?I ?\<pi> ! k"
+ and ?s\<^sub>k = "\<Phi>\<^sub>S\<inverse> \<Pi> \<A> k"
+ have k_lt_length_\<tau>_minus_one: "k < length ?\<tau> - 1" and k_lt_length_\<tau>: "k < length ?\<tau>"
+ using Suc.prems(3)
+ by linarith+
+ \<comment> \<open> Use the induction hypothesis to obtain the proposition for the previous step $k$.
+ Then, show that applying the $k$-th parallel operator in the plan $\pi$ on either the state
+ obtained from the trace or decoded from the model yields the same successor state. \<close>
+ {
+ have "?\<tau> ! k = execute_parallel_plan ?I (take k ?\<pi>)"
+ using trace_parallel_plan_plan_prefix k_lt_length_\<tau>
+ by blast
+ hence "?\<tau>\<^sub>k = ?s\<^sub>k"
+ using Suc.IH[OF assms(1, 2) k_lt_length_\<tau>]
+ by blast
+ }
+ moreover have "trace_parallel_plan_strips ?I ?\<pi> ! Suc k
+ = execute_parallel_operator ?\<tau>\<^sub>k (?\<pi> ! k)"
+ using trace_parallel_plan_step_effect_is[OF k_lt_length_\<tau>_minus_one]
+ by blast
+ moreover {
+ thm Suc.prems(3)
+ have "length (trace_parallel_plan_strips ?I ?\<pi>) \<le> length ?\<pi> + 1"
+ using length_trace_parallel_plan_strips_lte_length_plan_plus_one
+ by blast
+ then have "k < length ?\<pi>"
+ using Suc.prems(3)
+ unfolding Suc_eq_plus1
+ by linarith
+ hence "\<Phi>\<^sub>S\<inverse> \<Pi> \<A> (Suc k)
+ = execute_parallel_operator ?s\<^sub>k (?\<pi> ! k)"
+ using encode_problem_parallel_correct_v[OF assms(1, 2)]
+ by simp
+ }
+ ultimately show ?case
+ by argo
+ qed
+qed
+
+lemma encode_problem_parallel_correct_vii:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ shows "length (map (decode_state_at \<Pi> \<A>)
+ [0..<Suc (length (\<Phi>\<inverse> \<Pi> \<A> t))])
+ = length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) (\<Phi>\<inverse> \<Pi> \<A> t))"
+proof -
+ let ?I = "(\<Pi>)\<^sub>I"
+ and ?\<pi> = "\<Phi>\<inverse> \<Pi> \<A> t"
+ let ?\<sigma> = "map (decode_state_at \<Pi> \<A>) [0..<Suc (length ?\<pi>)]"
+ and ?\<tau> = "trace_parallel_plan_strips ?I ?\<pi>"
+ let ?l = "length ?\<tau> "
+ let ?k = "?l - 1"
+ show ?thesis
+ proof (rule ccontr)
+ assume length_\<sigma>_neq_length_\<tau>: "length ?\<sigma> \<noteq> length ?\<tau>"
+ {
+ have "length ?\<sigma> = length ?\<pi> + 1"
+ by fastforce
+ moreover have "length ?\<tau> \<le> length ?\<pi> + 1"
+ using length_trace_parallel_plan_strips_lte_length_plan_plus_one
+ by blast
+ moreover have "length ?\<tau> < length ?\<pi> + 1"
+ using length_\<sigma>_neq_length_\<tau> calculation
+ by linarith
+ } note nb\<^sub>1 = this
+ {
+ have "0 < length ?\<tau>"
+ using trace_parallel_plan_strips_not_nil..
+ then have "length ?\<tau> - 1 < length ?\<pi>"
+ using nb\<^sub>1
+ by linarith
+ } note nb\<^sub>2 = this
+ {
+ obtain k' where "length ?\<tau> = Suc k'"
+ using less_imp_Suc_add[OF length_trace_parallel_plan_gt_0]
+ by blast
+ hence "?k < length ?\<pi>"
+ using nb\<^sub>2
+ by blast
+ } note nb\<^sub>3 = this
+ {
+ have "?\<tau> ! ?k = execute_parallel_plan ?I (take ?k ?\<pi>)"
+ using trace_parallel_plan_plan_prefix[of ?k]
+ length_trace_minus_one_lt_length_trace
+ by blast
+ thm encode_problem_parallel_correct_vi[OF assms(1, 2)] nb\<^sub>3
+ moreover have "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> ?k) = ?\<tau> ! ?k"
+ using encode_problem_parallel_correct_vi[OF assms(1, 2)
+ length_trace_minus_one_lt_length_trace]..
+ ultimately have "(\<Phi>\<^sub>S\<inverse> \<Pi> \<A> ?k) = execute_parallel_plan ?I (take ?k ?\<pi>)"
+ by argo
+ } note nb\<^sub>4 = this
+ {
+ have "are_all_operators_applicable (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> ?k) (?\<pi> ! ?k)"
+ and "are_all_operator_effects_consistent (?\<pi> ! ?k)"
+ using encode_problem_parallel_correct_ii(1, 2)[OF assms(1, 2)] nb\<^sub>3
+ by blast+
+ \<comment> \<open> Unsure why \<open>calculation(1, 2)\<close> is needed for this proof step. Should just require the
+ default proof. \<close>
+ moreover have "\<not>are_all_operators_applicable (\<Phi>\<^sub>S\<inverse> \<Pi> \<A> ?k) (?\<pi> ! ?k)"
+ and "\<not>are_all_operator_effects_consistent (?\<pi> ! ?k)"
+ using length_trace_parallel_plan_strips_lt_length_plan_plus_one_then[OF nb\<^sub>1]
+ calculation(1, 2)
+ unfolding nb\<^sub>3 nb\<^sub>4
+ by blast+
+ ultimately have False
+ by blast
+ }
+ thus False.
+ qed
+qed
+
+lemma encode_problem_parallel_correct_x:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ shows "map (decode_state_at \<Pi> \<A>)
+ [0..<Suc (length (\<Phi>\<inverse> \<Pi> \<A> t))]
+ = trace_parallel_plan_strips ((\<Pi>)\<^sub>I) (\<Phi>\<inverse> \<Pi> \<A> t)"
+proof -
+ let ?I = "(\<Pi>)\<^sub>I"
+ and ?\<pi> = "\<Phi>\<inverse> \<Pi> \<A> t"
+ let ?\<sigma> = "map (decode_state_at \<Pi> \<A>) [0..<Suc (length ?\<pi>)]"
+ and ?\<tau> = "trace_parallel_plan_strips ?I ?\<pi>"
+ {
+ have "length ?\<tau> = length ?\<sigma>"
+ using encode_problem_parallel_correct_vii[OF assms]..
+ moreover {
+ fix k
+ assume k_lt_length_\<tau>: "k < length ?\<tau>"
+ then have "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) (\<Phi>\<inverse> \<Pi> \<A> t) ! k
+ = \<Phi>\<^sub>S\<inverse> \<Pi> \<A> k"
+ using encode_problem_parallel_correct_vi[OF assms]
+ by blast
+ moreover {
+ have "length ?\<tau> \<le> length ?\<pi> + 1"
+ using length_trace_parallel_plan_strips_lte_length_plan_plus_one
+ by blast
+ then have "k < length ?\<pi> + 1"
+ using k_lt_length_\<tau>
+ by linarith
+ then have "k < Suc (length ?\<pi>) - 0"
+ by simp
+ hence "?\<sigma> ! k = \<Phi>\<^sub>S\<inverse> \<Pi> \<A> k"
+ using nth_map_upt[of k "Suc (length ?\<pi>)" 0]
+ by auto
+ }
+ ultimately have "?\<tau> ! k = ?\<sigma> ! k"
+ by argo
+ }
+ ultimately have "?\<tau> = ?\<sigma>"
+ using list_eq_iff_nth_eq[of ?\<tau> ?\<sigma>]
+ by blast
+ }
+ thus ?thesis
+ by argo
+qed
+
+lemma encode_problem_parallel_correct_xi:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ and "ops \<in> set (\<Phi>\<inverse> \<Pi> \<A> t)"
+ and "op \<in> set ops"
+ shows "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+proof -
+ let ?\<pi> = "\<Phi>\<inverse> \<Pi> \<A> t"
+ have "length ?\<pi> = t"
+ using decode_plan_length
+ by force
+ moreover obtain k where "k < length ?\<pi>" and "ops = ?\<pi> ! k"
+ using in_set_conv_nth[of ops ?\<pi>] assms(3)
+ unfolding calculation
+ by blast
+ ultimately show ?thesis
+ using assms(4) decode_plan_step_element_then(1)
+ by force
+qed
+
+
+text \<open> To show soundness, we have to prove the following: given the existence of a model
+\<^term>\<open>\<A>\<close> of the basic SATPlan encoding \<^term>\<open>encode_problem \<Pi> t\<close> for a given valid problem \<^term>\<open>\<Pi>\<close>
+and hypothesized plan length \<^term>\<open>t\<close>, the decoded plan \<^term>\<open>\<pi> \<equiv> \<Phi>\<inverse> \<Pi> \<A> t\<close> is a parallel solution
+for \<^term>\<open>\<Pi>\<close>.
+
+We show this theorem by showing equivalence between the execution trace of the decoded plan and the
+sequence of states
+
+ @{text[display, indent=4] "\<sigma> = map (\<lambda> k. \<Phi>\<^sub>S\<inverse> \<Pi> \<A> k) [0..<Suc (length ?\<pi>)]" }
+
+decoded from the model \<^term>\<open>\<A>\<close>. Let
+
+ @{text[display, indent=4] "\<tau> \<equiv> trace_parallel_plan_strips I \<pi>"}
+
+be the trace of \<^term>\<open>\<pi>\<close>. Theorem \ref{isathm:soundness-satplan-encoding} first establishes the
+equality \<^term>\<open>\<sigma> = \<tau>\<close> of the decoded state sequence and the trace of \<^term>\<open>\<pi>\<close>.
+We can then derive that \<^term>\<open>G \<subseteq>\<^sub>m last \<sigma>\<close> by lemma \ref{isathm:parallel-solution-trace-strips}, i.e. the last
+state reached by plan execution (and moreover the last state decoded from the model), satisfies the
+goal state \<^term>\<open>G\<close> defined by the problem. By lemma \ref{isathm:parallel-solution-trace-strips}, we
+can conclude that \<^term>\<open>\<pi>\<close> is a solution for \<^term>\<open>I\<close> and \<^term>\<open>G\<close>.
+
+Moreover, we show that all operators \<^term>\<open>op\<close> in all parallel operators \<^term>\<open>ops \<in> set \<pi>\<close>
+are also contained in \<^term>\<open>\<O>\<close>. This is the case because the plan decoding function reverses the
+encoding function (which only encodes operators in \<^term>\<open>\<O>\<close>).
+
+By definition \ref{isadef:parallel-solution-strips} this means that \<^term>\<open>\<pi>\<close> is a parallel solution
+for \<^term>\<open>\<Pi>\<close>. Moreover \<^term>\<open>\<pi>\<close> has length \<^term>\<open>t\<close> as confirmed by lemma
+\isaname{decode_plan_length}.
+\footnote{This lemma is used in the proof but not shown.} \<close>
+
+theorem encode_problem_parallel_sound:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi> \<Pi> t"
+ shows "is_parallel_solution_for_problem \<Pi> (\<Phi>\<inverse> \<Pi> \<A> t)"
+ proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?I = "(\<Pi>)\<^sub>I"
+ and ?G = "(\<Pi>)\<^sub>G"
+ and ?\<pi> = "\<Phi>\<inverse> \<Pi> \<A> t"
+ let ?\<sigma> = "map (\<lambda> k. \<Phi>\<^sub>S\<inverse> \<Pi> \<A> k) [0..<Suc (length ?\<pi>)]"
+ and ?\<tau> = "trace_parallel_plan_strips ?I ?\<pi>"
+ {
+ have "?\<sigma> = ?\<tau>"
+ using encode_problem_parallel_correct_x[OF assms].
+ moreover {
+ have "length ?\<pi> = t"
+ using decode_plan_length
+ by auto
+ then have "?G \<subseteq>\<^sub>m last ?\<sigma>"
+ using decode_state_at_goal_state[OF assms]
+ by simp
+ }
+ ultimately have "((\<Pi>)\<^sub>G) \<subseteq>\<^sub>m execute_parallel_plan ((\<Pi>)\<^sub>I) (\<Phi>\<inverse> \<Pi> \<A> t)"
+ using execute_parallel_plan_reaches_goal_iff_goal_is_last_element_of_trace
+ by auto
+ }
+ moreover have "\<forall>ops \<in> set ?\<pi>. \<forall>op \<in> set ops. op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using encode_problem_parallel_correct_xi[OF assms(1, 2)]
+ by auto
+ ultimately show ?thesis
+ unfolding is_parallel_solution_for_problem_def
+ unfolding list_all_iff ListMem_iff operators_of_def STRIPS_Representation.operators_of_def
+ by fastforce
+ qed
+
+value "stop" (* Tell document preparation to stop collecting for the last tag *)
+
+
+
+subsection "Completeness"
+
+(* TODO make abbreviation *)
+definition empty_valuation :: "sat_plan_variable valuation" ("\<A>\<^sub>0")
+ where "empty_valuation \<equiv> (\<lambda>_. False)"
+
+abbreviation valuation_for_state
+ :: "'variable list
+ \<Rightarrow>'variable strips_state
+ \<Rightarrow> nat
+ \<Rightarrow> 'variable
+ \<Rightarrow> sat_plan_variable valuation
+ \<Rightarrow> sat_plan_variable valuation"
+ where "valuation_for_state vs s k v \<A>
+ \<equiv> \<A>(State k (index vs v) := (s v = Some True))"
+
+\<comment> \<open> Since the trace may be shorter than the plan length even though the last trace element
+subsumes the goal state---namely in case plan execution is impossible due to violation of the
+execution condition but the reached state serendipitously subsumes the goal state---, we also have
+to repeat the valuation for all time steps \<^term>\<open>k' \<in> {length \<tau>..(length \<pi> + 1)}\<close> for all \
+\<^term>\<open>v \<in> \<V>\<close> (see \<^term>\<open>\<A>\<^sub>2\<close>). \<close>
+definition valuation_for_state_variables
+ :: "'variable strips_problem
+ \<Rightarrow> 'variable strips_operator list list
+ \<Rightarrow> 'variable strips_state list
+ \<Rightarrow> sat_plan_variable valuation"
+ where "valuation_for_state_variables \<Pi> \<pi> \<tau> \<equiv> let
+ t' = length \<tau>
+ ; \<tau>\<^sub>\<Omega> = \<tau> ! (t' - 1)
+ ; vs = variables_of \<Pi>
+ ; V\<^sub>1 = { State k (index vs v) | k v. k \<in> {0..<t'} \<and> v \<in> set vs }
+ ; V\<^sub>2 = { State k (index vs v) | k v. k \<in> {t'..(length \<pi> + 1)} \<and> v \<in> set vs }
+ ; \<A>\<^sub>1 = foldr
+ (\<lambda>(k, v) \<A>. valuation_for_state (variables_of \<Pi>) (\<tau> ! k) k v \<A>)
+ (List.product [0..<t'] vs)
+ \<A>\<^sub>0
+ ; \<A>\<^sub>2 = foldr
+ (\<lambda>(k, v) \<A>. valuation_for_state (variables_of \<Pi>) \<tau>\<^sub>\<Omega> k v \<A>)
+ (List.product [t'..<length \<pi> + 2] vs)
+ \<A>\<^sub>0
+ in override_on (override_on \<A>\<^sub>0 \<A>\<^sub>1 V\<^sub>1) \<A>\<^sub>2 V\<^sub>2"
+
+\<comment> \<open> The valuation is left to yield false for the potentially remaining
+\<^term>\<open>k' \<in> {length \<tau>..(length \<pi> + 1)}\<close> since no more operators are executed after the trace ends
+anyway. The definition of \<^term>\<open>\<A>\<^sub>0\<close> as the valuation that is false for every argument ensures
+this implicitely. \<close>
+definition valuation_for_operator_variables
+ :: "'variable strips_problem
+ \<Rightarrow> 'variable strips_operator list list
+ \<Rightarrow> 'variable strips_state list
+ \<Rightarrow> sat_plan_variable valuation"
+ where "valuation_for_operator_variables \<Pi> \<pi> \<tau> \<equiv> let
+ ops = operators_of \<Pi>
+ ; Op = { Operator k (index ops op) | k op. k \<in> {0..<length \<tau> - 1} \<and> op \<in> set ops }
+ in override_on
+ \<A>\<^sub>0
+ (foldr
+ (\<lambda>(k, op) \<A>. \<A>(Operator k (index ops op) := True))
+ (concat (map (\<lambda>k. map (Pair k) (\<pi> ! k)) [0..<length \<tau> - 1]))
+ \<A>\<^sub>0)
+ Op"
+
+
+text \<open> The completeness proof requires that we show that the SATPlan encoding \<^term>\<open>\<Phi> \<Pi> t\<close> of a
+problem \<^term>\<open>\<Pi>\<close> has a model \<^term>\<open>\<A>\<close> in case a solution \<^term>\<open>\<pi>\<close> with length \<^term>\<open>t\<close> exists.
+Since a plan corresponds to a state trace \<^term>\<open>\<tau> \<equiv> trace_parallel_plan_strips I \<pi>\<close> with
+ @{text[display, indent=4] "\<tau> ! k = execute_parallel_plan I (take k \<pi>)"}
+for all \<^term>\<open>k < length \<tau>\<close> we can construct a valuation \<^term>\<open>\<A>\<^sub>V\<close> modeling the state sequence in
+\<^term>\<open>\<tau>\<close> by letting
+ @{text[display, indent=4] "\<A>(State k (index vs v) := (s v = Some True))"}
+or all \<^term>\<open>v \<in> \<V>\<close> where \<^term>\<open>s \<equiv> \<tau> ! k\<close> .
+\footnote{It is helpful to remember at this point, that the trace elements of a solution contain
+the states reached by plan prefix execution (lemma \ref{isathm:trace-elements-and-plan-prefixes}).}
+
+Similarly to \<^term>\<open>\<A>\<^sub>V\<close>, we obtain an operator valuation \<^term>\<open>\<A>\<^sub>O\<close> by defining
+ @{text[display, indent=4] "\<A>(Operator k (index ops op) := True)"}
+for all operators \<^term>\<open>op \<in> \<O>\<close> s.t. \<^term>\<open>op \<in> set (\<pi> ! k)\<close> for all \<^term>\<open>k < length \<tau> - 1\<close>.
+
+The overall valuation for the plan execution \<^term>\<open>\<A>\<close> can now be constructed by combining the
+state variable valuation \<^term>\<open>\<A>\<^sub>V\<close> and operator valuation \<^term>\<open>\<A>\<^sub>O\<close>. \<close>
+
+definition valuation_for_plan
+ :: "'variable strips_problem
+ \<Rightarrow> 'variable strips_operator list list
+ \<Rightarrow> sat_plan_variable valuation"
+ where "valuation_for_plan \<Pi> \<pi> \<equiv> let
+ vs = variables_of \<Pi>
+ ; ops = operators_of \<Pi>
+ ; \<tau> = trace_parallel_plan_strips (initial_of \<Pi>) \<pi>
+ ; t = length \<pi>
+ ; t' = length \<tau>
+ ; \<A>\<^sub>V = valuation_for_state_variables \<Pi> \<pi> \<tau>
+ ; \<A>\<^sub>O = valuation_for_operator_variables \<Pi> \<pi> \<tau>
+ ; V = { State k (index vs v)
+ | k v. k \<in> {0..<t + 1} \<and> v \<in> set vs }
+ ; Op = { Operator k (index ops op)
+ | k op. k \<in> {0..<t} \<and> op \<in> set ops }
+ in override_on (override_on \<A>\<^sub>0 \<A>\<^sub>V V) \<A>\<^sub>O Op"
+
+
+\<comment> \<open> Show that in case of an encoding with makespan zero, it suffices to show that a given
+model satisfies the initial state and goal state encodings. \<close>
+(* TODO refactor. *)
+lemma model_of_encode_problem_makespan_zero_iff:
+ "\<A> \<Turnstile> \<Phi> \<Pi> 0 \<longleftrightarrow> \<A> \<Turnstile> \<Phi>\<^sub>I \<Pi> \<^bold>\<and> (\<Phi>\<^sub>G \<Pi>) 0"
+proof -
+ have "encode_operators \<Pi> 0 = \<^bold>\<not>\<bottom> \<^bold>\<and> \<^bold>\<not>\<bottom>"
+ unfolding encode_operators_def encode_all_operator_effects_def
+ encode_all_operator_preconditions_def
+ by simp
+ moreover have "encode_all_frame_axioms \<Pi> 0 = \<^bold>\<not>\<bottom>"
+ unfolding encode_all_frame_axioms_def
+ by simp
+ ultimately show ?thesis
+ unfolding encode_problem_def SAT_Plan_Base.encode_problem_def encode_initial_state_def
+ encode_goal_state_def
+ by simp
+qed
+
+(* TODO refactor. *)
+lemma empty_valution_is_False[simp]: "\<A>\<^sub>0 v = False"
+ unfolding empty_valuation_def..
+
+lemma model_initial_state_set_valuations:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "set (map (\<lambda>v. case ((\<Pi>)\<^sub>I) v of Some b
+ \<Rightarrow> \<A>\<^sub>0(State 0 (index (strips_problem.variables_of \<Pi>) v) := b)
+ | _ \<Rightarrow> \<A>\<^sub>0)
+ (strips_problem.variables_of \<Pi>))
+ = { \<A>\<^sub>0(State 0 (index (strips_problem.variables_of \<Pi>) v) := the (((\<Pi>)\<^sub>I) v))
+ | v. v \<in> set ((\<Pi>)\<^sub>\<V>) }"
+proof -
+ let ?I = "(\<Pi>)\<^sub>I"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ let ?f = "\<lambda>v. case ((\<Pi>)\<^sub>I) v of Some b
+ \<Rightarrow> \<A>\<^sub>0(State 0 (index ?vs v) := b) | _ \<Rightarrow> \<A>\<^sub>0"
+ and ?g = "\<lambda>v. \<A>\<^sub>0(State 0 (index ?vs v) := the (?I v))"
+ let ?\<A>s = "map ?f ?vs"
+ have nb\<^sub>1: "dom ?I = set ((\<Pi>)\<^sub>\<V>)"
+ using is_valid_problem_strips_initial_of_dom assms
+ by fastforce
+ {
+ {
+ fix v
+ assume "v \<in> dom ?I"
+ hence "?f v = ?g v"
+ using nb\<^sub>1
+ by fastforce
+ }
+ hence "?f ` set ((\<Pi>)\<^sub>\<V>) = ?g ` set ((\<Pi>)\<^sub>\<V>)"
+ using nb\<^sub>1
+ by force
+ }
+ then have "set ?\<A>s = ?g ` set ((\<Pi>)\<^sub>\<V>)"
+ unfolding set_map
+ by simp
+ thus ?thesis
+ by blast
+qed
+
+(* TODO refactor *)
+lemma valuation_of_state_variable_implies_lit_semantics_if:
+ assumes "v \<in> dom S"
+ and "\<A> (State k (index vs v)) = the (S v)"
+ shows "lit_semantics \<A> (literal_formula_to_literal (encode_state_variable k (index vs v) (S v)))"
+proof -
+ let ?L = "literal_formula_to_literal (encode_state_variable k (index vs v) (S v))"
+ consider (True) "S v = Some True"
+ | (False) "S v = Some False"
+ using assms(1)
+ by fastforce
+ thus ?thesis
+ unfolding encode_state_variable_def
+ using assms(2)
+ by (cases, force+)
+qed
+
+(* TODO refactor \<open>Fun_Supplement\<close>? *)
+lemma foldr_fun_upd:
+ assumes "inj_on f (set xs)"
+ and "x \<in> set xs"
+ shows "foldr (\<lambda>x \<A>. \<A>(f x := g x)) xs \<A> (f x) = g x"
+ using assms
+proof (induction xs)
+ case (Cons a xs)
+ then show ?case
+ proof (cases "xs = []")
+ case True
+ then have "x = a"
+ using Cons.prems(2)
+ by simp
+ thus ?thesis
+ by simp
+ next
+ case False
+ thus ?thesis
+ proof (cases "a = x")
+ next
+ case False
+ {
+ from False
+ have "x \<in> set xs"
+ using Cons.prems(2)
+ by simp
+ moreover have "inj_on f (set xs)"
+ using Cons.prems(1)
+ by fastforce
+ ultimately have "(foldr (\<lambda>x \<A>. \<A>(f x := g x)) xs \<A>) (f x) = g x"
+ using Cons.IH
+ by blast
+ } moreover {
+ \<comment> \<open> Follows from modus tollens on the definition of @{text "inj_on"}. \<close>
+ have "f a \<noteq> f x"
+ using Cons.prems False
+ by force
+ moreover have "foldr (\<lambda>x \<A>. \<A>(f x := g x)) (a # xs) \<A>
+ = (foldr (\<lambda>x \<A>. \<A>(f x := g x)) xs \<A>)(f a := g a)"
+ by simp
+ ultimately have "foldr (\<lambda>x \<A>. \<A>(f x := g x)) (a # xs) \<A> (f x)
+ = (foldr (\<lambda>x \<A>. \<A>(f x := g x)) xs \<A>) (f x)"
+ unfolding fun_upd_def
+ by presburger
+ } ultimately show ?thesis
+ by argo
+ qed simp
+ qed
+qed fastforce
+
+lemma foldr_fun_no_upd:
+ assumes "inj_on f (set xs)"
+ and "y \<notin> f ` set xs"
+ shows "foldr (\<lambda>x \<A>. \<A>(f x := g x)) xs \<A> y = \<A> y"
+ using assms
+proof (induction xs)
+ case (Cons a xs)
+ {
+ have "inj_on f (set xs)" and "y \<notin> f ` set xs"
+ using Cons.prems
+ by (fastforce, simp)
+ hence "foldr (\<lambda>x \<A>. \<A>(f x := g x)) xs \<A> y = \<A> y"
+ using Cons.IH
+ by blast
+ }
+ moreover {
+ have "f a \<noteq> y"
+ using Cons.prems(2)
+ by auto
+ moreover have "foldr (\<lambda>x \<A>. \<A>(f x := g x)) (a # xs) \<A>
+ = (foldr (\<lambda>x \<A>. \<A>(f x := g x)) xs \<A>)(f a := g a)"
+ by simp
+ ultimately have "foldr (\<lambda>x \<A>. \<A>(f x := g x)) (a # xs) \<A> y
+ = (foldr (\<lambda>x \<A>. \<A>(f x := g x)) xs \<A>) y"
+ unfolding fun_upd_def
+ by presburger
+ }
+ ultimately show ?case
+ by argo
+qed simp
+
+\<comment> \<open> We only use the part of the characterization of \<open>\<A>\<close> which pertains to the state
+variables here. \<close>
+lemma encode_problem_parallel_complete_i:
+ fixes \<Pi>::"'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "(\<Pi>)\<^sub>G \<subseteq>\<^sub>m execute_parallel_plan ((\<Pi>)\<^sub>I) \<pi>"
+ "\<forall>v k. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)
+ \<longrightarrow> (\<A> (State k (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! k) v = Some True)
+ \<and> (\<not>\<A> (State k (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> ((trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! k) v \<noteq> Some True))"
+ shows "\<A> \<Turnstile> \<Phi>\<^sub>I \<Pi>"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?I = "(\<Pi>)\<^sub>I"
+ and ?G = "(\<Pi>)\<^sub>G"
+ and ?\<Phi>\<^sub>I = "\<Phi>\<^sub>I \<Pi>"
+ let ?\<tau> = "trace_parallel_plan_strips ?I \<pi>"
+ {
+ fix C
+ assume "C \<in> cnf ?\<Phi>\<^sub>I"
+ then obtain v
+ where v_in_set_vs: "v \<in> set ?vs"
+ and C_is: "C = { literal_formula_to_literal (encode_state_variable 0 (index ?vs v) (?I v)) }"
+ using cnf_of_encode_initial_state_set_ii[OF assms(1)]
+ by auto
+ {
+ have "0 < length ?\<tau>"
+ using trace_parallel_plan_strips_not_nil
+ by blast
+ then have "\<A> (State 0 (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! 0) v = Some True"
+ and "\<not>\<A> (State 0 (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> ((trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! 0) v \<noteq> Some True)"
+ using assms(3)
+ by (presburger+)
+ } note nb = this
+ {
+ let ?L = "literal_formula_to_literal (encode_state_variable 0 (index ?vs v) (?I v))"
+ have \<tau>_0_is: "?\<tau> ! 0 = ?I"
+ using trace_parallel_plan_strips_head_is_initial_state
+ by blast
+ have v_in_dom_I: "v \<in> dom ?I"
+ using is_valid_problem_strips_initial_of_dom assms(1) v_in_set_vs
+ by fastforce
+ then consider (I_v_is_Some_True) "?I v = Some True"
+ | (I_v_is_Some_False) "?I v = Some False"
+ by fastforce
+ hence "lit_semantics \<A> ?L"
+ unfolding encode_state_variable_def
+ using assms(3) \<tau>_0_is nb
+ by (cases, force+)
+ }
+ hence "clause_semantics \<A> C"
+ unfolding clause_semantics_def C_is
+ by blast
+ }
+ thus ?thesis
+ using is_cnf_encode_initial_state[OF assms(1)] is_nnf_cnf cnf_semantics
+ unfolding cnf_semantics_def
+ by blast
+qed
+
+\<comment> \<open> Plans may terminate early (i.e. by reaching a state satisfying the goal state before
+reaching the time point corresponding to the plan length). We therefore have to show the goal by
+splitting cases on whether the plan successfully terminated early.
+If not, we can just derive the goal from the assumptions pertaining to \<open>\<A>\<close> Otherwise, we
+have to first show that the goal was reached (albeit early) and that our valuation \<open>\<A>\<close>
+reflects the termination of plan execution after the time point at which the goal was reached. \<close>
+lemma encode_problem_parallel_complete_ii:
+ fixes \<Pi>::"'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "(\<Pi>)\<^sub>G \<subseteq>\<^sub>m execute_parallel_plan ((\<Pi>)\<^sub>I) \<pi>"
+ and "\<forall>v k. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)
+ \<longrightarrow> (\<A> (State k (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! k) v = Some True)"
+ and "\<forall>v l. l \<ge> length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) \<and> l < length \<pi> + 1
+ \<longrightarrow> \<A> (State l (index (strips_problem.variables_of \<Pi>) v))
+ = \<A> (State (length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1)
+ (index (strips_problem.variables_of \<Pi>) v))"
+ shows "\<A> \<Turnstile> (\<Phi>\<^sub>G \<Pi>)(length \<pi>)"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?I = "(\<Pi>)\<^sub>I"
+ and ?G = "(\<Pi>)\<^sub>G"
+ and ?\<Phi>\<^sub>I = "\<Phi>\<^sub>I \<Pi>"
+ and ?t = "length \<pi>"
+ and ?\<Phi>\<^sub>G = "(\<Phi>\<^sub>G \<Pi>) (length \<pi>)"
+ let ?\<tau> = "trace_parallel_plan_strips ?I \<pi>"
+ let ?t' = "length ?\<tau>"
+ {
+ fix v
+ assume G_of_v_is_not_None: "?G v \<noteq> None"
+ have "?G \<subseteq>\<^sub>m last ?\<tau>"
+ using execute_parallel_plan_reaches_goal_iff_goal_is_last_element_of_trace assms(2)
+ by blast
+ also have "\<dots> = ?\<tau> ! (?t' - 1)"
+ using last_conv_nth[OF trace_parallel_plan_strips_not_nil].
+ finally have "?G \<subseteq>\<^sub>m ?\<tau> ! (?t' - 1)"
+ by argo
+ hence "(?\<tau> ! (?t' - 1)) v = ?G v"
+ using G_of_v_is_not_None
+ unfolding map_le_def
+ by force
+ } note nb\<^sub>1 = this
+ (* TODO refactor. *)
+ \<comment> \<open> Discriminate on whether the trace has full length or not and show that the model
+ valuation of the state variables always correspond to the (defined) goal state values. \<close>
+ {
+ fix v
+ assume G_of_v_is_not_None: "?G v \<noteq> None"
+ hence "\<A> (State ?t (index ?vs v)) \<longleftrightarrow> ?G v = Some True"
+ proof (cases "?t' = ?t + 1")
+ case True
+ moreover have "?t < ?t'"
+ using calculation
+ by fastforce
+ moreover have "\<A> (State ?t (index ?vs v)) \<longleftrightarrow> (?\<tau> ! ?t) v = Some True"
+ using assms(3) calculation(2)
+ by blast
+ ultimately show ?thesis
+ using nb\<^sub>1[OF G_of_v_is_not_None]
+ by force
+ next
+ case False
+ {
+ have "?t' < ?t + 1"
+ using length_trace_parallel_plan_strips_lte_length_plan_plus_one False
+ le_neq_implies_less
+ by blast
+ moreover have "\<A> (State ?t (index ?vs v)) = \<A> (State (?t' - 1) (index ?vs v))"
+ using assms(4) calculation
+ by simp
+ moreover have "?t' - 1 < ?t'"
+ using trace_parallel_plan_strips_not_nil length_greater_0_conv[of ?\<tau>]
+ less_diff_conv2[of 1 ?t' ?t']
+ by force
+ moreover have "\<A> (State (?t' - 1) (index ?vs v)) \<longleftrightarrow> (?\<tau> ! (?t' - 1)) v = Some True"
+ using assms(3) calculation(3)
+ by blast
+ ultimately have "\<A> (State ?t (index ?vs v)) \<longleftrightarrow> (?\<tau> ! (?t' - 1)) v = Some True"
+ by blast
+ }
+ thus ?thesis
+ using nb\<^sub>1[OF G_of_v_is_not_None]
+ by presburger
+ qed
+ } note nb\<^sub>2 = this
+ {
+ fix C
+ assume C_in_cnf_of_\<Phi>\<^sub>G: "C \<in> cnf ?\<Phi>\<^sub>G"
+
+ moreover obtain v
+ where "v \<in> set ?vs"
+ and G_of_v_is_not_None: "?G v \<noteq> None"
+ and C_is: "C = { literal_formula_to_literal (encode_state_variable ?t (index ?vs v)
+ (?G v)) }"
+ using cnf_of_encode_goal_state_set_ii[OF assms(1)] calculation
+ by auto
+ consider (G_of_v_is_Some_True) "?G v = Some True"
+ | (G_of_v_is_Some_False) "?G v = Some False"
+ using G_of_v_is_not_None
+ by fastforce
+ then have "clause_semantics \<A> C"
+ using nb\<^sub>2 C_is
+ unfolding clause_semantics_def encode_state_variable_def
+ by (cases, force+)
+ }
+ thus ?thesis
+ using cnf_semantics[OF is_nnf_cnf[OF encode_goal_state_is_cnf[OF assms(1)]]]
+ unfolding cnf_semantics_def
+ by blast
+qed
+
+\<comment> \<open> We are not using the full characterization of \<open>\<A>\<close> here since it's not needed. \<close>
+(* TODO make private *)
+lemma encode_problem_parallel_complete_iii_a:
+ fixes \<Pi>::"'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "(\<Pi>)\<^sub>G \<subseteq>\<^sub>m execute_parallel_plan ((\<Pi>)\<^sub>I) \<pi>"
+ and "C \<in> cnf (encode_all_operator_preconditions \<Pi> (strips_problem.operators_of \<Pi>) (length \<pi>))"
+ and "\<forall>k op. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1
+ \<longrightarrow> \<A> (Operator k (index (strips_problem.operators_of \<Pi>) op)) = (op \<in> set (\<pi> ! k))"
+ and "\<forall>l op. l \<ge> length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1 \<and> l < length \<pi>
+ \<longrightarrow> \<not>\<A> (Operator l (index (strips_problem.operators_of \<Pi>) op))"
+ and "\<forall>v k. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)
+ \<longrightarrow> (\<A> (State k (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! k) v = Some True)"
+ shows "clause_semantics \<A> C"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ and ?t = "length \<pi>"
+ let ?\<tau> = "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>"
+ (* TODO slow. *)
+ obtain k op
+ where k_and_op_are: "(k, op) \<in> ({0..<?t} \<times> set ((\<Pi>)\<^sub>\<O>))"
+ and "C \<in> (\<Union>v \<in> set (precondition_of op). {{ (Operator k (index ?ops op))\<inverse>
+ , (State k (index ?vs v))\<^sup>+ }})"
+ using cnf_of_encode_all_operator_preconditions_structure assms(3)
+ UN_E[of C ]
+ by auto
+ then obtain v
+ where v_in_preconditions_of_op: "v \<in> set (precondition_of op)"
+ and C_is: "C = { (Operator k (index ?ops op))\<inverse>, (State k (index ?vs v))\<^sup>+ }"
+ by blast
+ thus ?thesis
+ proof (cases "k < length ?\<tau> - 1")
+ case k_lt_length_\<tau>_minus_one: True
+ thus ?thesis
+ proof (cases "op \<in> set (\<pi> ! k)")
+ case True
+ {
+ have "are_all_operators_applicable (?\<tau> ! k) (\<pi> ! k)"
+ using trace_parallel_plan_strips_operator_preconditions k_lt_length_\<tau>_minus_one
+ by blast
+ then have "(?\<tau> ! k) v = Some True"
+ using are_all_operators_applicable_set v_in_preconditions_of_op True
+ by fast
+ hence "\<A> (State k (index ?vs v))"
+ using assms(6) k_lt_length_\<tau>_minus_one
+ by force
+ }
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ next
+ case False
+ then have "\<not>\<A> (Operator k (index ?ops op))"
+ using assms(4) k_lt_length_\<tau>_minus_one
+ by blast
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ qed
+ next
+ case False
+ then have "k \<ge> length ?\<tau> - 1" "k < ?t"
+ using k_and_op_are
+ by(force, simp)
+ then have "\<not>\<A> (Operator k (index ?ops op))"
+ using assms(5)
+ by blast
+ thus ?thesis
+ unfolding clause_semantics_def
+ using C_is
+ by fastforce
+ qed
+qed
+
+\<comment> \<open> We are not using the full characterization of \<open>\<A>\<close> here since it's not needed. \<close>
+(* TODO make private *)
+lemma encode_problem_parallel_complete_iii_b:
+ fixes \<Pi>::"'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "(\<Pi>)\<^sub>G \<subseteq>\<^sub>m execute_parallel_plan ((\<Pi>)\<^sub>I) \<pi>"
+ and "C \<in> cnf (encode_all_operator_effects \<Pi> (strips_problem.operators_of \<Pi>) (length \<pi>))"
+ and "\<forall>k op. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1
+ \<longrightarrow> \<A> (Operator k (index (strips_problem.operators_of \<Pi>) op)) = (op \<in> set (\<pi> ! k))"
+ and "\<forall>l op. l \<ge> length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1 \<and> l < length \<pi>
+ \<longrightarrow> \<not>\<A> (Operator l (index (strips_problem.operators_of \<Pi>) op))"
+ and "\<forall>v k. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)
+ \<longrightarrow> (\<A> (State k (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! k) v = Some True)"
+ shows "clause_semantics \<A> C"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ and ?t = "length \<pi>"
+ let ?\<tau> = "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>"
+ let ?A = "(\<Union>(k, op) \<in> {0..<?t} \<times> set ((\<Pi>)\<^sub>\<O>).
+ \<Union>v \<in> set (add_effects_of op).
+ {{ (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }})"
+ and ?B = "(\<Union>(k, op) \<in> {0..<?t} \<times> set ((\<Pi>)\<^sub>\<O>).
+ \<Union>v \<in> set (delete_effects_of op).
+ {{ (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse> }})"
+ consider (C_in_A) "C \<in> ?A"
+ | (C_in_B) "C \<in> ?B"
+ using Un_iff[of C ?A ?B] cnf_of_encode_all_operator_effects_structure assms(3)
+ by (metis C_in_A C_in_B)
+ thus ?thesis
+ proof (cases)
+ case C_in_A
+ then obtain k op
+ where k_and_op_are: "(k, op) \<in> {0..<?t} \<times> set((\<Pi>)\<^sub>\<O>)"
+ and "C \<in> (\<Union>v \<in> set (add_effects_of op).
+ {{ (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }})"
+ by blast
+ then obtain v where v_in_add_effects_of_op: "v \<in> set (add_effects_of op)"
+ and C_is: "C = { (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }"
+ by blast
+ thus ?thesis
+ proof (cases "k < length ?\<tau> - 1")
+ case k_lt_length_\<tau>_minus_one: True
+ thus ?thesis
+ proof (cases "op \<in> set (\<pi> ! k)")
+ case True
+ {
+ then have "are_all_operators_applicable (?\<tau> ! k) (\<pi> ! k)"
+ and "are_all_operator_effects_consistent (\<pi> ! k)"
+ using trace_parallel_plan_strips_operator_preconditions k_lt_length_\<tau>_minus_one
+ by blast+
+ hence "execute_parallel_operator (?\<tau> ! k) (\<pi> ! k) v = Some True"
+ using execute_parallel_operator_positive_effect_if[
+ OF _ _ True v_in_add_effects_of_op, of "?\<tau> ! k"]
+ by blast
+ }
+ then have \<tau>_Suc_k_is_Some_True: "(?\<tau> ! Suc k) v = Some True"
+ using trace_parallel_plan_step_effect_is[OF k_lt_length_\<tau>_minus_one]
+ by argo
+ have "\<A> (State (Suc k) (index ?vs v))"
+ using assms(6) k_lt_length_\<tau>_minus_one \<tau>_Suc_k_is_Some_True
+ by fastforce
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ next
+ case False
+ then have "\<not>\<A> (Operator k (index ?ops op))"
+ using assms(4) k_lt_length_\<tau>_minus_one
+ by blast
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by force
+ qed
+ next
+ case False
+ then have "k \<ge> length ?\<tau> - 1" and "k < ?t"
+ using k_and_op_are
+ by auto
+ then have "\<not>\<A> (Operator k (index ?ops op))"
+ using assms(5)
+ by blast
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ qed
+ next
+ \<comment> \<open> This case is completely symmetrical to the one above. \<close>
+ case C_in_B
+ then obtain k op
+ where k_and_op_are: "(k, op) \<in> {0..<?t} \<times> set ((\<Pi>)\<^sub>\<O>)"
+ and "C \<in> (\<Union>v \<in> set (delete_effects_of op).
+ {{ (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse> }})"
+ by blast
+ then obtain v where v_in_delete_effects_of_op: "v \<in> set (delete_effects_of op)"
+ and C_is: "C = { (Operator k (index ?ops op))\<inverse>, (State (Suc k) (index ?vs v))\<inverse> }"
+ by blast
+ thus ?thesis
+ proof (cases "k < length ?\<tau> - 1")
+ case k_lt_length_\<tau>_minus_one: True
+ thus ?thesis
+ proof (cases "op \<in> set (\<pi> ! k)")
+ case True
+ {
+ then have "are_all_operators_applicable (?\<tau> ! k) (\<pi> ! k)"
+ and "are_all_operator_effects_consistent (\<pi> ! k)"
+ using trace_parallel_plan_strips_operator_preconditions k_lt_length_\<tau>_minus_one
+ by blast+
+ hence "execute_parallel_operator (?\<tau> ! k) (\<pi> ! k) v = Some False"
+ using execute_parallel_operator_negative_effect_if[
+ OF _ _ True v_in_delete_effects_of_op, of "?\<tau> ! k"]
+ by blast
+ }
+ then have \<tau>_Suc_k_is_Some_True: "(?\<tau> ! Suc k) v = Some False"
+ using trace_parallel_plan_step_effect_is[OF k_lt_length_\<tau>_minus_one]
+ by argo
+ have "\<not>\<A> (State (Suc k) (index ?vs v))"
+ using assms(6) k_lt_length_\<tau>_minus_one \<tau>_Suc_k_is_Some_True
+ by fastforce
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ next
+ case False
+ then have "\<not>\<A> (Operator k (index ?ops op))"
+ using assms(4) k_lt_length_\<tau>_minus_one
+ by blast
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by force
+ qed
+ next
+ case False
+ then have "k \<ge> length ?\<tau> - 1" and "k < ?t"
+ using k_and_op_are
+ by auto
+ then have "\<not>\<A> (Operator k (index ?ops op))"
+ using assms(5)
+ by blast
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ qed
+ qed
+qed
+
+(* TODO make private *)
+lemma encode_problem_parallel_complete_iii:
+ fixes \<Pi>::"'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "(\<Pi>)\<^sub>G \<subseteq>\<^sub>m execute_parallel_plan ((\<Pi>)\<^sub>I) \<pi>"
+ and "\<forall>k op. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1
+ \<longrightarrow> \<A> (Operator k (index (strips_problem.operators_of \<Pi>) op)) = (op \<in> set (\<pi> ! k))"
+ and "\<forall>l op. l \<ge> length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1 \<and> l < length \<pi>
+ \<longrightarrow> \<not>\<A> (Operator l (index (strips_problem.operators_of \<Pi>) op))"
+ and "\<forall>v k. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)
+ \<longrightarrow> (\<A> (State k (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! k) v = Some True)"
+ shows "\<A> \<Turnstile> encode_operators \<Pi> (length \<pi>)"
+proof -
+ let ?t = "length \<pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ let ?\<Phi>\<^sub>O = "encode_operators \<Pi> ?t"
+ and ?\<Phi>\<^sub>P = "encode_all_operator_preconditions \<Pi> ?ops?t"
+ and ?\<Phi>\<^sub>E = "encode_all_operator_effects \<Pi> ?ops ?t"
+ {
+ fix C
+ assume "C \<in> cnf ?\<Phi>\<^sub>O"
+ then consider (C_in_precondition_encoding) "C \<in> cnf ?\<Phi>\<^sub>P"
+ | (C_in_effect_encoding) "C \<in> cnf ?\<Phi>\<^sub>E"
+ using cnf_of_operator_encoding_structure
+ by blast
+ hence "clause_semantics \<A> C"
+ proof (cases)
+ case C_in_precondition_encoding
+ thus ?thesis
+ using encode_problem_parallel_complete_iii_a[OF assms(1, 2) _ assms(3, 4, 5)]
+ by blast
+ next
+ case C_in_effect_encoding
+ thus ?thesis
+ using encode_problem_parallel_complete_iii_b[OF assms(1, 2) _ assms(3, 4, 5)]
+ by blast
+ qed
+ }
+ thus ?thesis
+ using encode_operators_is_cnf[OF assms(1)] is_nnf_cnf cnf_semantics
+ unfolding cnf_semantics_def
+ by blast
+qed
+
+(* TODO make private *)
+lemma encode_problem_parallel_complete_iv_a:
+ fixes \<Pi> :: "'a strips_problem"
+ assumes "STRIPS_Semantics.is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "\<forall>k op. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1
+ \<longrightarrow> \<A> (Operator k (index (strips_problem.operators_of \<Pi>) op)) = (op \<in> set (\<pi> ! k))"
+ and "\<forall>v k. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)
+ \<longrightarrow> (\<A> (State k (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! k) v = Some True)"
+ and "\<forall>v l. l \<ge> length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) \<and> l < length \<pi> + 1
+ \<longrightarrow> \<A> (State l (index (strips_problem.variables_of \<Pi>) v))
+ = \<A> (State
+ (length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1)
+ (index (strips_problem.variables_of \<Pi>) v))"
+ and "C \<in> \<Union> (\<Union>(k, v) \<in> {0..<length \<pi>} \<times> set ((\<Pi>)\<^sub>\<V>).
+ {{{ (State k (index (strips_problem.variables_of \<Pi>) v))\<^sup>+
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<inverse> }
+ \<union> { (Operator k (index (strips_problem.operators_of \<Pi>) op))\<^sup>+
+ |op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (add_effects_of op) }}})"
+ shows "clause_semantics \<A> C"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?t = "length \<pi>"
+ let ?\<tau> = "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>"
+ let ?A = "(\<Union>(k, v) \<in> {0..<?t} \<times> set ?vs.
+ {{{ (State k (index ?vs v))\<^sup>+, (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> { (Operator k (index ?ops op))\<^sup>+ |op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }}})"
+ (* TODO refactor *)
+ {
+ (* TODO slow *)
+ obtain C' where "C' \<in> ?A" and C_in_C': "C \<in> C'"
+ using Union_iff assms(5)
+ by auto
+ then obtain k v
+ where "(k, v) \<in> {0..<?t} \<times> set ?vs"
+ and "C' \<in> {{{ (State k (index ?vs v))\<^sup>+, (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> { (Operator k (index ?ops op))\<^sup>+ |op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }}}"
+ using UN_E
+ by blast
+ hence "\<exists>k v.
+ k \<in> {0..<?t}
+ \<and> v \<in> set ?vs
+ \<and> C = { (State k (index ?vs v))\<^sup>+, (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> { (Operator k (index ?ops op))\<^sup>+ |op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }"
+ using C_in_C'
+ by blast
+ }
+ then obtain k v
+ where k_in: "k \<in> {0..<?t}"
+ and v_in_vs: "v \<in> set ?vs"
+ and C_is: "C = { (State k (index ?vs v))\<^sup>+, (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> { (Operator k (index ?ops op))\<^sup>+ |op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }"
+ by blast
+ show ?thesis
+ proof (cases "k < length ?\<tau> - 1")
+ case k_lt_length_\<tau>_minus_one: True
+ then have k_lt_t: "k < ?t"
+ using k_in
+ by force
+ have all_operators_applicable: "are_all_operators_applicable (?\<tau> ! k) (\<pi> ! k)"
+ and all_operator_effects_consistent: "are_all_operator_effects_consistent (\<pi> ! k)"
+ using trace_parallel_plan_strips_operator_preconditions[OF k_lt_length_\<tau>_minus_one]
+ by simp+
+ then consider (A) "\<exists>op \<in> set (\<pi> ! k). v \<in> set (add_effects_of op)"
+ | (B) "\<exists>op \<in> set (\<pi> ! k). v \<in> set (delete_effects_of op)"
+ | (C) "\<forall>op \<in> set (\<pi> ! k). v \<notin> set (add_effects_of op) \<and> v \<notin> set (delete_effects_of op)"
+ by blast
+ thus ?thesis
+ proof (cases)
+ case A
+ moreover obtain op
+ where op_in_\<pi>\<^sub>k: "op \<in> set (\<pi> ! k)"
+ and v_is_add_effect: "v \<in> set (add_effects_of op)"
+ using A
+ by blast
+ moreover {
+ have "(\<pi> ! k) \<in> set \<pi>"
+ using k_lt_t
+ by simp
+ hence "op \<in> set ?ops"
+ using is_parallel_solution_for_problem_operator_set[OF assms(1) _ op_in_\<pi>\<^sub>k]
+ by blast
+ }
+ ultimately have "(Operator k (index ?ops op))\<^sup>+
+ \<in> { (Operator k (index ?ops op))\<^sup>+ | op. op \<in> set ?ops \<and> v \<in> set (add_effects_of op) }"
+ using v_is_add_effect
+ by blast
+ then have "(Operator k (index ?ops op))\<^sup>+ \<in> C"
+ using C_is
+ by auto
+ moreover have "\<A> (Operator k (index ?ops op))"
+ using assms(2) k_lt_length_\<tau>_minus_one op_in_\<pi>\<^sub>k
+ by blast
+ ultimately show ?thesis
+ unfolding clause_semantics_def
+ by force
+ next
+ case B
+ then obtain op
+ where op_in_\<pi>\<^sub>k: "op \<in> set (\<pi> ! k)"
+ and v_is_delete_effect: "v \<in> set (delete_effects_of op)"..
+ then have "\<not>(\<exists>op \<in> set (\<pi> ! k). v \<in> set (add_effects_of op))"
+ using all_operator_effects_consistent are_all_operator_effects_consistent_set
+ by fast
+ then have "execute_parallel_operator (?\<tau> ! k) (\<pi> ! k) v
+ = Some False"
+ using execute_parallel_operator_negative_effect_if[OF all_operators_applicable
+ all_operator_effects_consistent op_in_\<pi>\<^sub>k v_is_delete_effect]
+ by blast
+ moreover have "(?\<tau> ! Suc k) v = execute_parallel_operator (?\<tau> ! k) (\<pi> ! k) v"
+ using trace_parallel_plan_step_effect_is[OF k_lt_length_\<tau>_minus_one]
+ by simp
+ ultimately have "\<not>\<A> (State (Suc k) (index ?vs v))"
+ using assms(3) k_lt_length_\<tau>_minus_one
+ by simp
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by simp
+ next
+ case C
+ show ?thesis
+ proof (cases "(?\<tau> ! k) v = Some True")
+ case True
+ then have "\<A> (State k (index ?vs v))"
+ using assms(3) k_lt_length_\<tau>_minus_one
+ by force
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ next
+ case False
+ {
+ have "(?\<tau> ! Suc k) = execute_parallel_operator (?\<tau> ! k) (\<pi> ! k)"
+ using trace_parallel_plan_step_effect_is[OF k_lt_length_\<tau>_minus_one].
+ then have "(?\<tau> ! Suc k) v = (?\<tau> ! k) v"
+ using execute_parallel_operator_no_effect_if C
+ by fastforce
+ hence "(?\<tau> ! Suc k) v \<noteq> Some True"
+ using False
+ by argo
+ }
+ then have "\<not>\<A> (State (Suc k) (index ?vs v))"
+ using assms(3) k_lt_length_\<tau>_minus_one
+ by auto
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ qed
+ qed
+ next
+ case k_gte_length_\<tau>_minus_one: False
+ show ?thesis
+ proof (cases "\<A> (State (length ?\<tau> - 1) (index ?vs v))")
+ case True
+ {
+ have "\<A> (State k (index ?vs v)) = \<A> (State (length ?\<tau> - 1) (index ?vs v))"
+ proof (cases "k = length ?\<tau> - 1")
+ case False
+ then have "length ?\<tau> \<le> k" and "k < ?t + 1"
+ using k_gte_length_\<tau>_minus_one k_in
+ by fastforce+
+ thus ?thesis
+ using assms(4)
+ by blast
+ qed blast
+ hence "\<A> (State k (index ?vs v))"
+ using True
+ by blast
+ }
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by simp
+ next
+ case False
+ {
+ have "length ?\<tau> \<le> Suc k" and "Suc k < ?t + 1"
+ using k_gte_length_\<tau>_minus_one k_in
+ by fastforce+
+ then have "\<A> (State (Suc k) (index ?vs v)) = \<A> (State (length ?\<tau> - 1) (index ?vs v))"
+ using assms(4)
+ by blast
+ hence "\<not>\<A> (State (Suc k) (index ?vs v))"
+ using False
+ by blast
+ }
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ qed
+ qed
+qed
+
+(* TODO make private *)
+lemma encode_problem_parallel_complete_iv_b:
+ fixes \<Pi> :: "'a strips_problem"
+ assumes "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "\<forall>k op. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1
+ \<longrightarrow> \<A> (Operator k (index (strips_problem.operators_of \<Pi>) op)) = (op \<in> set (\<pi> ! k))"
+ and "\<forall>v k. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)
+ \<longrightarrow> (\<A> (State k (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! k) v = Some True)"
+ and "\<forall>v l. l \<ge> length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) \<and> l < length \<pi> + 1
+ \<longrightarrow> \<A> (State l (index (strips_problem.variables_of \<Pi>) v))
+ = \<A> (State
+ (length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1)
+ (index (strips_problem.variables_of \<Pi>) v))"
+ and "C \<in> \<Union> (\<Union>(k, v) \<in> {0..<length \<pi>} \<times> set ((\<Pi>)\<^sub>\<V>).
+ {{{ (State k (index (strips_problem.variables_of \<Pi>) v))\<inverse>
+ , (State (Suc k) (index (strips_problem.variables_of \<Pi>) v))\<^sup>+ }
+ \<union> { (Operator k (index (strips_problem.operators_of \<Pi>) op))\<^sup>+
+ |op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (delete_effects_of op) }}})"
+ shows "clause_semantics \<A> C"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?t = "length \<pi>"
+ let ?\<tau> = "trace_parallel_plan_strips (initial_of \<Pi>) \<pi>"
+ let ?A = "(\<Union>(k, v) \<in> {0..<?t} \<times> set ?vs.
+ {{{ (State k (index ?vs v))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> { (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (delete_effects_of op) }}})"
+ (* TODO refactor *)
+ {
+ (* TODO slow *)
+ obtain C' where "C' \<in> ?A" and C_in_C': "C \<in> C'"
+ using Union_iff assms(5)
+ by auto
+ (* TODO slow *)
+ then obtain k v
+ where "(k, v) \<in> {0..<?t} \<times> set ?vs"
+ and "C' \<in> {{{ (State k (index ?vs v))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> { (Operator k (index ?ops op))\<^sup>+ |op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op) }}}"
+ using UN_E
+ by fastforce
+ hence "\<exists>k v.
+ k \<in> {0..<?t}
+ \<and> v \<in> set ?vs
+ \<and> C = { (State k (index ?vs v))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> { (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (delete_effects_of op) }"
+ using C_in_C'
+ by auto
+ }
+ then obtain k v
+ where k_in: "k \<in> {0..<?t}"
+ and v_in_vs: "v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ and C_is: "C = { (State k (index ?vs v))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> { (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (delete_effects_of op) }"
+ by auto
+ show ?thesis
+ proof (cases "k < length ?\<tau> - 1")
+ case k_lt_length_\<tau>_minus_one: True
+ then have k_lt_t: "k < ?t"
+ using k_in
+ by force
+ have all_operators_applicable: "are_all_operators_applicable (?\<tau> ! k) (\<pi> ! k)"
+ and all_operator_effects_consistent: "are_all_operator_effects_consistent (\<pi> ! k)"
+ using trace_parallel_plan_strips_operator_preconditions[OF k_lt_length_\<tau>_minus_one]
+ by simp+
+ then consider (A) "\<exists>op \<in> set (\<pi> ! k). v \<in> set (delete_effects_of op)"
+ | (B) "\<exists>op \<in> set (\<pi> ! k). v \<in> set (add_effects_of op)"
+ | (C) "\<forall>op \<in> set (\<pi> ! k). v \<notin> set (add_effects_of op) \<and> v \<notin> set (delete_effects_of op)"
+ by blast
+ thus ?thesis
+ proof (cases)
+ case A
+ moreover obtain op
+ where op_in_\<pi>\<^sub>k: "op \<in> set (\<pi> ! k)"
+ and v_is_delete_effect: "v \<in> set (delete_effects_of op)"
+ using A
+ by blast
+ moreover {
+ have "(\<pi> ! k) \<in> set \<pi>"
+ using k_lt_t
+ by simp
+ hence "op \<in> set ?ops"
+ using is_parallel_solution_for_problem_operator_set[OF assms(1) _ op_in_\<pi>\<^sub>k]
+ by auto
+ }
+ ultimately have "(Operator k (index ?ops op))\<^sup>+
+ \<in> { (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ?ops \<and> v \<in> set (delete_effects_of op) }"
+ using v_is_delete_effect
+ by blast
+ then have "(Operator k (index ?ops op))\<^sup>+ \<in> C"
+ using C_is
+ by auto
+ moreover have "\<A> (Operator k (index ?ops op))"
+ using assms(2) k_lt_length_\<tau>_minus_one op_in_\<pi>\<^sub>k
+ by blast
+ ultimately show ?thesis
+ unfolding clause_semantics_def
+ by force
+ next
+ case B
+ then obtain op
+ where op_in_\<pi>\<^sub>k: "op \<in> set (\<pi> ! k)"
+ and v_is_add_effect: "v \<in> set (add_effects_of op)"..
+ then have "\<not>(\<exists>op \<in> set (\<pi> ! k). v \<in> set (delete_effects_of op))"
+ using all_operator_effects_consistent are_all_operator_effects_consistent_set
+ by fast
+ then have "execute_parallel_operator (?\<tau> ! k) (\<pi> ! k) v = Some True"
+ using execute_parallel_operator_positive_effect_if[OF all_operators_applicable
+ all_operator_effects_consistent op_in_\<pi>\<^sub>k v_is_add_effect]
+ by blast
+ moreover have "(?\<tau> ! Suc k) v = execute_parallel_operator (?\<tau> ! k) (\<pi> ! k) v"
+ using trace_parallel_plan_step_effect_is[OF k_lt_length_\<tau>_minus_one]
+ by simp
+ ultimately have "\<A> (State (Suc k) (index ?vs v))"
+ using assms(3) k_lt_length_\<tau>_minus_one
+ by simp
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by simp
+ next
+ case C
+ show ?thesis
+ \<comment> \<open> We split on cases for @{text "(?\<tau> ! k) v = Some True"} here to avoid having to
+ proof @{text "(?\<tau> ! k) v \<noteq> None"}. \<close>
+ proof (cases "(?\<tau> ! k) v = Some True")
+ case True
+ {
+ have "(?\<tau> ! Suc k) = execute_parallel_operator (?\<tau> ! k) (\<pi> ! k)"
+ using trace_parallel_plan_step_effect_is[OF k_lt_length_\<tau>_minus_one].
+ then have "(?\<tau> ! Suc k) v = (?\<tau> ! k) v"
+ using execute_parallel_operator_no_effect_if C
+ by fastforce
+ then have "(?\<tau> ! Suc k) v = Some True"
+ using True
+ by argo
+ hence "\<A> (State (Suc k) (index ?vs v))"
+ using assms(3) k_lt_length_\<tau>_minus_one
+ by fastforce
+ }
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ next
+ case False
+ then have "\<not>\<A> (State k (index ?vs v))"
+ using assms(3) k_lt_length_\<tau>_minus_one
+ by simp
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ qed
+ qed
+ next
+ case k_gte_length_\<tau>_minus_one: False
+ show ?thesis
+ proof (cases "\<A> (State (length ?\<tau> - 1) (index ?vs v))")
+ case True
+ {
+ have "length ?\<tau> \<le> Suc k" and "Suc k < ?t + 1"
+ using k_gte_length_\<tau>_minus_one k_in
+ by fastforce+
+ then have "\<A> (State (Suc k) (index ?vs v)) = \<A> (State (length ?\<tau> - 1) (index ?vs v))"
+ using assms(4)
+ by blast
+ hence "\<A> (State (Suc k) (index ?vs v))"
+ using True
+ by blast
+ }
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by fastforce
+ next
+ case False
+ {
+ have "\<A> (State k (index ?vs v)) = \<A> (State (length ?\<tau> - 1) (index ?vs v))"
+ proof (cases "k = length ?\<tau> - 1")
+ case False
+ then have "length ?\<tau> \<le> k" and "k < ?t + 1"
+ using k_gte_length_\<tau>_minus_one k_in
+ by fastforce+
+ thus ?thesis
+ using assms(4)
+ by blast
+ qed blast
+ hence "\<not>\<A> (State k (index ?vs v))"
+ using False
+ by blast
+ }
+ thus ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by simp
+ qed
+ qed
+qed
+
+(* TODO make private *)
+lemma encode_problem_parallel_complete_iv:
+ fixes \<Pi>::"'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "\<forall>k op. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1
+ \<longrightarrow> \<A> (Operator k (index (strips_problem.operators_of \<Pi>) op)) = (op \<in> set (\<pi> ! k))"
+ and "\<forall>v k. k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)
+ \<longrightarrow> (\<A> (State k (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! k) v = Some True)"
+ and "\<forall>v l. l \<ge> length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) \<and> l < length \<pi> + 1
+ \<longrightarrow> \<A> (State l (index (strips_problem.variables_of \<Pi>) v))
+ = \<A> (State
+ (length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1)
+ (index (strips_problem.variables_of \<Pi>) v))"
+ shows "\<A> \<Turnstile> encode_all_frame_axioms \<Pi> (length \<pi>)"
+proof -
+ let ?\<Phi>\<^sub>F = "encode_all_frame_axioms \<Pi> (length \<pi>)"
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?t = "length \<pi>"
+ let ?A = "\<Union> (\<Union>(k, v) \<in> {0..<?t} \<times> set ((\<Pi>)\<^sub>\<V>).
+ {{{ (State k (index ?vs v))\<^sup>+, (State (Suc k) (index ?vs v))\<inverse> }
+ \<union> { (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (add_effects_of op) }}})"
+ and ?B = "\<Union> (\<Union>(k, v) \<in> {0..<?t} \<times> set ((\<Pi>)\<^sub>\<V>).
+ {{{ (State k (index ?vs v))\<inverse>, (State (Suc k) (index ?vs v))\<^sup>+ }
+ \<union> { (Operator k (index ?ops op))\<^sup>+
+ | op. op \<in> set ((\<Pi>)\<^sub>\<O>) \<and> v \<in> set (delete_effects_of op) }}})"
+ (* TODO slow (and why can only metis do this?). *)
+ have cnf_\<Phi>\<^sub>F_is_A_union_B: "cnf ?\<Phi>\<^sub>F = ?A \<union> ?B"
+ using cnf_of_encode_all_frame_axioms_structure
+ by (simp add: cnf_of_encode_all_frame_axioms_structure)
+ {
+ fix C
+ assume "C \<in> cnf ?\<Phi>\<^sub>F"
+ then consider (C_in_A) "C \<in> ?A"
+ | (C_in_B) "C \<in> ?B"
+ using Un_iff[of C ?A ?B] cnf_\<Phi>\<^sub>F_is_A_union_B
+ by argo
+ hence "clause_semantics \<A> C"
+ proof (cases)
+ case C_in_A
+ then show ?thesis
+ using encode_problem_parallel_complete_iv_a[OF assms(2, 3, 4, 5) C_in_A]
+ by blast
+ next
+ case C_in_B
+ then show ?thesis
+ using encode_problem_parallel_complete_iv_b[OF assms(2, 3, 4, 5) C_in_B]
+ by blast
+ qed
+ }
+ thus ?thesis
+ using encode_frame_axioms_is_cnf is_nnf_cnf cnf_semantics
+ unfolding cnf_semantics_def
+ by blast
+qed
+
+(* TODO refactor. *)
+lemma valuation_for_operator_variables_is:
+ fixes \<Pi> :: "'a strips_problem"
+ assumes "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1"
+ and "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ shows "valuation_for_operator_variables \<Pi> \<pi> (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)
+ (Operator k (index (strips_problem.operators_of \<Pi>) op))
+ = (op \<in> set (\<pi> ! k))"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?\<tau> = "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>"
+ let ?v = "Operator k (index ?ops op)"
+ and ?Op = "{ Operator k (index ?ops op)
+ | k op. k \<in> {0..<length ?\<tau> - 1} \<and> op \<in> set ((\<Pi>)\<^sub>\<O>) }"
+ let ?l = "concat (map (\<lambda>k. map (Pair k) (\<pi> ! k)) [0..<length ?\<tau> - 1])"
+ and ?f = "\<lambda>x. Operator (fst x) (index ?ops (snd x))"
+ \<comment> \<open> show that our operator construction function is injective on
+ @{text "set (concat (map (\<lambda>k. map (Pair k) (\<pi> ! k)) [0..<length ?\<tau> - 1]))"}. \<close>
+ have k_in: "k \<in> {0..<length ?\<tau> - 1}"
+ using assms(2)
+ by fastforce
+ {
+ (* TODO refactor. *)
+ {
+ fix k k' op op'
+ assume k_op_in: "(k, op) \<in> set ?l" and k'_op'_in: "(k', op') \<in> set ?l"
+ have "Operator k (index ?ops op) = Operator k' (index ?ops op') \<longleftrightarrow> (k, op) = (k', op')"
+ proof (rule iffI)
+ assume index_op_is_index_op': "Operator k (index ?ops op) = Operator k' (index ?ops op')"
+ then have k_is_k': "k = k'"
+ by fast
+ moreover {
+ have k'_lt: "k' < length ?\<tau> - 1"
+ using k'_op'_in
+ by fastforce
+ (* TODO slow *)
+ have op_in: "op \<in> set (\<pi> ! k)"
+ using k_op_in
+ by force
+ (* TODO slow *)
+ then have op'_in: "op' \<in> set (\<pi> ! k)"
+ using k'_op'_in k_is_k'
+ by auto
+ {
+ have length_\<tau>_gt_1: "length ?\<tau> > 1"
+ using assms(2)
+ by linarith
+ have "length ?\<tau> - Suc 0 \<le> length \<pi> + 1 - Suc 0"
+ using length_trace_parallel_plan_strips_lte_length_plan_plus_one
+ using diff_le_mono
+ by blast
+ then have "length ?\<tau> - 1 \<le> length \<pi>"
+ by fastforce
+ then have "k' < length \<pi>"
+ using length_\<tau>_gt_1 k'_lt
+ by linarith
+ hence "\<pi> ! k' \<in> set \<pi>"
+ by simp
+ }
+ moreover have "op \<in> set ?ops" and "op' \<in> set ?ops"
+ using is_parallel_solution_for_problem_operator_set[OF assms(1)] op_in op'_in k_is_k'
+ calculation
+ by auto
+ ultimately have "op = op'"
+ using index_op_is_index_op'
+ by force
+ }
+ ultimately show "(k, op) = (k', op')"
+ by blast
+ qed fast
+ }
+ (* TODO slow *)
+ hence "inj_on ?f (set ?l)"
+ unfolding inj_on_def fst_def snd_def
+ by fast
+ } note inj_on_f_set_l = this
+ (* TODO refactor. *)
+ {
+ have "set ?l = \<Union> (set ` set (map (\<lambda>k. map (Pair k) (\<pi> ! k)) [0..<length ?\<tau> - 1]))"
+ using set_concat
+ by metis
+ also have "\<dots> = \<Union> (set ` (\<lambda>k. map (Pair k) (\<pi> ! k)) ` {0..<length ?\<tau> - 1})"
+ by force
+ also have "\<dots> = \<Union> ((\<lambda>k. (Pair k) ` set (\<pi> ! k)) ` {0..<length ?\<tau> - 1})"
+ by force
+ also have "\<dots> = \<Union>((\<lambda>k. { (k, op) | op. op \<in> set (\<pi> ! k) }) ` {0..<length ?\<tau> - 1})"
+ by blast
+ also have "\<dots> = \<Union>({{ (k, op) } | k op. k \<in> {0..<length ?\<tau> - 1} \<and> op \<in> set (\<pi> ! k) })"
+ by blast
+ (* TODO slow. *)
+ finally have "set ?l = \<Union>((\<lambda>(k, op). { (k, op) })
+ ` { (k, op). k \<in> {0..<length ?\<tau> - 1} \<and> op \<in> set (\<pi> ! k) })"
+ using setcompr_eq_image[of "\<lambda>(k, op). { (k, op) }" _]
+ by auto
+ } note set_l_is = this
+ {
+ have "Operator k (index ?ops op) \<in> ?Op"
+ using assms(3) k_in
+ by blast
+ (* TODO slow *)
+ hence "valuation_for_operator_variables \<Pi> \<pi> ?\<tau> ?v
+ = foldr (\<lambda>(k, op) \<A>. \<A>(Operator k (index ?ops op) := True)) ?l \<A>\<^sub>0 ?v"
+ unfolding valuation_for_operator_variables_def override_on_def Let_def
+ by auto
+ } note nb = this
+ show ?thesis
+ proof (cases "op \<in> set (\<pi> ! k)")
+ case True
+ moreover have k_op_in: "(k, op) \<in> set ?l"
+ using set_l_is k_in calculation
+ by blast
+ \<comment> \<open> There is some problem with the pattern match in the lambda in fact \isaname{nb}, sow
+ we have to do some extra work to convince Isabelle of the truth of the statement. \<close>
+ moreover {
+ let ?g = "\<lambda>_. True"
+ thm foldr_fun_upd[OF inj_on_f_set_l k_op_in]
+ have "?v = Operator (fst (k, op)) (index ?ops (snd (k, op)))"
+ by simp
+ moreover have "(\<lambda>(k, op) \<A>. \<A>(Operator k (index ?ops op) := True))
+ = (\<lambda>x \<A>. \<A>(Operator (fst x) (index ?ops (snd x)) := True))"
+ by fastforce
+ moreover have "foldr (\<lambda>x \<A>. \<A>(Operator (fst x) (index ?ops (snd x)) := ?g x))
+ ?l \<A>\<^sub>0 (Operator (fst (k, op)) (index ?ops (snd (k, op)))) = True"
+ unfolding foldr_fun_upd[OF inj_on_f_set_l k_op_in]..
+ ultimately have "valuation_for_operator_variables \<Pi> \<pi> ?\<tau> ?v = True"
+ using nb
+ by argo
+ }
+ thus ?thesis
+ using True
+ by blast
+ next
+ case False
+ {
+ have "(k, op) \<notin> set ?l"
+ using False set_l_is
+ by fast
+ moreover {
+ fix k' op'
+ assume "(k', op') \<in> set ?l"
+ and "?f (k', op') = ?f (k, op)"
+ (* TODO slow. *)
+ hence "(k', op') = (k, op)"
+ using inj_on_f_set_l assms(3)
+ by simp
+ }
+ (* TODO slow. *)
+ ultimately have "Operator k (index ?ops op) \<notin> ?f ` set ?l"
+ using image_iff
+ by force
+ } note operator_not_in_f_image_set_l = this
+ {
+ have "\<A>\<^sub>0 (Operator k (index ?ops op)) = False"
+ by simp
+ moreover have "(\<lambda>(k, op) \<A>. \<A>(Operator k (index ?ops op) := True))
+ = (\<lambda>x \<A>. \<A>(Operator (fst x) (index ?ops (snd x)) := True))"
+ by fastforce
+ ultimately have "foldr (\<lambda>(k, op) \<A>. \<A>(Operator k (index ?ops op) := True)) ?l \<A>\<^sub>0 ?v = False"
+ using foldr_fun_no_upd[OF inj_on_f_set_l operator_not_in_f_image_set_l, of "\<lambda>_. True" \<A>\<^sub>0]
+ by presburger
+ }
+ thus ?thesis
+ using nb False
+ by blast
+ qed
+qed
+
+(* TODO refactor (also used in proof of completeness for \<forall>-step 1 encoding)
+ TODO make private *)
+lemma encode_problem_parallel_complete_vi_a:
+ fixes \<Pi> :: "'a strips_problem"
+ assumes "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1"
+ shows "valuation_for_plan \<Pi> \<pi> (Operator k (index (strips_problem.operators_of \<Pi>) op))
+ = (op \<in> set (\<pi> ! k))"
+proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?t = "length \<pi>"
+ and ?\<tau> = "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>"
+ let ?\<A>\<^sub>\<pi> = "valuation_for_plan \<Pi> \<pi>"
+ and ?\<A>\<^sub>O = "valuation_for_operator_variables \<Pi> \<pi> ?\<tau>"
+ and ?Op = "{ Operator k (index ?ops op) | k op. k \<in> {0..<?t} \<and> op \<in> set ?ops }"
+ and ?V = "{ State k (index ?vs v) | k v. k \<in> {0..<?t + 1} \<and> v \<in> set ?vs }"
+ and ?v = "Operator k (index ?ops op)"
+ {
+ have "length ?\<tau> \<le> length \<pi> + 1"
+ using length_trace_parallel_plan_strips_lte_length_plan_plus_one.
+ then have "length ?\<tau> - 1 \<le> length \<pi>"
+ by simp
+ then have "k < ?t"
+ using assms
+ by fastforce
+ } note k_lt_length_\<pi> = this
+ show ?thesis
+ proof (cases "op \<in> set ((\<Pi>)\<^sub>\<O>)")
+ case True
+ {
+ have "?v \<in> ?Op"
+ using k_lt_length_\<pi> True
+ by auto
+ (* TODO slow. *)
+ hence "?\<A>\<^sub>\<pi> ?v = ?\<A>\<^sub>O ?v"
+ unfolding valuation_for_plan_def override_on_def Let_def
+ by force
+ }
+ then show ?thesis
+ using valuation_for_operator_variables_is[OF assms(1, 2) True]
+ by blast
+ next
+ (* TODO refactor (used in the lemma below as well). *)
+ case False
+ {
+ {
+ \<comment> \<open> We have @{text "\<not>index ?ops op < length ?ops"} due to the assumption that
+ @{text "\<not>op \<in> set ?ops"}. Hence @{text "\<not>k \<in> {0..<?t"} and therefore
+ @{text "?v \<notin> ?Op"}. \<close>
+ have "?Op = (\<lambda>(k, op). Operator k (index ?ops op)) ` ({0..<?t} \<times> set ?ops)"
+ by fast
+ moreover have "\<not>index ?ops op < length ?ops"
+ using False
+ by simp
+ ultimately have "?v \<notin> ?Op"
+ by fastforce
+ }
+ moreover have "?v \<notin> ?V"
+ by force
+ (* TODO slow. *)
+ ultimately have "?\<A>\<^sub>\<pi> ?v = \<A>\<^sub>0 ?v"
+ unfolding valuation_for_plan_def override_on_def
+ by metis
+ hence "\<not>?\<A>\<^sub>\<pi> ?v"
+ unfolding empty_valuation_def
+ by blast
+ }
+ moreover have "(\<pi> ! k) \<in> set \<pi>"
+ using k_lt_length_\<pi>
+ by simp
+ moreover have "op \<notin> set (\<pi> ! k)"
+ using is_parallel_solution_for_problem_operator_set[OF assms(1) calculation(2)] False
+ by blast
+ ultimately show ?thesis
+ by blast
+ qed
+qed
+
+(* TODO make private *)
+lemma encode_problem_parallel_complete_vi_b:
+ fixes \<Pi> :: "'a strips_problem"
+ assumes "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "l \<ge> length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1"
+ and "l < length \<pi>"
+ shows "\<not>valuation_for_plan \<Pi> \<pi> (Operator l (index (strips_problem.operators_of \<Pi>) op))"
+proof -
+ (* TODO prune variables *)
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?t = "length \<pi>"
+ and ?\<tau> = "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>"
+ let ?\<A>\<^sub>\<pi> = "valuation_for_plan \<Pi> \<pi>"
+ and ?\<A>\<^sub>O = "valuation_for_operator_variables \<Pi> \<pi> ?\<tau>"
+ and ?Op = "{ Operator k (index ?ops op) | k op. k \<in> {0..<?t} \<and> op \<in> set ?ops }"
+ and ?Op' = "{ Operator k (index ?ops op) | k op. k \<in> {0..<length ?\<tau> - 1} \<and> op \<in> set ?ops }"
+ and ?V = "{ State k (index ?vs v) | k v. k \<in> {0..<?t + 1} \<and> v \<in> set ?vs }"
+ and ?v = "Operator l (index ?ops op)"
+ show ?thesis
+ proof (cases "op \<in> set ((\<Pi>)\<^sub>\<O>)")
+ case True
+ {
+ {
+ have "?v \<in> ?Op"
+ using assms(3) True
+ by auto
+ (* TODO slow. *)
+ hence "?\<A>\<^sub>\<pi> ?v = ?\<A>\<^sub>O ?v"
+ unfolding valuation_for_plan_def override_on_def Let_def
+ by simp
+ }
+ moreover {
+ have "l \<notin> {0..<length ?\<tau> - 1}"
+ using assms(2)
+ by simp
+ then have "?v \<notin> ?Op'"
+ by blast
+ hence "?\<A>\<^sub>O ?v = \<A>\<^sub>0 ?v"
+ unfolding valuation_for_operator_variables_def override_on_def
+ by meson
+ }
+ ultimately have "\<not>?\<A>\<^sub>\<pi> ?v"
+ unfolding empty_valuation_def
+ by blast
+ }
+ then show ?thesis
+ by blast
+ next
+ (* TODO refactor (used in the lemma above as well). *)
+ case False
+ {
+ {
+ \<comment> \<open> We have @{text "\<not>index ?ops op < length ?ops"} due to the assumption that
+ @{text "\<not>op \<in> set ?ops"}. Hence @{text "\<not>k \<in> {0..<?t"} and therefore
+ @{text "?v \<notin> ?Op"}. \<close>
+ have "?Op = (\<lambda>(k, op). Operator k (index ?ops op)) ` ({0..<?t} \<times> set ?ops)"
+ by fast
+ moreover have "\<not>index ?ops op < length ?ops"
+ using False
+ by simp
+ ultimately have "?v \<notin> ?Op"
+ by fastforce
+ }
+ moreover have "?v \<notin> ?V"
+ by force
+ (* TODO slow. *)
+ ultimately have "?\<A>\<^sub>\<pi> ?v = \<A>\<^sub>0 ?v"
+ unfolding valuation_for_plan_def override_on_def
+ by metis
+ hence "\<not>?\<A>\<^sub>\<pi> ?v"
+ unfolding empty_valuation_def
+ by blast
+ }
+ thus ?thesis
+ by blast
+ qed
+qed
+
+\<comment> \<open> As a corollary from lemmas \isaname{encode_problem_parallel_complete_vi_a} and
+\isaname{encode_problem_parallel_complete_vi_b} we obtain the result that the constructed
+valuation \<^term>\<open>\<A> \<equiv> valuation_for_plan \<Pi> \<pi>\<close> valuates SATPlan operator variables as false if
+they are not contained in any operator set \<^term>\<open>\<pi> ! k\<close> for any time point \<^term>\<open>k < length \<pi>\<close>. \<close>
+corollary encode_problem_parallel_complete_vi_d:
+ (* TODO why is this necessary? *)
+ fixes \<Pi> :: "'variable strips_problem"
+ assumes "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "k < length \<pi>"
+ and "op \<notin> set (\<pi> ! k)"
+ shows "\<not>valuation_for_plan \<Pi> \<pi> (Operator k (index (strips_problem.operators_of \<Pi>) op))"
+ using encode_problem_parallel_complete_vi_a[OF assms(1)] assms(3)
+ encode_problem_parallel_complete_vi_b[OF assms(1) _ assms(2)] assms(3)
+ by (cases "k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1"; fastforce)
+
+(* TODO refactor List_Supplement OR rm (unused) *)
+lemma list_product_is_nil_iff: "List.product xs ys = [] \<longleftrightarrow> xs = [] \<or> ys = []"
+proof (rule iffI)
+ assume product_xs_ys_is_Nil: "List.product xs ys = []"
+ show "xs = [] \<or> ys = []"
+ proof (rule ccontr)
+ assume "\<not>(xs = [] \<or> ys = [])"
+ then have "xs \<noteq> []" and "ys \<noteq> []"
+ by simp+
+ then obtain x xs' y ys' where "xs = x # xs'" and "ys = y # ys'"
+ using list.exhaust
+ by metis
+ then have "List.product xs ys = (x, y) # map (Pair x) ys' @ List.product xs' (y # ys')"
+ by simp
+ thus False
+ using product_xs_ys_is_Nil
+ by simp
+ qed
+next
+ assume "xs = [] \<or> ys = []"
+ thus "List.product xs ys = []"
+ \<comment> \<open> First cases in the next two proof blocks follow from definition of List.product. \<close>
+ proof (rule disjE)
+ assume ys_is_Nil: "ys = []"
+ show "List.product xs ys = []"
+ proof (induction xs)
+ case (Cons x xs)
+ have "List.product (x # xs) ys = map (Pair x) ys @ List.product xs ys"
+ by simp
+ also have "\<dots> = [] @ List.product xs ys"
+ using Nil_is_map_conv ys_is_Nil
+ by blast
+ finally show ?case
+ using Cons.IH
+ by force
+ qed auto
+ qed simp
+qed
+
+\<comment> \<open> We keep the state abstract by requiring a function \<open>s\<close> which takes the index
+\<open>k\<close> and returns state. This makes the lemma cover both cases, i.e. dynamic (e.g. the \<open>k\<close>-th
+trace state) as well as static state (e.g. final trace state). \<close>
+lemma valuation_for_state_variables_is:
+ assumes "k \<in> set ks"
+ and "v \<in> set vs"
+ shows "foldr (\<lambda>(k, v) \<A>. valuation_for_state vs (s k) k v \<A>) (List.product ks vs) \<A>\<^sub>0
+ (State k (index vs v))
+ \<longleftrightarrow> (s k) v = Some True"
+proof -
+ let ?v = "State k (index vs v)"
+ and ?ps = "List.product ks vs"
+ let ?\<A> = "foldr (\<lambda>(k, v) \<A>. valuation_for_state vs (s k) k v \<A>) ?ps \<A>\<^sub>0"
+ and ?f = "\<lambda>x. State (fst x) (index vs (snd x))"
+ and ?g = "\<lambda>x. (s (fst x)) (snd x) = Some True"
+ have nb\<^sub>1: "(k, v) \<in> set ?ps"
+ using assms(1, 2) set_product
+ by simp
+ (* TODO refactor (State construction is injective on List.product ks vs). *)
+ moreover {
+ {
+ fix x y
+ assume x_in_ps: "x \<in> set ?ps" and y_in_ps: "y \<in> set ?ps"
+ and "\<not>(?f x = ?f y \<longrightarrow> x = y)"
+ then have f_x_is_f_y: "?f x = ?f y" and x_is_not_y: "x \<noteq> y"
+ by blast+
+ then obtain k' k'' v' v''
+ where x_is: "x = (k', v')"
+ and y_is: "y = (k'', v'')"
+ by fastforce
+ then consider (A) "k' \<noteq> k''"
+ | (B) "v' \<noteq> v''"
+ using x_is_not_y
+ by blast
+ hence False
+ proof (cases)
+ case A
+ then have "?f x \<noteq> ?f y"
+ using x_is y_is
+ by simp
+ thus ?thesis
+ using f_x_is_f_y
+ by argo
+ next
+ case B
+ have "v' \<in> set vs" and "v'' \<in> set vs"
+ using x_in_ps x_is y_in_ps y_is set_product
+ by blast+
+ then have "index vs v' \<noteq> index vs v''"
+ using B
+ by force
+ then have "?f x \<noteq> ?f y"
+ using x_is y_is
+ by simp
+ thus False
+ using f_x_is_f_y
+ by blast
+ qed
+ }
+ hence "inj_on ?f (set ?ps)"
+ using inj_on_def
+ by blast
+ } note nb\<^sub>2 = this
+ {
+ have "foldr (\<lambda>x. valuation_for_state vs (s (fst x)) (fst x) (snd x))
+ (List.product ks vs) \<A>\<^sub>0 (State (fst (k, v)) (index vs (snd (k, v)))) =
+ (s (fst (k, v)) (snd (k, v)) = Some True)"
+ using foldr_fun_upd[OF nb\<^sub>2 nb\<^sub>1, of ?g \<A>\<^sub>0]
+ by blast
+ moreover have "(\<lambda>x. valuation_for_state vs (s (fst x)) (fst x) (snd x))
+ = (\<lambda>(k, v). valuation_for_state vs (s k) k v)"
+ by fastforce
+ ultimately have "?\<A> (?f (k, v)) = ?g (k, v)"
+ by simp
+ }
+ thus ?thesis
+ by simp
+qed
+
+(* TODO make private *)
+lemma encode_problem_parallel_complete_vi_c:
+ fixes \<Pi> :: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)"
+ shows "valuation_for_plan \<Pi> \<pi> (State k (index (strips_problem.variables_of \<Pi>) v))
+ \<longleftrightarrow> (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! k) v = Some True"
+proof -
+ (* TODO prune variables *)
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?\<tau> = "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>"
+ let ?t = "length \<pi>"
+ and ?t' = "length ?\<tau>"
+ let ?\<A>\<^sub>\<pi> = "valuation_for_plan \<Pi> \<pi>"
+ and ?\<A>\<^sub>V = "valuation_for_state_variables \<Pi> \<pi> ?\<tau>"
+ and ?\<A>\<^sub>O = "valuation_for_state_variables \<Pi> \<pi> ?\<tau>"
+ and ?\<A>\<^sub>1 = "foldr
+ (\<lambda>(k, v) \<A>. valuation_for_state ?vs (?\<tau> ! k) k v \<A>)
+ (List.product [0..<?t'] ?vs) \<A>\<^sub>0"
+ and ?Op = "{ Operator k (index ?ops op) | k op. k \<in> {0..<?t} \<and> op \<in> set ((\<Pi>)\<^sub>\<O>) }"
+ and ?Op' = "{ Operator k (index ?ops op) | k op. k \<in> {0..<?t' - 1} \<and> op \<in> set ((\<Pi>)\<^sub>\<O>) }"
+ and ?V = "{ State k (index ?vs v) | k v. k \<in> {0..<?t + 1} \<and> v \<in> set ((\<Pi>)\<^sub>\<V>) }"
+ and ?V\<^sub>1 = "{ State k (index ?vs v) | k v. k \<in> {0..<?t'} \<and> v \<in> set ((\<Pi>)\<^sub>\<V>) }"
+ and ?V\<^sub>2 = "{ State k (index ?vs v) | k v. k \<in> {?t'..(?t + 1)} \<and> v \<in> set ((\<Pi>)\<^sub>\<V>) }"
+ and ?v = "State k (index ?vs v)"
+ have v_notin_Op: "?v \<notin> ?Op"
+ by blast
+ have k_lte_length_\<pi>_plus_one: "k < length \<pi> + 1"
+ using less_le_trans length_trace_parallel_plan_strips_lte_length_plan_plus_one assms(3)
+ by blast
+ show ?thesis
+ proof (cases "v \<in> set ((\<Pi>)\<^sub>\<V>)")
+ case True
+ {
+ (* TODO refactor. *)
+ {
+ have "?v \<in> ?V" "?v \<notin> ?Op"
+ using k_lte_length_\<pi>_plus_one True
+ by force+
+ hence "?\<A>\<^sub>\<pi> ?v = ?\<A>\<^sub>V ?v"
+ unfolding valuation_for_plan_def override_on_def Let_def
+ by simp
+ }
+ moreover {
+ have "?v \<in> ?V\<^sub>1" "?v \<notin> ?V\<^sub>2"
+ using assms(3) True
+ by fastforce+
+ hence "?\<A>\<^sub>V ?v = ?\<A>\<^sub>1 ?v"
+ unfolding valuation_for_state_variables_def override_on_def Let_def
+ by force
+ }
+ ultimately have "?\<A>\<^sub>\<pi> ?v = ?\<A>\<^sub>1 ?v"
+ by blast
+ }
+ moreover have "k \<in> set [0..<?t']"
+ using assms(3)
+ by simp
+ moreover have "v \<in> set (strips_problem.variables_of \<Pi>)"
+ using True
+ by simp
+ (* TODO slow *)
+ ultimately show ?thesis
+ using valuation_for_state_variables_is[of k "[0..<?t']"]
+ by fastforce
+ next
+ case False
+ {
+ {
+ have "\<not> index ?vs v < length ?vs"
+ using False index_less_size_conv
+ by simp
+ hence "?v \<notin> ?V"
+ by fastforce
+ }
+ then have "\<not>?\<A>\<^sub>\<pi> ?v"
+ using v_notin_Op
+ unfolding valuation_for_plan_def override_on_def empty_valuation_def Let_def
+ variables_of_def operators_of_def
+ by presburger
+ }
+ moreover have "\<not>(?\<tau> ! k) v = Some True"
+ using trace_parallel_plan_strips_none_if[of \<Pi> \<pi> k v] assms(1, 2, 3) False
+ unfolding initial_of_def
+ by force
+ ultimately show ?thesis
+ by blast
+ qed
+qed
+
+(* TODO make private *)
+lemma encode_problem_parallel_complete_vi_f:
+ fixes \<Pi> :: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "l \<ge> length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)"
+ and "l < length \<pi> + 1"
+ shows "valuation_for_plan \<Pi> \<pi> (State l (index (strips_problem.variables_of \<Pi>) v))
+ = valuation_for_plan \<Pi> \<pi>
+ (State (length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>) - 1)
+ (index (strips_problem.variables_of \<Pi>) v))"
+proof -
+ (* TODO prune variables *)
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?\<tau> = "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>"
+ let ?t = "length \<pi>"
+ and ?t' = "length ?\<tau>"
+ let ?\<tau>\<^sub>\<Omega> = "?\<tau> ! (?t' - 1)"
+ and ?\<A>\<^sub>\<pi> = "valuation_for_plan \<Pi> \<pi>"
+ and ?\<A>\<^sub>V = "valuation_for_state_variables \<Pi> \<pi> ?\<tau>"
+ and ?\<A>\<^sub>O = "valuation_for_state_variables \<Pi> \<pi> ?\<tau>"
+ let ?\<A>\<^sub>2 = "foldr
+ (\<lambda>(k, v) \<A>. valuation_for_state (strips_problem.variables_of \<Pi>) ?\<tau>\<^sub>\<Omega> k v \<A>)
+ (List.product [?t'..<length \<pi> + 2] ?vs)
+ \<A>\<^sub>0"
+ and ?Op = "{ Operator k (index ?ops op) | k op. k \<in> {0..<?t} \<and> op \<in> set ((\<Pi>)\<^sub>\<O>) }"
+ and ?Op' = "{ Operator k (index ?ops op) | k op. k \<in> {0..<?t' - 1} \<and> op \<in> set ((\<Pi>)\<^sub>\<O>) }"
+ and ?V = "{ State k (index ?vs v) | k v. k \<in> {0..<?t + 1} \<and> v \<in> set ((\<Pi>)\<^sub>\<V>) }"
+ and ?V\<^sub>1 = "{ State k (index ?vs v) | k v. k \<in> {0..<?t'} \<and> v \<in> set ((\<Pi>)\<^sub>\<V>) }"
+ and ?V\<^sub>2 = "{ State k (index ?vs v) | k v. k \<in> {?t'..(?t + 1)} \<and> v \<in> set ((\<Pi>)\<^sub>\<V>) }"
+ and ?v = "State l (index ?vs v)"
+ have v_notin_Op: "?v \<notin> ?Op"
+ by blast
+ show ?thesis
+ proof (cases "v \<in> set ((\<Pi>)\<^sub>\<V>)")
+ case True
+ {
+ (* TODO refactor. *)
+ {
+ have "?v \<in> ?V" "?v \<notin> ?Op"
+ using assms(4) True
+ by force+
+ (* TODO slow. *)
+ hence "?\<A>\<^sub>\<pi> ?v = ?\<A>\<^sub>V ?v"
+ unfolding valuation_for_plan_def override_on_def Let_def
+ by simp
+ }
+ moreover {
+ have "?v \<notin> ?V\<^sub>1" "?v \<in> ?V\<^sub>2"
+ using assms(3, 4) True
+ by force+
+ (* TODO slow. *)
+ hence "?\<A>\<^sub>V ?v = ?\<A>\<^sub>2 ?v"
+ unfolding valuation_for_state_variables_def override_on_def Let_def
+ by auto
+ }
+ ultimately have "?\<A>\<^sub>\<pi> ?v = ?\<A>\<^sub>2 ?v"
+ by blast
+ } note nb = this
+ moreover
+ {
+ have "l \<in> set [?t'..<?t + 2]"
+ using assms(3, 4)
+ by auto
+ (* TODO slow *)
+ hence "?\<A>\<^sub>2 ?v \<longleftrightarrow> ?\<tau>\<^sub>\<Omega> v = Some True"
+ using valuation_for_state_variables_is[of l "[?t'..<?t + 2]"] True nb
+ by fastforce
+ }
+ ultimately have "?\<A>\<^sub>\<pi> ?v \<longleftrightarrow> ?\<tau>\<^sub>\<Omega> v = Some True"
+ by fast
+ moreover {
+ have "0 < ?t'"
+ using trace_parallel_plan_strips_not_nil
+ by blast
+ then have "?t' - 1 < ?t'"
+ using diff_less
+ by presburger
+ }
+ ultimately show ?thesis
+ using encode_problem_parallel_complete_vi_c[of _ _ "?t' - 1", OF assms(1, 2)]
+ by blast
+ next
+ case False
+ {
+ {
+ have "\<not> index ?vs v < length ?vs"
+ using False index_less_size_conv
+ by auto
+ hence "?v \<notin> ?V"
+ by fastforce
+ }
+ then have "\<not>?\<A>\<^sub>\<pi> ?v"
+ using v_notin_Op
+ unfolding valuation_for_plan_def override_on_def empty_valuation_def Let_def
+ variables_of_def operators_of_def
+ by presburger
+ }
+ moreover {
+ have "0 < ?t'"
+ using trace_parallel_plan_strips_not_nil
+ by blast
+ then have "?t' - 1 < ?t'"
+ by simp
+ }
+ moreover have "\<not>((?\<tau> ! (?t' - 1)) v = Some True)"
+ using trace_parallel_plan_strips_none_if[of _ _ "?t' - 1" v, OF _ assms(2) calculation(2)]
+ assms(1) False
+ by simp
+ ultimately show ?thesis
+ using encode_problem_parallel_complete_vi_c[of _ _ "?t' - 1", OF assms(1, 2)]
+ by blast
+ qed
+qed
+
+
+text \<open> Let now \<^term>\<open>\<tau> \<equiv> trace_parallel_plan_strips I \<pi>\<close> be the trace of the plan \<^term>\<open>\<pi>\<close>, \<^term>\<open>t \<equiv> length \<pi>\<close>, and
+\<^term>\<open>t' \<equiv> length \<tau>\<close>.
+
+Any model of the SATPlan encoding \<^term>\<open>\<A>\<close> must satisfy the following properties:
+\footnote{Cf. \cite[Theorem 3.1, p. 1044]{DBLP:journals/ai/RintanenHN06} for the construction
+of \<^term>\<open>\<A>\<close>.}
+
+ \begin{enumerate}
+ \item for all \<^term>\<open>k\<close> and for all \<^term>\<open>op\<close> with \<^term>\<open>k < t' - 1\<close>
+
+ @{text[display, indent=4] "\<A> (Operator k (index (operators_of \<Pi>) op)) = op \<in> set (\<pi> ! k)"}
+ \item for all \<^term>\<open>l\<close> and for all \<^term>\<open>op\<close> with \<^term>\<open>l \<ge> t' - 1\<close> and
+ \<^term>\<open>l < length \<pi>\<close> we require
+
+ @{text[display, indent=4] "\<A> (Operator l (index (operators_of \<Pi>) op))"}
+ \item for all \<^term>\<open>v\<close> and for all \<^term>\<open>k\<close> with \<^term>\<open>k < t'\<close> we require
+
+ @{text[display, indent=4] "\<A> (State k (index (variables_of \<Pi>) v)) \<longrightarrow> ((\<tau> ! k) v = Some True)"}
+ \item and finally for all \<^term>\<open>v\<close> and for all \<^term>\<open>l\<close> with \<^term>\<open>l \<ge> t'\<close> and \<^term>\<open>l < t + 1\<close> we require
+
+ @{text[display, indent=4] "\<A> (State l (index (variables_of \<Pi>) v))
+ = \<A> (State (t' - 1) (index (variables_of \<Pi>) v))"}
+ \end{enumerate}
+
+Condition ``1.'' states that the model must reflect operator activation for all operators in the
+parallel operator lists \<^term>\<open>\<pi> ! k\<close> of the plan \<^term>\<open>\<pi>\<close> for each time step \<^term>\<open>k < t' - 1\<close> s.t. there is a
+successor state in the trace. Moreover ``3.''
+requires that the model is consistent with the states reached during plan execution (i.e. the
+elements \<^term>\<open>\<tau> ! k\<close> for \<^term>\<open>k < t'\<close> of the trace \<^term>\<open>\<tau>\<close>). Meaning that
+\<^term>\<open>\<A> (State k (index (strips_problem.variables_of \<Pi>) v))\<close> for the SAT plan variable of
+every state variable \<^term>\<open>v\<close> at time point \<^term>\<open>k\<close> if and only if \<^term>\<open>(\<tau> ! k) v = Some True\<close>
+for the corresponding state \<^term>\<open>\<tau> ! k\<close> at time \<^term>\<open>k\<close> (and
+\<^term>\<open>\<not>\<A> (State k (index (strips_problem.variables_of \<Pi>) v))\<close> otherwise).
+
+The second respectively fourth condition cover early plan termination by negating operator
+activation and propagating the last reached state. Note that in the state propagation constraint,
+the index is incremented by one compared to the similar constraint for operators, since operator
+activations are always followed by at least one successor state.
+Hence the last state in the trace has index
+\<^term>\<open>length (trace_parallel_plan_strips ((\<Pi>::'variable strips_problem)\<^sub>I) \<pi>) - 1\<close> and the remaining states
+take up the indexes to \<^term>\<open>length \<pi> + 1\<close>.
+
+% TODO Comments on how the partial encoding modeling follows from the construction (lemmas ...). \<close>
+
+value "stop" (* Tell document preparation to stop collecting for the last tag *)
+
+\<comment> \<open> To show completeness—i.e. every valid parallel plan \<open>\<pi>\<close> corresponds to a model
+for the SATPlan encoding \<open>\<Phi> \<Pi> (length \<pi>)\<close>—, we simply split the
+conjunction defined by the encoding into partial encodings and show that the model satisfies each
+of them. \<close>
+theorem
+ encode_problem_parallel_complete:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "is_parallel_solution_for_problem \<Pi> \<pi>"
+ shows "valuation_for_plan \<Pi> \<pi> \<Turnstile> \<Phi> \<Pi> (length \<pi>)"
+proof -
+ let ?t = "length \<pi>"
+ and ?I = "(\<Pi>)\<^sub>I"
+ and ?G = "(\<Pi>)\<^sub>G"
+ and ?\<A> = "valuation_for_plan \<Pi> \<pi>"
+ have nb: "?G \<subseteq>\<^sub>m execute_parallel_plan ?I \<pi>"
+ using assms(2)
+ unfolding is_parallel_solution_for_problem_def
+ by force
+ have "?\<A> \<Turnstile> \<Phi>\<^sub>I \<Pi>"
+ using encode_problem_parallel_complete_i[OF assms(1) nb]
+ encode_problem_parallel_complete_vi_c[OF assms(1, 2)]
+ by presburger
+ moreover have "?\<A> \<Turnstile> (\<Phi>\<^sub>G \<Pi>) ?t"
+ using encode_problem_parallel_complete_ii[OF assms(1) nb]
+ encode_problem_parallel_complete_vi_c[OF assms(1, 2)]
+ encode_problem_parallel_complete_vi_f[OF assms(1, 2)]
+ by presburger
+ moreover have "?\<A> \<Turnstile> encode_operators \<Pi> ?t"
+ using encode_problem_parallel_complete_iii[OF assms(1) nb]
+ encode_problem_parallel_complete_vi_a[OF assms(2)]
+ encode_problem_parallel_complete_vi_b[OF assms(2)]
+ encode_problem_parallel_complete_vi_c[OF assms(1, 2)]
+ by presburger
+ moreover have "?\<A> \<Turnstile> encode_all_frame_axioms \<Pi> ?t"
+ using encode_problem_parallel_complete_iv[OF assms(1, 2)]
+ encode_problem_parallel_complete_vi_a[OF assms(2)]
+ encode_problem_parallel_complete_vi_c[OF assms(1, 2)]
+ encode_problem_parallel_complete_vi_f[OF assms(1, 2)]
+ by presburger
+ ultimately show ?thesis
+ unfolding encode_problem_def SAT_Plan_Base.encode_problem_def
+ encode_initial_state_def encode_goal_state_def
+ by auto
+qed
+
+end
+
diff --git a/thys/Verified_SAT_Based_AI_Planning/SAT_Plan_Extensions.thy b/thys/Verified_SAT_Based_AI_Planning/SAT_Plan_Extensions.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/SAT_Plan_Extensions.thy
@@ -0,0 +1,798 @@
+(*
+ Author: Mohammad Abdulaziz, Fred Kurz
+*)
+theory SAT_Plan_Extensions
+ imports SAT_Plan_Base
+begin
+section "Serializable SATPlan Encodings"
+
+text \<open> A SATPlan encoding with exclusion of operator interference (see definition
+\ref{def:sat-plan-encoding-with-interference-exclusion}) can be defined by extending the basic
+SATPlan encoding with clauses
+
+ @{text[display, indent=4] "
+ \<^bold>\<not>(Atom (Operator k (index ops op\<^sub>1))
+ \<^bold>\<or> \<^bold>\<not>(Atom (Operator k (index ops op\<^sub>2))"}
+
+for all pairs of distinct interfering operators \<^term>\<open>op\<^sub>1\<close>, \<^term>\<open>op\<^sub>2\<close> for all time points
+\<^term>\<open>k < t\<close> for a given estimated plan length \<^term>\<open>t\<close>. Definitions
+\ref{isadef:interfering-operator-pair-exclusion-encoding} and
+\ref{isadef:interfering-operator-exclusion-encoding} implement the encoding for operator pairs
+resp. for all interfering operator pairs and all time points. \<close>
+
+definition encode_interfering_operator_pair_exclusion
+ :: "'variable strips_problem
+ \<Rightarrow> nat
+ \<Rightarrow> 'variable strips_operator
+ \<Rightarrow> 'variable strips_operator
+ \<Rightarrow> sat_plan_variable formula"
+ where "encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2
+ \<equiv> let ops = operators_of \<Pi> in
+ \<^bold>\<not>(Atom (Operator k (index ops op\<^sub>1)))
+ \<^bold>\<or> \<^bold>\<not>(Atom (Operator k (index ops op\<^sub>2)))"
+
+definition encode_interfering_operator_exclusion
+ :: "'variable strips_problem \<Rightarrow> nat \<Rightarrow> sat_plan_variable formula"
+ where "encode_interfering_operator_exclusion \<Pi> t \<equiv> let
+ ops = operators_of \<Pi>
+ ; interfering = filter (\<lambda>(op\<^sub>1, op\<^sub>2). index ops op\<^sub>1 \<noteq> index ops op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2) (List.product ops ops)
+ in foldr (\<^bold>\<and>) [encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2.
+ (op\<^sub>1, op\<^sub>2) \<leftarrow> interfering, k \<leftarrow> [0..<t]] (\<^bold>\<not>\<bottom>)"
+
+text \<open> A SATPlan encoding with interfering operator pair exclusion can now be defined by
+simplying adding the conjunct \<^term>\<open>encode_interfering_operator_exclusion \<Pi> t\<close> to the basic
+SATPlan encoding. \<close>
+
+\<comment> \<open> NOTE This is the quadratic size encoding for the $\forall$-step semantics as defined in @{cite
+\<open>3.2.1, p.1045\<close> "DBLP:journals/ai/RintanenHN06"}. This encoding ensures that decoded plans are
+sequentializable by simply excluding the simultaneous execution of operators with potential
+interference at any timepoint. Note that this yields a $\forall$-step plan for which parallel
+operator execution at any time step may be sequentialised in any order (due to non-interference). \<close>
+
+definition encode_problem_with_operator_interference_exclusion
+ :: "'variable strips_problem \<Rightarrow> nat \<Rightarrow> sat_plan_variable formula"
+ ("\<Phi>\<^sub>\<forall> _ _" 52)
+ where "encode_problem_with_operator_interference_exclusion \<Pi> t
+ \<equiv> encode_initial_state \<Pi>
+ \<^bold>\<and> (encode_operators \<Pi> t
+ \<^bold>\<and> (encode_all_frame_axioms \<Pi> t
+ \<^bold>\<and> (encode_interfering_operator_exclusion \<Pi> t
+ \<^bold>\<and> (encode_goal_state \<Pi> t))))"
+
+
+\<comment> \<open> Immediately proof the sublocale proposition for strips in order to gain access to definitions
+and lemmas. \<close>
+
+
+lemma cnf_of_encode_interfering_operator_pair_exclusion_is_i[simp]:
+ "cnf (encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2) = {{
+ (Operator k (index (strips_problem.operators_of \<Pi>) op\<^sub>1))\<inverse>
+ , (Operator k (index (strips_problem.operators_of \<Pi>) op\<^sub>2))\<inverse> }}"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ have "cnf (encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2)
+ = cnf (\<^bold>\<not>(Atom (Operator k (index ?ops op\<^sub>1))) \<^bold>\<or> \<^bold>\<not>(Atom (Operator k (index ?ops op\<^sub>2))))"
+ unfolding encode_interfering_operator_pair_exclusion_def
+ by metis
+ also have "\<dots> = { C \<union> D | C D.
+ C \<in> cnf (\<^bold>\<not>(Atom (Operator k (index ?ops op\<^sub>1))))
+ \<and> D \<in> cnf (\<^bold>\<not>(Atom (Operator k (index ?ops op\<^sub>2)))) }"
+ by simp
+ finally show ?thesis
+ by auto
+qed
+
+lemma cnf_of_encode_interfering_operator_exclusion_is_ii[simp]:
+ "set [encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2.
+ (op\<^sub>1, op\<^sub>2) \<leftarrow> filter (\<lambda>(op\<^sub>1, op\<^sub>2).
+ index (strips_problem.operators_of \<Pi>) op\<^sub>1 \<noteq> index (strips_problem.operators_of \<Pi>) op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2)
+ (List.product (strips_problem.operators_of \<Pi>) (strips_problem.operators_of \<Pi>))
+ , k \<leftarrow> [0..<t]]
+ = (\<Union>(op\<^sub>1, op\<^sub>2)
+ \<in> { (op\<^sub>1, op\<^sub>2) \<in> set (operators_of \<Pi>) \<times> set (operators_of \<Pi>).
+ index (strips_problem.operators_of \<Pi>) op\<^sub>1 \<noteq> index (strips_problem.operators_of \<Pi>) op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2 }.
+ (\<lambda>k. encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2) ` {0..<t})"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ let ?interfering = "filter (\<lambda>(op\<^sub>1, op\<^sub>2). index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2) (List.product ?ops ?ops)"
+ let ?fs = "[encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2.
+ (op\<^sub>1, op\<^sub>2) \<leftarrow> ?interfering, k \<leftarrow> [0..<t]]"
+ have "set ?fs = \<Union>(set
+ ` (\<lambda>(op\<^sub>1, op\<^sub>2). map (\<lambda>k. encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2) [0..<t])
+ ` (set (filter (\<lambda>(op\<^sub>1, op\<^sub>2). index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2 \<and> are_operators_interfering op\<^sub>1 op\<^sub>2)
+ (List.product ?ops ?ops))))"
+ unfolding set_concat set_map
+ by blast
+ \<comment> \<open> TODO slow. \<close>
+ also have "\<dots> = \<Union>((\<lambda>(op\<^sub>1, op\<^sub>2).
+ set (map (\<lambda>k. encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2) [0..<t]))
+ ` (set (filter (\<lambda>(op\<^sub>1, op\<^sub>2). index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2 \<and> are_operators_interfering op\<^sub>1 op\<^sub>2)
+ (List.product ?ops ?ops))))"
+ unfolding image_comp[of
+ set "\<lambda>(op\<^sub>1, op\<^sub>2). map (\<lambda>k. encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2) [0..<t]"]
+ comp_apply
+ by fast
+ also have "\<dots> = \<Union>((\<lambda>(op\<^sub>1, op\<^sub>2).
+ (\<lambda>k. encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2) ` {0..<t})
+ ` (set (filter (\<lambda>(op\<^sub>1, op\<^sub>2). index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2 \<and> are_operators_interfering op\<^sub>1 op\<^sub>2)
+ (List.product ?ops ?ops))))"
+ unfolding set_map[of _ "[0..<t]"] atLeastLessThan_upt[of 0 t]
+ by blast
+ also have "\<dots> = \<Union>((\<lambda>(op\<^sub>1, op\<^sub>2).
+ (\<lambda>k. encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2) ` {0..<t})
+ ` (Set.filter (\<lambda>(op\<^sub>1, op\<^sub>2). index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2 \<and> are_operators_interfering op\<^sub>1 op\<^sub>2)
+ (set (List.product ?ops ?ops))))"
+ unfolding set_filter[of "\<lambda>(op\<^sub>1, op\<^sub>2). are_operators_interfering op\<^sub>1 op\<^sub>2" "List.product ?ops ?ops"]
+ by force
+ \<comment> \<open> TODO slow.\<close>
+ finally show ?thesis
+ unfolding operators_of_def set_product[of ?ops ?ops]
+ by fastforce
+qed
+
+(* TODO refactor using above lemma *)
+lemma cnf_of_encode_interfering_operator_exclusion_is_iii[simp]:
+ (* TODO why is this necessary? *)
+ fixes \<Pi> :: "'variable strips_problem"
+ shows "cnf ` set [encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2.
+ (op\<^sub>1, op\<^sub>2) \<leftarrow> filter (\<lambda>(op\<^sub>1, op\<^sub>2).
+ index (strips_problem.operators_of \<Pi>) op\<^sub>1 \<noteq> index (strips_problem.operators_of \<Pi>) op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2)
+ (List.product (strips_problem.operators_of \<Pi>) (strips_problem.operators_of \<Pi>))
+ , k \<leftarrow> [0..<t]]
+ = (\<Union>(op\<^sub>1, op\<^sub>2)
+ \<in> { (op\<^sub>1, op\<^sub>2) \<in> set (strips_problem.operators_of \<Pi>) \<times> set (strips_problem.operators_of \<Pi>).
+ index (strips_problem.operators_of \<Pi>) op\<^sub>1 \<noteq> index (strips_problem.operators_of \<Pi>) op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2 }.
+ {{{ (Operator k (index (strips_problem.operators_of \<Pi>) op\<^sub>1))\<inverse>
+ , (Operator k (index (strips_problem.operators_of \<Pi>) op\<^sub>2))\<inverse> }} | k. k \<in> {0..<t}})"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ let ?interfering = "filter (\<lambda>(op\<^sub>1, op\<^sub>2). index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2) (List.product ?ops ?ops)"
+ let ?fs = "[encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2.
+ (op\<^sub>1, op\<^sub>2) \<leftarrow> ?interfering, k \<leftarrow> [0..<t]]"
+ have "cnf ` set ?fs = cnf ` (\<Union>(op\<^sub>1, op\<^sub>2) \<in> { (op\<^sub>1, op\<^sub>2).
+ (op\<^sub>1, op\<^sub>2) \<in> set (operators_of \<Pi>) \<times> set (operators_of \<Pi>) \<and> index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2 }.
+ (\<lambda>k. encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2) ` {0..<t})"
+ unfolding cnf_of_encode_interfering_operator_exclusion_is_ii
+ by blast
+ also have "\<dots> = (\<Union>(op\<^sub>1, op\<^sub>2) \<in> { (op\<^sub>1, op\<^sub>2).
+ (op\<^sub>1, op\<^sub>2) \<in> set (operators_of \<Pi>) \<times> set (operators_of \<Pi>) \<and> index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2 }.
+ (\<lambda>k. cnf (encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2)) ` {0..<t})"
+ unfolding image_Un image_comp comp_apply
+ by blast
+ also have "\<dots> = (\<Union>(op\<^sub>1, op\<^sub>2) \<in> { (op\<^sub>1, op\<^sub>2).
+ (op\<^sub>1, op\<^sub>2) \<in> set (operators_of \<Pi>) \<times> set (operators_of \<Pi>) \<and> index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2 }.
+ (\<lambda>k. {{ (Operator k (index ?ops op\<^sub>1))\<inverse>, (Operator k (index ?ops op\<^sub>2))\<inverse> }}) ` {0..<t})"
+ by simp
+ also have "\<dots> = (\<Union>(op\<^sub>1, op\<^sub>2) \<in> { (op\<^sub>1, op\<^sub>2).
+ (op\<^sub>1, op\<^sub>2) \<in> set (operators_of \<Pi>) \<times> set (operators_of \<Pi>) \<and> index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2 }.
+ (\<lambda>k. {{ (Operator k (index ?ops op\<^sub>1))\<inverse>, (Operator k (index ?ops op\<^sub>2))\<inverse> }})
+ ` { k | k. k \<in> {0..<t}})"
+ by blast
+ \<comment> \<open> TODO slow.\<close>
+ finally show ?thesis
+ unfolding operators_of_def setcompr_eq_image[of _ "\<lambda>k. k \<in> {0..<t}"]
+ by force
+qed
+
+lemma cnf_of_encode_interfering_operator_exclusion_is:
+ "cnf (encode_interfering_operator_exclusion \<Pi> t) = \<Union>(\<Union>(op\<^sub>1, op\<^sub>2)
+ \<in> { (op\<^sub>1, op\<^sub>2) \<in> set (operators_of \<Pi>) \<times> set (operators_of \<Pi>).
+ index (strips_problem.operators_of \<Pi>) op\<^sub>1 \<noteq> index (strips_problem.operators_of \<Pi>) op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2 }.
+ {{{ (Operator k (index (strips_problem.operators_of \<Pi>) op\<^sub>1))\<inverse>
+ , (Operator k (index (strips_problem.operators_of \<Pi>) op\<^sub>2))\<inverse> }} | k. k \<in> {0..<t}})"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ let ?interfering = "filter (\<lambda>(op\<^sub>1, op\<^sub>2). index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2) (List.product ?ops ?ops)"
+ let ?fs = "[encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2.
+ (op\<^sub>1, op\<^sub>2) \<leftarrow> ?interfering, k \<leftarrow> [0..<t]]"
+ have "cnf (encode_interfering_operator_exclusion \<Pi> t) = cnf (foldr (\<^bold>\<and>) ?fs (\<^bold>\<not>\<bottom>))"
+ unfolding encode_interfering_operator_exclusion_def
+ by metis
+ also have "\<dots> = \<Union>(cnf ` set ?fs)"
+ unfolding cnf_foldr_and[of ?fs]..
+ finally show ?thesis
+ unfolding cnf_of_encode_interfering_operator_exclusion_is_iii[of \<Pi> t]
+ by blast
+qed
+
+lemma cnf_of_encode_interfering_operator_exclusion_contains_clause_if:
+ (* TODO why do we need to fix the problem type? *)
+ fixes \<Pi> :: "'variable strips_problem"
+ assumes "k < t"
+ and "op\<^sub>1 \<in> set (strips_problem.operators_of \<Pi>)" and "op\<^sub>2 \<in> set (strips_problem.operators_of \<Pi>)"
+ and "index (strips_problem.operators_of \<Pi>) op\<^sub>1 \<noteq> index (strips_problem.operators_of \<Pi>) op\<^sub>2"
+ and "are_operators_interfering op\<^sub>1 op\<^sub>2"
+ shows "{ (Operator k (index (strips_problem.operators_of \<Pi>) op\<^sub>1))\<inverse>
+ , (Operator k (index (strips_problem.operators_of \<Pi>) op\<^sub>2))\<inverse>}
+ \<in> cnf (encode_interfering_operator_exclusion \<Pi> t)"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?\<Phi>\<^sub>X = "encode_interfering_operator_exclusion \<Pi> t"
+ let ?Ops = "{ (op\<^sub>1, op\<^sub>2) \<in> set (operators_of \<Pi>) \<times> set (operators_of \<Pi>).
+ index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2 \<and> are_operators_interfering op\<^sub>1 op\<^sub>2 }"
+ and ?f = "\<lambda>(op\<^sub>1, op\<^sub>2). {{{ (Operator k (index ?ops op\<^sub>1))\<inverse>, (Operator k (index ?ops op\<^sub>2))\<inverse> }}
+ | k. k \<in> {0..<t}}"
+ let ?A = "(\<Union>(op\<^sub>1, op\<^sub>2) \<in> ?Ops. ?f (op\<^sub>1, op\<^sub>2))"
+ let ?B = "\<Union>?A"
+ and ?C = "{ (Operator k (index ?ops op\<^sub>1))\<inverse>, (Operator k (index ?ops op\<^sub>2))\<inverse> }"
+ {
+ have "(op\<^sub>1, op\<^sub>2) \<in> ?Ops"
+ using assms(2, 3, 4, 5)
+ unfolding operators_of_def
+ by force
+ moreover have "{ ?C } \<in> ?f (op\<^sub>1, op\<^sub>2)"
+ using assms(1)
+ by auto
+ moreover have "{ ?C } \<in> ?A"
+ using UN_iff[of ?C _ ?Ops] calculation(1, 2)
+ by blast
+ (* TODO slow *)
+ ultimately have "\<exists>X \<in> ?A. ?C \<in> X"
+ by auto
+ }
+ (* TODO slow *)
+ thus ?thesis
+ unfolding cnf_of_encode_interfering_operator_exclusion_is
+ using Union_iff[of ?C ?A]
+ by auto
+qed
+
+lemma is_cnf_encode_interfering_operator_exclusion:
+ (* TODO why is this necessary? *)
+ fixes \<Pi> :: "'variable strips_problem"
+ shows "is_cnf (encode_interfering_operator_exclusion \<Pi> t)"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ let ?interfering = "filter (\<lambda>(op\<^sub>1, op\<^sub>2). index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2) (List.product ?ops ?ops)"
+ let ?fs = "[encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2.
+ (op\<^sub>1, op\<^sub>2) \<leftarrow> ?interfering, k \<leftarrow> [0..<t]]"
+ let ?Fs = "(\<Union>(op\<^sub>1, op\<^sub>2)
+ \<in> { (op\<^sub>1, op\<^sub>2) \<in> set (operators_of \<Pi>) \<times> set (operators_of \<Pi>). are_operators_interfering op\<^sub>1 op\<^sub>2 }.
+ (\<lambda>k. encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2) ` {0..<t})"
+ {
+ fix f
+ assume "f \<in> set ?fs"
+ then have "f \<in> ?Fs"
+ unfolding cnf_of_encode_interfering_operator_exclusion_is_ii
+ by blast
+ then obtain op\<^sub>1 op\<^sub>2
+ where "(op\<^sub>1, op\<^sub>2) \<in> set (operators_of \<Pi>) \<times> set (operators_of \<Pi>)"
+ and "are_operators_interfering op\<^sub>1 op\<^sub>2"
+ and "f \<in> (\<lambda>k. encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2) ` {0..<t}"
+ by fast
+ then obtain k where "f = encode_interfering_operator_pair_exclusion \<Pi> k op\<^sub>1 op\<^sub>2"
+ by blast
+ then have "f = \<^bold>\<not>(Atom (Operator k (index ?ops op\<^sub>1))) \<^bold>\<or> \<^bold>\<not>(Atom (Operator k (index ?ops op\<^sub>2)))"
+ unfolding encode_interfering_operator_pair_exclusion_def
+ by metis
+ hence "is_cnf f"
+ by force
+ }
+ thus ?thesis
+ unfolding encode_interfering_operator_exclusion_def
+ using is_cnf_foldr_and_if[of ?fs]
+ by meson
+qed
+
+lemma is_cnf_encode_problem_with_operator_interference_exclusion:
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "is_cnf (\<Phi>\<^sub>\<forall> \<Pi> t)"
+ using is_cnf_encode_problem is_cnf_encode_interfering_operator_exclusion assms
+ unfolding encode_problem_with_operator_interference_exclusion_def SAT_Plan_Base.encode_problem_def
+ is_cnf.simps(1)
+ by blast
+
+lemma cnf_of_encode_problem_with_operator_interference_exclusion_structure:
+ shows "cnf (\<Phi>\<^sub>I \<Pi>) \<subseteq> cnf (\<Phi>\<^sub>\<forall> \<Pi> t)"
+ and "cnf ((\<Phi>\<^sub>G \<Pi>) t) \<subseteq> cnf (\<Phi>\<^sub>\<forall> \<Pi> t)"
+ and "cnf (encode_operators \<Pi> t) \<subseteq> cnf (\<Phi>\<^sub>\<forall> \<Pi> t)"
+ and "cnf (encode_all_frame_axioms \<Pi> t) \<subseteq> cnf (\<Phi>\<^sub>\<forall> \<Pi> t)"
+ and "cnf (encode_interfering_operator_exclusion \<Pi> t) \<subseteq> cnf (\<Phi>\<^sub>\<forall> \<Pi> t)"
+ unfolding encode_problem_with_operator_interference_exclusion_def encode_problem_def SAT_Plan_Base.encode_problem_def
+ encode_initial_state_def
+ encode_goal_state_def
+ by auto+
+
+(* TODO remove (unused)? *)
+lemma encode_problem_with_operator_interference_exclusion_has_model_then_also_partial_encodings:
+ assumes "\<A> \<Turnstile> \<Phi>\<^sub>\<forall> \<Pi> t"
+ shows "\<A> \<Turnstile> SAT_Plan_Base.encode_initial_state \<Pi>"
+ and "\<A> \<Turnstile> SAT_Plan_Base.encode_operators \<Pi> t"
+ and "\<A> \<Turnstile> SAT_Plan_Base.encode_all_frame_axioms \<Pi> t"
+ and "\<A> \<Turnstile> encode_interfering_operator_exclusion \<Pi> t"
+ and "\<A> \<Turnstile> SAT_Plan_Base.encode_goal_state \<Pi> t"
+ using assms
+ unfolding encode_problem_with_operator_interference_exclusion_def encode_problem_def SAT_Plan_Base.encode_problem_def
+ by simp+
+
+
+
+text \<open> Just as for the basic SATPlan encoding we defined local context for the SATPlan encoding
+with interfering operator exclusion. We omit this here since it is basically identical to the one
+shown in the basic SATPlan theory replacing only the definitions of \isaname{encode_transitions}
+and \isaname{encode_problem}. The sublocale proof is shown below. It confirms that the new
+encoding again a CNF as required by locale \isaname{sat_encode_strips}. \<close>
+
+subsection "Soundness"
+
+
+text \<open> The Proof of soundness for the SATPlan encoding with interfering operator exclusion follows
+directly from the proof of soundness of the basic SATPlan encoding. By looking at the structure of
+the new encoding which simply extends the basic SATPlan encoding with a conjunct, any model for
+encoding with exclusion of operator interference also models the basic SATPlan encoding and the
+soundness of the new encoding therefore follows from theorem
+\ref{isathm:soundness-satplan-encoding}.
+
+Moreover, since we additionally added interfering operator exclusion clauses at every timestep, the
+decoded parallel plan cannot contain any interfering operators in any parallel operator (making it
+serializable). \<close>
+
+\<comment> \<open> NOTE We use the \<open>subseq\<close> formulation in the fourth assumption to be able to instantiate the
+induction hypothesis on the subseq \<open>ops\<close> given the induction premise
+\<open>op # ops \<in> set (subseqs (\<Phi>\<inverse> \<Pi> \<A> t ! k))\<close>. We do not use subsets in the
+assumption since we would otherwise lose the distinctness property which can be infered from
+\<open>ops \<in> set (subseqs (\<Phi>\<inverse> \<Pi> \<A> t ! k))\<close> using lemma \<open>subseqs_distinctD\<close>. \<close>
+lemma encode_problem_serializable_sound_i:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi>\<^sub>\<forall> \<Pi> t"
+ and "k < t"
+ and "ops \<in> set (subseqs ((\<Phi>\<inverse> \<Pi> \<A> t) ! k))"
+ shows "are_all_operators_non_interfering ops"
+proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?\<pi> = "\<Phi>\<inverse> \<Pi> \<A> t"
+ and ?\<Phi>\<^sub>X = "encode_interfering_operator_exclusion \<Pi> t"
+ let ?\<pi>\<^sub>k = "(\<Phi>\<inverse> \<Pi> \<A> t) ! k"
+ (* TODO refactor *)
+ {
+ fix C
+ assume C_in: "C \<in> cnf ?\<Phi>\<^sub>X"
+ have "cnf_semantics \<A> (cnf ?\<Phi>\<^sub>X)"
+ using cnf_semantics_monotonous_in_cnf_subsets_if[OF assms(2)
+ is_cnf_encode_problem_with_operator_interference_exclusion[OF assms(1)]
+ cnf_of_encode_problem_with_operator_interference_exclusion_structure(5)].
+ hence "clause_semantics \<A> C"
+ unfolding cnf_semantics_def
+ using C_in
+ by fast
+ } note nb\<^sub>1 = this
+ {
+ fix op\<^sub>1 op\<^sub>2
+ assume "op\<^sub>1 \<in> set ?\<pi>\<^sub>k" and "op\<^sub>2 \<in> set ?\<pi>\<^sub>k"
+ and index_op\<^sub>1_is_not_index_op\<^sub>2: "index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2"
+ moreover have op\<^sub>1_in: "op\<^sub>1 \<in> set ?ops" and \<A>_models_op\<^sub>1:"\<A> (Operator k (index ?ops op\<^sub>1))"
+ and op\<^sub>2_in: "op\<^sub>2 \<in> set ?ops" and \<A>_models_op\<^sub>2: "\<A> (Operator k (index ?ops op\<^sub>2))"
+ using decode_plan_step_element_then[OF assms(3)] calculation
+ unfolding decode_plan_def
+ by blast+
+ moreover {
+ let ?C = "{ (Operator k (index ?ops op\<^sub>1))\<inverse>, (Operator k (index ?ops op\<^sub>2))\<inverse> }"
+ assume "are_operators_interfering op\<^sub>1 op\<^sub>2"
+ moreover have "?C \<in> cnf ?\<Phi>\<^sub>X"
+ using cnf_of_encode_interfering_operator_exclusion_contains_clause_if[OF
+ assms(3) op\<^sub>1_in op\<^sub>2_in index_op\<^sub>1_is_not_index_op\<^sub>2] calculation
+ by blast
+ moreover have "\<not>clause_semantics \<A> ?C"
+ using \<A>_models_op\<^sub>1 \<A>_models_op\<^sub>2
+ unfolding clause_semantics_def
+ by auto
+ ultimately have False
+ using nb\<^sub>1
+ by blast
+ }
+ ultimately have "\<not>are_operators_interfering op\<^sub>1 op\<^sub>2"
+ by blast
+ } note nb\<^sub>3 = this
+ show ?thesis
+ using assms
+ proof (induction ops)
+ case (Cons op\<^sub>1 ops)
+ have "are_all_operators_non_interfering ops"
+ using Cons.IH[OF Cons.prems(1, 2, 3) Cons_in_subseqsD[OF Cons.prems(4)]]
+ by blast
+ moreover {
+ fix op\<^sub>2
+ assume op\<^sub>2_in_ops: "op\<^sub>2 \<in> set ops"
+ moreover have op\<^sub>1_in_\<pi>\<^sub>k: "op\<^sub>1 \<in> set ?\<pi>\<^sub>k" and op\<^sub>2_in_\<pi>\<^sub>k: "op\<^sub>2 \<in> set ?\<pi>\<^sub>k"
+ using element_of_subseqs_then_subset[OF Cons.prems(4)] calculation(1)
+ by auto+
+ moreover
+ {
+ have "distinct (op\<^sub>1 # ops)"
+ using subseqs_distinctD[OF Cons.prems(4)]
+ decode_plan_step_distinct[OF Cons.prems(3)]
+ unfolding decode_plan_def
+ by blast
+ moreover have "op\<^sub>1 \<in> set ?ops" and "op\<^sub>2 \<in> set ?ops"
+ using decode_plan_step_element_then(1)[OF Cons.prems(3)] op\<^sub>1_in_\<pi>\<^sub>k op\<^sub>2_in_\<pi>\<^sub>k
+ unfolding decode_plan_def
+ by force+
+ moreover have "op\<^sub>1 \<noteq> op\<^sub>2"
+ using op\<^sub>2_in_ops calculation(1)
+ by fastforce
+ ultimately have "index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2"
+ using index_eq_index_conv
+ by auto
+ }
+ ultimately have "\<not>are_operators_interfering op\<^sub>1 op\<^sub>2"
+ using nb\<^sub>3
+ by blast
+ }
+ ultimately show ?case
+ using list_all_iff
+ by auto
+ qed simp
+qed
+
+theorem encode_problem_serializable_sound:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi>\<^sub>\<forall> \<Pi> t"
+ shows "is_parallel_solution_for_problem \<Pi> (\<Phi>\<inverse> \<Pi> \<A> t)"
+ and "\<forall>k < length (\<Phi>\<inverse> \<Pi> \<A> t). are_all_operators_non_interfering ((\<Phi>\<inverse> \<Pi> \<A> t) ! k)"
+proof -
+ {
+ have "\<A> \<Turnstile> SAT_Plan_Base.encode_initial_state \<Pi>"
+ and "\<A> \<Turnstile> SAT_Plan_Base.encode_operators \<Pi> t"
+ and "\<A> \<Turnstile> SAT_Plan_Base.encode_all_frame_axioms \<Pi> t"
+ and "\<A> \<Turnstile> SAT_Plan_Base.encode_goal_state \<Pi> t"
+ using assms(2)
+ unfolding encode_problem_with_operator_interference_exclusion_def
+ by simp+
+ then have "\<A> \<Turnstile> SAT_Plan_Base.encode_problem \<Pi> t"
+ unfolding SAT_Plan_Base.encode_problem_def
+ by simp
+ }
+ thus "is_parallel_solution_for_problem \<Pi> (\<Phi>\<inverse> \<Pi> \<A> t)"
+ using encode_problem_parallel_sound assms(1, 2)
+ unfolding decode_plan_def
+ by blast
+next
+ let ?\<pi> = "\<Phi>\<inverse> \<Pi> \<A> t"
+ {
+ fix k
+ assume "k < t"
+ moreover have "?\<pi> ! k \<in> set (subseqs (?\<pi> ! k))"
+ using subseqs_refl
+ by blast
+ ultimately have "are_all_operators_non_interfering (?\<pi> ! k)"
+ using encode_problem_serializable_sound_i[OF assms]
+ unfolding SAT_Plan_Base.decode_plan_def decode_plan_def
+ by blast
+ }
+ moreover have "length ?\<pi> = t"
+ unfolding SAT_Plan_Base.decode_plan_def decode_plan_def
+ by simp
+ ultimately show "\<forall>k < length ?\<pi>. are_all_operators_non_interfering (?\<pi> ! k)"
+ by simp
+qed
+
+
+subsection "Completeness"
+
+
+lemma encode_problem_with_operator_interference_exclusion_complete_i:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "\<forall>k < length \<pi>. are_all_operators_non_interfering (\<pi> ! k)"
+ shows "valuation_for_plan \<Pi> \<pi> \<Turnstile> encode_interfering_operator_exclusion \<Pi> (length \<pi>)"
+proof -
+ let ?\<A> = "valuation_for_plan \<Pi> \<pi>"
+ and ?\<Phi>\<^sub>X = "encode_interfering_operator_exclusion \<Pi> (length \<pi>)"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?t = "length \<pi>"
+ let ?\<tau> = "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>"
+ let ?Ops = "{ (op\<^sub>1, op\<^sub>2). (op\<^sub>1, op\<^sub>2) \<in> set (operators_of \<Pi>) \<times> set (operators_of \<Pi>)
+ \<and> index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2
+ \<and> are_operators_interfering op\<^sub>1 op\<^sub>2 }"
+ and ?f = "\<lambda>(op\<^sub>1, op\<^sub>2). {{{ (Operator k (index ?ops op\<^sub>1))\<inverse>, (Operator k (index ?ops op\<^sub>2))\<inverse> }}
+ | k. k \<in> {0..<length \<pi>} }"
+ let ?A = "\<Union>(?f ` ?Ops)"
+ let ?B = "\<Union>?A"
+ have nb\<^sub>1: "\<forall>ops \<in> set \<pi>. \<forall>op \<in> set ops. op \<in> set (operators_of \<Pi>)"
+ using is_parallel_solution_for_problem_operator_set[OF assms(2)]
+ unfolding operators_of_def
+ by blast
+ (* TODO refactor (characterization of \<A>) *)
+ {
+ fix k op
+ assume "k < length \<pi>" and "op \<in> set (\<pi> ! k)"
+ hence "lit_semantics ?\<A> ((Operator k (index ?ops op))\<^sup>+) = (k < length ?\<tau> - 1)"
+ using encode_problem_parallel_complete_vi_a[OF assms(2)]
+ encode_problem_parallel_complete_vi_b[OF assms(2)] initial_of_def
+ by(cases "k < length ?\<tau> - 1"; simp)
+ } note nb\<^sub>2 = this
+ {
+ fix k op\<^sub>1 op\<^sub>2
+ assume "k < length \<pi>"
+ and "op\<^sub>1 \<in> set (\<pi> ! k)"
+ and "index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2"
+ and "are_operators_interfering op\<^sub>1 op\<^sub>2"
+ moreover have "are_all_operators_non_interfering (\<pi> ! k)"
+ using assms(3) calculation(1)
+ by blast
+ moreover have "op\<^sub>1 \<noteq> op\<^sub>2"
+ using calculation(3)
+ by blast
+ ultimately have "op\<^sub>2 \<notin> set (\<pi> ! k)"
+ using are_all_operators_non_interfering_set_contains_no_distinct_interfering_operator_pairs
+ assms(3)
+ by blast
+ } note nb\<^sub>3 = this
+ {
+ fix C
+ assume "C \<in> cnf ?\<Phi>\<^sub>X"
+ then have "C \<in> ?B"
+ using cnf_of_encode_interfering_operator_exclusion_is[of \<Pi> "length \<pi>"]
+ by argo
+ then obtain C' where "C' \<in> ?A" and C_in: "C \<in> C'"
+ using Union_iff[of C ?A]
+ by meson
+ then obtain op\<^sub>1 op\<^sub>2 where "(op\<^sub>1, op\<^sub>2) \<in> set (operators_of \<Pi>) \<times> set (operators_of \<Pi>)"
+ and index_op\<^sub>1_is_not_index_op\<^sub>2: "index ?ops op\<^sub>1 \<noteq> index ?ops op\<^sub>2"
+ and are_operators_interfering_op\<^sub>1_op\<^sub>2: "are_operators_interfering op\<^sub>1 op\<^sub>2"
+ and C'_in: "C' \<in> {{{(Operator k (index ?ops op\<^sub>1))\<inverse>, (Operator k (index ?ops op\<^sub>2))\<inverse>}}
+ | k. k \<in> {0..<length \<pi>}}"
+ using UN_iff[of C' ?f ?Ops]
+ by blast
+ then obtain k where "k \<in> {0..<length \<pi>}"
+ and C_is: "C = { (Operator k (index ?ops op\<^sub>1))\<inverse>, (Operator k (index ?ops op\<^sub>2))\<inverse> }"
+ using C_in C'_in
+ by blast
+ then have k_lt_length_\<pi>: "k < length \<pi>"
+ by simp
+ consider (A) "op\<^sub>1 \<in> set (\<pi> ! k)"
+ | (B) "op\<^sub>2 \<in> set (\<pi> ! k)"
+ | (C) "\<not>op\<^sub>1 \<in> set (\<pi> ! k) \<or> \<not>op\<^sub>2 \<in> set (\<pi> ! k)"
+ by linarith
+ hence "clause_semantics ?\<A> C"
+ proof (cases)
+ case A
+ moreover have "op\<^sub>2 \<notin> set (\<pi> ! k)"
+ using nb\<^sub>3 k_lt_length_\<pi> calculation index_op\<^sub>1_is_not_index_op\<^sub>2 are_operators_interfering_op\<^sub>1_op\<^sub>2
+ by blast
+ moreover have "\<not>?\<A> (Operator k (index ?ops op\<^sub>2))"
+ using encode_problem_parallel_complete_vi_d[OF assms(2) k_lt_length_\<pi>]
+ calculation(2)
+ by blast
+ ultimately show ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by force
+ next
+ case B
+ moreover have "op\<^sub>1 \<notin> set (\<pi> ! k)"
+ using nb\<^sub>3 k_lt_length_\<pi> calculation index_op\<^sub>1_is_not_index_op\<^sub>2 are_operators_interfering_op\<^sub>1_op\<^sub>2
+ by blast
+ moreover have "\<not>?\<A> (Operator k (index ?ops op\<^sub>1))"
+ using encode_problem_parallel_complete_vi_d[OF assms(2) k_lt_length_\<pi>]
+ calculation(2)
+ by blast
+ ultimately show ?thesis
+ using C_is
+ unfolding clause_semantics_def
+ by force
+ next
+ case C
+ then show ?thesis
+ proof (rule disjE)
+ assume "op\<^sub>1 \<notin> set (\<pi> ! k)"
+ then have "\<not>?\<A> (Operator k (index ?ops op\<^sub>1))"
+ using encode_problem_parallel_complete_vi_d[OF assms(2) k_lt_length_\<pi>]
+ by blast
+ thus "clause_semantics (valuation_for_plan \<Pi> \<pi>) C"
+ using C_is
+ unfolding clause_semantics_def
+ by force
+ next
+ assume "op\<^sub>2 \<notin> set (\<pi> ! k)"
+ then have "\<not>?\<A> (Operator k (index ?ops op\<^sub>2))"
+ using encode_problem_parallel_complete_vi_d[OF assms(2) k_lt_length_\<pi>]
+ by blast
+ thus "clause_semantics (valuation_for_plan \<Pi> \<pi>) C"
+ using C_is
+ unfolding clause_semantics_def
+ by force
+ qed
+ qed
+ }
+ then have "cnf_semantics ?\<A> (cnf ?\<Phi>\<^sub>X)"
+ unfolding cnf_semantics_def..
+ thus ?thesis
+ using cnf_semantics[OF is_nnf_cnf[OF is_cnf_encode_interfering_operator_exclusion]]
+ by fast
+qed
+
+text \<open> Similar to the soundness proof, we may reuse the previously established
+facts about the valuation for the completeness proof of the basic SATPlan encoding
+(\ref{isathm:completeness-satplan-encoding}).
+To make it clearer why this is true we have a look at the form of the clauses for interfering operator
+pairs \<^term>\<open>op\<^sub>1\<close> and \<^term>\<open>op\<^sub>2\<close> at the same time index \<^term>\<open>k\<close> which have the form shown below:
+ @{text[display, indent=4] "{ (Operator k (index ops op\<^sub>1))\<inverse>, (Operator k (index ops op\<^sub>2))\<inverse> }"}
+where \<^term>\<open>ops \<equiv> strips_problem.operators_of \<Pi>\<close>.
+Now, consider an operator \<^term>\<open>op\<^sub>1\<close> that is contained in the \<^term>\<open>k\<close>-th plan step \<^term>\<open>\<pi> ! k\<close>
+(symmetrically for \<^term>\<open>op\<^sub>2\<close>). Since \<^term>\<open>\<pi>\<close> is a serializable solution, there can be no
+interference between \<^term>\<open>op\<^sub>1\<close> and \<^term>\<open>op\<^sub>2\<close> at time \<^term>\<open>k\<close>. Hence \<^term>\<open>op\<^sub>2\<close> cannot be in \<^term>\<open>\<pi> ! k\<close>
+This entails that for \<^term>\<open>\<A> \<equiv> valuation_for_plan \<Pi> \<pi>\<close> it holds that
+ @{text[display, indent=4] "\<A> \<Turnstile> \<^bold>\<not> Atom (Operator k (index ops op\<^sub>2))"}
+and \<^term>\<open>\<A>\<close> therefore models the clause.
+
+Furthermore, if neither is present, than \<^term>\<open>\<A>\<close> will evaluate both atoms to false and the clause
+therefore evaluates to true as well.
+
+It follows from this that each clause in the extension of the SATPlan encoding evaluates to true
+for \<^term>\<open>\<A>\<close>. The other parts of the encoding evaluate to true as per the completeness of the
+basic SATPlan encoding (theorem \ref{isathm:completeness-satplan-encoding}).\<close>
+
+theorem encode_problem_serializable_complete:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "\<forall>k < length \<pi>. are_all_operators_non_interfering (\<pi> ! k)"
+ shows "valuation_for_plan \<Pi> \<pi> \<Turnstile> \<Phi>\<^sub>\<forall> \<Pi> (length \<pi>)"
+proof -
+ let ?\<A> = "valuation_for_plan \<Pi> \<pi>"
+ and ?\<Phi>\<^sub>X = "encode_interfering_operator_exclusion \<Pi> (length \<pi>)"
+ have "?\<A> \<Turnstile> SAT_Plan_Base.encode_problem \<Pi> (length \<pi>)"
+ using assms(1, 2) encode_problem_parallel_complete
+ by auto
+ moreover have "?\<A> \<Turnstile> ?\<Phi>\<^sub>X"
+ using encode_problem_with_operator_interference_exclusion_complete_i[OF assms].
+ ultimately show ?thesis
+ unfolding encode_problem_with_operator_interference_exclusion_def encode_problem_def
+ SAT_Plan_Base.encode_problem_def
+ by force
+qed
+
+value "stop" (* Tell document preparation to stop collecting for the last tag *)
+
+(* TODO rename encode_problem_with_operator_interference_exclusion_decoded_plan_is_serializable_i *)
+lemma encode_problem_forall_step_decoded_plan_is_serializable_i:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi>\<^sub>\<forall> \<Pi> t"
+ shows "(\<Pi>)\<^sub>G \<subseteq>\<^sub>m execute_serial_plan ((\<Pi>)\<^sub>I) (concat (\<Phi>\<inverse> \<Pi> \<A> t))"
+proof -
+ let ?G = "(\<Pi>)\<^sub>G"
+ and ?I = "(\<Pi>)\<^sub>I"
+ and ?\<pi> = "\<Phi>\<inverse> \<Pi> \<A> t"
+ let ?\<pi>' = "concat (\<Phi>\<inverse> \<Pi> \<A> t)"
+ and ?\<tau> = "trace_parallel_plan_strips ?I ?\<pi>"
+ and ?\<sigma> = "map (decode_state_at \<Pi> \<A>) [0..<Suc (length ?\<pi>)]"
+ {
+ fix k
+ assume k_lt_length_\<pi>: "k < length ?\<pi>"
+ moreover have "\<A> \<Turnstile> SAT_Plan_Base.encode_problem \<Pi> t"
+ using assms(2)
+ unfolding encode_problem_with_operator_interference_exclusion_def
+ encode_problem_def SAT_Plan_Base.encode_problem_def
+ by simp
+ moreover have "length ?\<sigma> = length ?\<tau>"
+ using encode_problem_parallel_correct_vii assms(1) calculation
+ unfolding decode_state_at_def decode_plan_def initial_of_def
+ by fast
+ ultimately have "k < length ?\<tau> - 1" and "k < t"
+ unfolding decode_plan_def SAT_Plan_Base.decode_plan_def
+ by force+
+ } note nb = this
+ {
+ have "?G \<subseteq>\<^sub>m execute_parallel_plan ?I ?\<pi>"
+ using encode_problem_serializable_sound assms
+ unfolding is_parallel_solution_for_problem_def decode_plan_def
+ goal_of_def initial_of_def
+ by blast
+ hence "?G \<subseteq>\<^sub>m last (trace_parallel_plan_strips ?I ?\<pi>)"
+ using execute_parallel_plan_reaches_goal_iff_goal_is_last_element_of_trace
+ by fast
+ }
+ moreover {
+ fix k
+ assume k_lt_length_\<pi>: "k < length ?\<pi>"
+ moreover have "k < length ?\<tau> - 1" and "k < t"
+ using nb calculation
+ by blast+
+ moreover have "are_all_operators_applicable (?\<tau> ! k) (?\<pi> ! k)"
+ and "are_all_operator_effects_consistent (?\<pi> ! k)"
+ using trace_parallel_plan_strips_operator_preconditions calculation(2)
+ by blast+
+ moreover have "are_all_operators_non_interfering (?\<pi> ! k)"
+ using encode_problem_serializable_sound(2)[OF assms(1, 2)] k_lt_length_\<pi>
+ by blast
+ ultimately have "are_all_operators_applicable (?\<tau> ! k) (?\<pi> ! k)"
+ and "are_all_operator_effects_consistent (?\<pi> ! k)"
+ and "are_all_operators_non_interfering (?\<pi> ! k)"
+ by blast+
+ }
+ ultimately show ?thesis
+ using execute_parallel_plan_is_execute_sequential_plan_if assms(1)
+ by metis
+qed
+
+(* TODO rename encode_problem_with_operator_interference_exclusion_decoded_plan_is_serializable_ii *)
+lemma encode_problem_forall_step_decoded_plan_is_serializable_ii:
+ (* TODO why is the fixed type necessary? *)
+ fixes \<Pi> :: "'variable strips_problem"
+ shows "list_all (\<lambda>op. ListMem op (strips_problem.operators_of \<Pi>))
+ (concat (\<Phi>\<inverse> \<Pi> \<A> t))"
+proof -
+ let ?\<pi> = "\<Phi>\<inverse> \<Pi> \<A> t"
+ let ?\<pi>' = "concat ?\<pi>"
+ (* TODO refactor *)
+ {
+ have "set ?\<pi>' = \<Union>(set ` (\<Union>k < t. { decode_plan' \<Pi> \<A> k }))"
+ unfolding decode_plan_def decode_plan_set_is set_concat
+ by auto
+ also have "\<dots> = \<Union>(\<Union>k < t. { set (decode_plan' \<Pi> \<A> k) })"
+ by blast
+ finally have "set ?\<pi>' = (\<Union>k < t. set (decode_plan' \<Pi> \<A> k))"
+ by blast
+ } note nb = this
+ {
+ fix op
+ assume "op \<in> set ?\<pi>'"
+ then obtain k where "k < t" and "op \<in> set (decode_plan' \<Pi> \<A> k)"
+ using nb
+ by blast
+ moreover have "op \<in> set (decode_plan \<Pi> \<A> t ! k)"
+ using calculation
+ unfolding decode_plan_def SAT_Plan_Base.decode_plan_def
+ by simp
+ ultimately have "op \<in> set (operators_of \<Pi>)"
+ using decode_plan_step_element_then(1)
+ unfolding operators_of_def decode_plan_def
+ by blast
+ }
+ thus ?thesis
+ unfolding list_all_iff ListMem_iff operators_of_def
+ by blast
+qed
+
+text \<open> Given the soundness and completeness of the SATPlan encoding with interfering operator
+exclusion \<^term>\<open>\<Phi>\<^sub>\<forall> \<Pi> t\<close>, we can
+now conclude this part with showing that for a parallel plan \<^term>\<open>\<pi> \<equiv> \<Phi>\<inverse> \<Pi> \<A> t\<close>
+that was decoded from a model \<^term>\<open>\<A>\<close> of \<^term>\<open>\<Phi>\<^sub>\<forall> \<Pi> t\<close> the serialized plan
+\<^term>\<open>\<pi>' \<equiv> concat \<pi>\<close> is a serial solution for \<^term>\<open>\<Pi>\<close>. To this end, we have to show that
+\begin{itemize}
+ \item the state reached by serial execution of \<^term>\<open>\<pi>'\<close> subsumes \<^term>\<open>G\<close>, and
+ \item all operators in \<^term>\<open>\<pi>'\<close> are operators contained in \<^term>\<open>\<O>\<close>.
+\end{itemize}
+While the proof of the latter step is rather straight forward, the proof for the
+former requires a bit more work. We use the previously established theorem on serial and parallel
+STRIPS equivalence (theorem \ref{isathm:equivalence-parallel-serial-strips-plans}) to show the
+serializability of \<^term>\<open>\<pi>\<close> and therefore have to show that \<^term>\<open>G\<close> is subsumed by the last state
+of the trace of \<^term>\<open>\<pi>'\<close>
+ @{text[display, indent=4] "G \<subseteq>\<^sub>m last (trace_sequential_plan_strips I \<pi>')"}
+and moreover that at every step of the parallel plan execution, the parallel operator execution
+condition as well as non interference are met
+ @{text[display, indent=4] "\<forall>k < length \<pi>. are_all_operators_non_interfering (\<pi> ! k)"}.
+\footnote{These propositions are shown in lemmas \texttt{encode\_problem\_forall\_step\_decoded\_plan\_is\_serializable\_ii} and
+\texttt{encode\_problem\_forall\_step\_decoded\_plan\_is\_serializable\_i} which have been omitted for
+brevity.}
+Note that the parallel operator execution condition is implicit in the existence of the parallel
+trace for \<^term>\<open>\<pi>\<close> with
+ @{text[display, indent=4] "G \<subseteq>\<^sub>m last (trace_parallel_plan_strips I \<pi>)"}
+warranted by the soundness of \<^term>\<open>\<Phi>\<^sub>\<forall> \<Pi> t\<close>. \<close>
+
+(* TODO rename encode_problem_with_operator_interference_exclusion_decoded_plan_is_serializable *)
+theorem serializable_encoding_decoded_plan_is_serializable:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<A> \<Turnstile> \<Phi>\<^sub>\<forall> \<Pi> t"
+ shows "is_serial_solution_for_problem \<Pi> (concat (\<Phi>\<inverse> \<Pi> \<A> t))"
+ using encode_problem_forall_step_decoded_plan_is_serializable_i[OF assms]
+ encode_problem_forall_step_decoded_plan_is_serializable_ii
+ unfolding is_serial_solution_for_problem_def goal_of_def
+ initial_of_def decode_plan_def
+ by blast
+
+end
diff --git a/thys/Verified_SAT_Based_AI_Planning/SAT_Solve_SAS_Plus.thy b/thys/Verified_SAT_Based_AI_Planning/SAT_Solve_SAS_Plus.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/SAT_Solve_SAS_Plus.thy
@@ -0,0 +1,181 @@
+(*
+ Author: Mohammad Abdulaziz, Fred Kurz
+*)
+theory SAT_Solve_SAS_Plus
+ imports "SAS_Plus_STRIPS"
+ "SAT_Plan_Extensions"
+begin
+section "SAT-Solving of SAS+ Problems"
+
+
+lemma sas_plus_problem_has_serial_solution_iff_i:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "\<A> \<Turnstile> \<Phi>\<^sub>\<forall> (\<phi> \<Psi>) t"
+ shows "is_serial_solution_for_problem \<Psi> [\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> concat (\<Phi>\<inverse> (\<phi> \<Psi>) \<A> t)]"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ and ?\<pi>' = "concat (\<Phi>\<inverse> (\<phi> \<Psi>) \<A> t)"
+ let ?\<psi> = "[\<phi>\<^sub>O\<inverse> \<Psi> op. op \<leftarrow> ?\<pi>']"
+ {
+ have "is_valid_problem_strips ?\<Pi>"
+ using is_valid_problem_sas_plus_then_strips_transformation_too[OF assms(1)].
+ moreover have "STRIPS_Semantics.is_serial_solution_for_problem ?\<Pi> ?\<pi>'"
+ using calculation serializable_encoding_decoded_plan_is_serializable[OF
+ _ assms(2)]
+ unfolding decode_plan_def
+ by simp
+ ultimately have "SAS_Plus_Semantics.is_serial_solution_for_problem \<Psi> ?\<psi>"
+ using assms(1) serial_strips_equivalent_to_serial_sas_plus
+ by blast
+ }
+ thus ?thesis
+ using serial_strips_equivalent_to_serial_sas_plus[OF assms(1)]
+ by blast
+qed
+
+lemma sas_plus_problem_has_serial_solution_iff_ii:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "is_serial_solution_for_problem \<Psi> \<psi>"
+ and "h = length \<psi>"
+ shows "\<exists>\<A>. (\<A> \<Turnstile> \<Phi>\<^sub>\<forall> (\<phi> \<Psi>) h)"
+proof -
+ let ?\<Pi> = "\<phi> \<Psi>"
+ and ?\<pi> = "\<phi>\<^sub>P \<Psi> (embed \<psi>)"
+ let ?\<A> = "valuation_for_plan ?\<Pi> ?\<pi>"
+ let ?t = "length \<psi>"
+ (* TODO refactor *)
+ have nb: "length \<psi> = length ?\<pi>"
+ unfolding SAS_Plus_STRIPS.sas_plus_parallel_plan_to_strips_parallel_plan_def
+ sasp_op_to_strips_def
+ sas_plus_parallel_plan_to_strips_parallel_plan_def
+ by (induction \<psi>; auto)
+ have "is_valid_problem_strips ?\<Pi>"
+ using assms(1) is_valid_problem_sas_plus_then_strips_transformation_too
+ by blast
+ moreover have "STRIPS_Semantics.is_parallel_solution_for_problem ?\<Pi> ?\<pi>"
+ using execute_serial_plan_sas_plus_is_execute_parallel_plan_sas_plus[OF assms(1,2)]
+ strips_equivalent_to_sas_plus[OF assms(1)]
+ by blast
+ moreover {
+ fix k
+ assume "k < length ?\<pi>"
+ moreover obtain ops' where "ops' = ?\<pi> ! k"
+ by simp
+ moreover have "ops' \<in> set ?\<pi>"
+ using calculation nth_mem
+ by blast
+ moreover have "?\<pi> = [[\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]. ops \<leftarrow> embed \<psi>]"
+ unfolding SAS_Plus_STRIPS.sas_plus_parallel_plan_to_strips_parallel_plan_def
+ sasp_op_to_strips_def
+ sas_plus_parallel_plan_to_strips_parallel_plan_def
+ ..
+ moreover obtain ops
+ where "ops' = [\<phi>\<^sub>O \<Psi> op. op \<leftarrow> ops]"
+ and "ops \<in> set (embed \<psi>)"
+ using calculation(3, 4)
+ by auto
+ moreover have "ops \<in> { [op] | op. op \<in> set \<psi> }"
+ using calculation(6) set_of_embed_is
+ by blast
+ moreover obtain op
+ where "ops = [op]" and "op \<in> set \<psi>"
+ using calculation(7)
+ by blast
+ ultimately have "are_all_operators_non_interfering (?\<pi> ! k)"
+ by fastforce
+ }
+ ultimately show ?thesis
+ using encode_problem_serializable_complete nb
+ by (auto simp: assms(3))
+qed
+
+text \<open> To wrap-up our documentation of the Isabelle formalization, we take a look at the central
+theorem which combines all the previous theorem to show that SAS+ problems \<^term>\<open>\<Psi>\<close> can be solved
+using the planning as satisfiability framework.
+
+A solution \<^term>\<open>\<psi>\<close> for the SAS+ problem \<^term>\<open>\<Psi>\<close> exists if and only if a model \<^term>\<open>\<A>\<close> and a
+hypothesized plan length \<^term>\<open>t\<close> exist s.t.
+@{text[display,indent=4] "\<A> \<Turnstile> \<Phi>\<^sub>\<forall> (\<phi> \<Psi>) t"}
+for the serializable SATPlan encoding of the corresponding STRIPS problem \<^term>\<open>\<Phi>\<^sub>\<forall> (\<phi> \<Psi>) t\<close> exist. \<close>
+theorem sas_plus_problem_has_serial_solution_iff:
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ shows "(\<exists>\<psi>. is_serial_solution_for_problem \<Psi> \<psi>) \<longleftrightarrow> (\<exists>\<A> t. \<A> \<Turnstile> \<Phi>\<^sub>\<forall> (\<phi> \<Psi>) t)"
+ using sas_plus_problem_has_serial_solution_iff_i[OF assms]
+ sas_plus_problem_has_serial_solution_iff_ii[OF assms]
+ by blast
+
+
+section \<open>Adding Noop actions to the SAS+ problem\<close>
+
+text \<open>Here we add noop actions to the SAS+ problem to enable the SAT formula to be satisfiable if
+ there are plans that are shorter than the given horizons.\<close>
+
+definition "empty_sasp_action \<equiv> \<lparr>SAS_Plus_Representation.sas_plus_operator.precondition_of = [],
+ SAS_Plus_Representation.sas_plus_operator.effect_of = []\<rparr>"
+
+lemma sasp_exec_noops: "execute_serial_plan_sas_plus s (replicate n empty_sasp_action) = s"
+ by (induction n arbitrary: )
+ (auto simp: empty_sasp_action_def STRIPS_Representation.is_operator_applicable_in_def
+ execute_operator_def)
+
+definition
+ "prob_with_noop \<Pi> \<equiv>
+ \<lparr>SAS_Plus_Representation.sas_plus_problem.variables_of = SAS_Plus_Representation.sas_plus_problem.variables_of \<Pi>,
+ SAS_Plus_Representation.sas_plus_problem.operators_of = empty_sasp_action # SAS_Plus_Representation.sas_plus_problem.operators_of \<Pi>,
+ SAS_Plus_Representation.sas_plus_problem.initial_of = SAS_Plus_Representation.sas_plus_problem.initial_of \<Pi>,
+ SAS_Plus_Representation.sas_plus_problem.goal_of = SAS_Plus_Representation.sas_plus_problem.goal_of \<Pi>,
+ SAS_Plus_Representation.sas_plus_problem.range_of = SAS_Plus_Representation.sas_plus_problem.range_of \<Pi>\<rparr>"
+
+lemma sasp_noops_in_noop_problem: "set (replicate n empty_sasp_action) \<subseteq> set (SAS_Plus_Representation.sas_plus_problem.operators_of (prob_with_noop \<Pi>))"
+ by (induction n) (auto simp: prob_with_noop_def)
+
+lemma noops_complete:
+ "SAS_Plus_Semantics.is_serial_solution_for_problem \<Psi> \<pi> \<Longrightarrow>
+ SAS_Plus_Semantics.is_serial_solution_for_problem (prob_with_noop \<Psi>) ((replicate n empty_sasp_action) @ \<pi>)"
+ by(induction n)
+ (auto simp: SAS_Plus_Semantics.is_serial_solution_for_problem_def insert list.pred_set
+ sasp_exec_noops prob_with_noop_def Let_def empty_sasp_action_def elem)
+
+definition "rem_noops \<equiv> filter (\<lambda>op. op \<noteq> empty_sasp_action)"
+
+lemma sasp_filter_empty_action:
+ "execute_serial_plan_sas_plus s (rem_noops \<pi>s) = execute_serial_plan_sas_plus s \<pi>s"
+ by (induction \<pi>s arbitrary: s)
+ (auto simp: empty_sasp_action_def rem_noops_def)
+
+lemma noops_sound:
+ "SAS_Plus_Semantics.is_serial_solution_for_problem (prob_with_noop \<Psi>) \<pi>s \<Longrightarrow>
+ SAS_Plus_Semantics.is_serial_solution_for_problem \<Psi> (rem_noops \<pi>s)"
+ by(induction \<pi>s)
+ (fastforce simp: SAS_Plus_Semantics.is_serial_solution_for_problem_def insert list.pred_set
+ prob_with_noop_def ListMem_iff rem_noops_def
+ sasp_filter_empty_action[unfolded empty_sasp_action_def rem_noops_def]
+ empty_sasp_action_def)+
+
+lemma noops_valid: "is_valid_problem_sas_plus \<Psi> \<Longrightarrow> is_valid_problem_sas_plus (prob_with_noop \<Psi>)"
+ by (auto simp: is_valid_problem_sas_plus_def prob_with_noop_def Let_def
+ empty_sasp_action_def is_valid_operator_sas_plus_def list.pred_set)
+
+lemma sas_plus_problem_has_serial_solution_iff_i':
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "\<A> \<Turnstile> \<Phi>\<^sub>\<forall> (\<phi> (prob_with_noop \<Psi>)) t"
+ shows "SAS_Plus_Semantics.is_serial_solution_for_problem \<Psi>
+ (rem_noops
+ (map (\<lambda>op. \<phi>\<^sub>O\<inverse> (prob_with_noop \<Psi>) op)
+ (concat (\<Phi>\<inverse> (\<phi> (prob_with_noop \<Psi>)) \<A> t))))"
+ using assms noops_valid
+ by(force intro!: noops_sound sas_plus_problem_has_serial_solution_iff_i)
+
+lemma sas_plus_problem_has_serial_solution_iff_ii':
+ assumes "is_valid_problem_sas_plus \<Psi>"
+ and "SAS_Plus_Semantics.is_serial_solution_for_problem \<Psi> \<psi>"
+ and "length \<psi> \<le> h"
+ shows "\<exists>\<A>. (\<A> \<Turnstile> \<Phi>\<^sub>\<forall> (\<phi> (prob_with_noop \<Psi>)) h)"
+ using assms
+ by(fastforce
+ intro!: assms noops_valid noops_complete
+ sas_plus_problem_has_serial_solution_iff_ii
+ [where \<psi> = "(replicate (h - length \<psi>) empty_sasp_action) @ \<psi>"] )
+end
+
+
diff --git a/thys/Verified_SAT_Based_AI_Planning/STRIPS_Representation.thy b/thys/Verified_SAT_Based_AI_Planning/STRIPS_Representation.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/STRIPS_Representation.thy
@@ -0,0 +1,128 @@
+(*
+ Author: Mohammad Abdulaziz, Fred Kurz
+*)
+theory STRIPS_Representation
+ imports State_Variable_Representation
+begin
+
+section "STRIPS Representation"
+
+(*<*)
+type_synonym ('variable) strips_state = "('variable, bool) state"
+(*>*)
+text \<open> We start by declaring a \isakeyword{record} for STRIPS operators.
+This which allows us to define a data type and automatically generated selector operations.
+\footnote{For the full reference on records see \cite[11.6, pp.260-265]{wenzel--2018}}
+
+The record specification given below closely resembles the canonical representation of
+STRIPS operators with fields corresponding to precondition, add effects as well as delete effects.\<close>
+
+record ('variable) strips_operator =
+ precondition_of :: "'variable list"
+ add_effects_of :: "'variable list"
+ delete_effects_of :: "'variable list"
+
+\<comment> \<open> This constructor function is sometimes a more descriptive and replacement for the record
+syntax and can moreover be helpful if the record syntax leads to type ambiguity.\<close>
+abbreviation operator_for
+ :: "'variable list \<Rightarrow> 'variable list \<Rightarrow> 'variable list \<Rightarrow> 'variable strips_operator"
+ where "operator_for pre add delete \<equiv> \<lparr>
+ precondition_of = pre
+ , add_effects_of = add
+ , delete_effects_of = delete \<rparr>"
+
+definition to_precondition
+ :: "'variable strips_operator \<Rightarrow> ('variable, bool) assignment list"
+ where "to_precondition op \<equiv> map (\<lambda>v. (v, True)) (precondition_of op)"
+
+definition to_effect
+ :: "'variable strips_operator \<Rightarrow> ('variable, bool) Effect"
+ where "to_effect op = [(v\<^sub>a, True). v\<^sub>a \<leftarrow> add_effects_of op] @ [(v\<^sub>d, False). v\<^sub>d \<leftarrow> delete_effects_of op]"
+
+text \<open> Similar to the operator definition, we use a record to represent STRIPS problems and specify
+fields for the variables, operators, as well as the initial and goal state. \<close>
+
+record ('variable) strips_problem =
+ variables_of :: "'variable list" ("(_\<^sub>\<V>)" [1000] 999)
+ operators_of :: "'variable strips_operator list" ("(_\<^sub>\<O>)" [1000] 999)
+ initial_of :: "'variable strips_state" ("(_\<^sub>I)" [1000] 999)
+ goal_of :: "'variable strips_state" ("(_\<^sub>G)" [1000] 999)
+
+value "stop" (* Tell document preparation to stop collecting for the last tag *)
+(*<*)
+\<comment> \<open> This constructor function is sometimes a more descriptive and replacement for the record
+syntax and can moreover be helpful if the record syntax leads to type ambiguity.\<close>
+(* TODO change identifier gs ~> G *)
+abbreviation problem_for
+ :: "'variable list
+ \<Rightarrow> 'variable strips_operator list
+ \<Rightarrow> 'variable strips_state
+ \<Rightarrow> 'variable strips_state
+ \<Rightarrow> ('variable) strips_problem"
+ where "problem_for vs ops I gs \<equiv> \<lparr>
+ variables_of = vs
+ , operators_of = ops
+ , initial_of = I
+ , goal_of = gs \<rparr>"
+
+type_synonym ('variable) strips_plan = "'variable strips_operator list"
+
+type_synonym ('variable) strips_parallel_plan = "'variable strips_operator list list"
+
+definition is_valid_operator_strips
+ :: "'variable strips_problem \<Rightarrow> 'variable strips_operator \<Rightarrow> bool"
+ where "is_valid_operator_strips \<Pi> op \<equiv> let
+ vs = variables_of \<Pi>
+ ; pre = precondition_of op
+ ; add = add_effects_of op
+ ; del = delete_effects_of op
+ in list_all (\<lambda>v. ListMem v vs) pre
+ \<and> list_all (\<lambda>v. ListMem v vs) add
+ \<and> list_all (\<lambda>v. ListMem v vs) del
+ \<and> list_all (\<lambda>v. \<not>ListMem v del) add
+ \<and> list_all (\<lambda>v. \<not>ListMem v add) del"
+
+definition "is_valid_problem_strips \<Pi>
+ \<equiv> let ops = operators_of \<Pi>
+ ; vs = variables_of \<Pi>
+ ; I = initial_of \<Pi>
+ ; G = goal_of \<Pi>
+ in list_all (is_valid_operator_strips \<Pi>) ops
+ \<and> (\<forall>v. I v \<noteq> None \<longleftrightarrow> ListMem v vs)
+ \<and> (\<forall>v. G v \<noteq> None \<longrightarrow> ListMem v vs)"
+
+definition is_operator_applicable_in
+ :: "'variable strips_state \<Rightarrow> 'variable strips_operator \<Rightarrow> bool"
+ where "is_operator_applicable_in s op \<equiv> let p = precondition_of op in
+ list_all (\<lambda>v. s v = Some True) p"
+
+(* TODO effect_to_strips and effect_to_assignments could just be removed if we prove a lemma
+ showing the equivalence to effcond semantics.*)
+definition effect__strips
+ :: "'variable strips_operator \<Rightarrow> ('variable, bool) Effect"
+ where "effect__strips op
+ =
+ map (\<lambda>v. (v, True)) (add_effects_of op)
+ @ map (\<lambda>v. (v, False)) (delete_effects_of op)"
+
+definition effect_to_assignments
+ where "effect_to_assignments op \<equiv> effect__strips op"
+(*>*)
+
+text \<open> As discussed in \autoref{sub:serial-sas-plus-and-parallel-strips}, the effect of
+a STRIPS operator can be normalized to a conjunction of atomic effects. We can therefore construct
+the successor state by simply converting the list of add effects to assignments to \<^term>\<open>True\<close> resp.
+converting the list of delete effect to a list of assignments to \<^term>\<open>False\<close> and then adding the
+map corresponding to the assignments to the given state \<^term>\<open>s\<close> as shown below in definition
+\ref{isadef:operator-execution-strips}.
+\footnote{Function \path{effect_to_assignments} converts the operator effect to a list of
+assignments. }\<close>
+
+definition execute_operator
+ :: "'variable strips_state
+ \<Rightarrow> 'variable strips_operator
+ \<Rightarrow> 'variable strips_state" (infixl "\<then>" 52)
+ where "execute_operator s op
+ \<equiv> s ++ map_of (effect_to_assignments op)"
+
+end
\ No newline at end of file
diff --git a/thys/Verified_SAT_Based_AI_Planning/STRIPS_Semantics.thy b/thys/Verified_SAT_Based_AI_Planning/STRIPS_Semantics.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/STRIPS_Semantics.thy
@@ -0,0 +1,2611 @@
+(*
+ Author: Mohammad Abdulaziz, Fred Kurz
+*)
+theory STRIPS_Semantics
+ imports "STRIPS_Representation"
+ "List_Supplement"
+ "Map_Supplement"
+begin
+section "STRIPS Semantics"
+text \<open> Having provided a concrete implementation of STRIPS and a corresponding locale \<open>strips\<close>, we
+can now continue to define the semantics of serial and parallel STRIPS plan execution (see
+\autoref{sub:serial-sas-plus-and-parallel-strips} and
+\autoref{sub:parallel-sas-plus-and-parallel-strips}). \<close>
+subsection "Serial Plan Execution Semantics"
+
+text \<open> Serial plan execution is defined by primitive recursion on the plan.
+Definition \autoref{isadef:execute_serial_plan} returns the given state if the state argument does
+note satisfy the precondition of the next operator in the plan.
+Otherwise it executes the rest of the plan on the successor state \<^term>\<open>execute_operator s op\<close> of
+the given state and operator. \<close>
+
+primrec execute_serial_plan
+ where "execute_serial_plan s [] = s"
+ | "execute_serial_plan s (op # ops)
+ = (if is_operator_applicable_in s op
+ then execute_serial_plan (execute_operator s op) ops
+ else s
+ )"
+
+text \<open> Analogously, a STRIPS trace either returns the singleton list containing only the given
+state in case the precondition of the next operator in the plan is not satisfied. Otherwise, the
+given state is prepended to trace of the rest of the plan for the successor state of executing the
+next operator on the given state. \<close>
+
+fun trace_serial_plan_strips
+ :: "'variable strips_state \<Rightarrow> 'variable strips_plan \<Rightarrow> 'variable strips_state list"
+ where "trace_serial_plan_strips s [] = [s]"
+ | "trace_serial_plan_strips s (op # ops)
+ = s # (if is_operator_applicable_in s op
+ then trace_serial_plan_strips (execute_operator s op) ops
+ else [])"
+
+text \<open> Finally, a serial solution is a plan which transforms a given problems initial state into
+its goal state and for which all operators are elements of the problem's operator list. \<close>
+
+definition is_serial_solution_for_problem
+ where "is_serial_solution_for_problem \<Pi> \<pi>
+ \<equiv> (goal_of \<Pi>) \<subseteq>\<^sub>m execute_serial_plan (initial_of \<Pi>) \<pi>
+ \<and> list_all (\<lambda>op. ListMem op (operators_of \<Pi>)) \<pi>"
+
+lemma is_valid_problem_strips_initial_of_dom:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "dom ((\<Pi>)\<^sub>I) = set ((\<Pi>)\<^sub>\<V>)"
+ proof -
+ {
+ let ?I = "strips_problem.initial_of \<Pi>"
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ fix v
+ have "?I v \<noteq> None \<longleftrightarrow> ListMem v ?vs"
+ using assms(1)
+ unfolding is_valid_problem_strips_def
+ by meson
+ hence "v \<in> dom ?I \<longleftrightarrow> v \<in> set ?vs"
+ using ListMem_iff
+ by fast
+ }
+ thus ?thesis
+ by auto
+ qed
+
+lemma is_valid_problem_dom_of_goal_state_is:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ shows "dom ((\<Pi>)\<^sub>G) \<subseteq> set ((\<Pi>)\<^sub>\<V>)"
+ proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ let ?G = "strips_problem.goal_of \<Pi>"
+ have nb: "\<forall>v. ?G v \<noteq> None \<longrightarrow> ListMem v ?vs"
+ using assms(1)
+ unfolding is_valid_problem_strips_def
+ by meson
+ {
+ fix v
+ assume "v \<in> dom ?G"
+ then have "?G v \<noteq> None"
+ by blast
+ hence "v \<in> set ?vs"
+ using nb
+ unfolding ListMem_iff
+ by blast
+ }
+ thus ?thesis
+ by auto
+ qed
+
+lemma is_valid_problem_strips_operator_variable_sets:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ shows "set (precondition_of op) \<subseteq> set ((\<Pi>)\<^sub>\<V>)"
+ and "set (add_effects_of op) \<subseteq> set ((\<Pi>)\<^sub>\<V>)"
+ and "set (delete_effects_of op) \<subseteq> set ((\<Pi>)\<^sub>\<V>)"
+ and "disjnt (set (add_effects_of op)) (set (delete_effects_of op))"
+ proof -
+ let ?ops = "strips_problem.operators_of \<Pi>"
+ and ?vs = "strips_problem.variables_of \<Pi>"
+ have "list_all (is_valid_operator_strips \<Pi>) ?ops"
+ using assms(1)
+ unfolding is_valid_problem_strips_def
+ by meson
+ moreover have "\<forall>v \<in> set (precondition_of op). v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ and "\<forall>v \<in> set (add_effects_of op). v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ and "\<forall>v \<in> set (delete_effects_of op). v \<in> set ((\<Pi>)\<^sub>\<V>)"
+ and "\<forall>v \<in> set (add_effects_of op). v \<notin> set (delete_effects_of op)"
+ and "\<forall>v \<in> set (delete_effects_of op). v \<notin> set (add_effects_of op)"
+ using assms(2) calculation
+ unfolding is_valid_operator_strips_def list_all_iff Let_def ListMem_iff
+ using variables_of_def
+ by auto+
+ ultimately show "set (precondition_of op) \<subseteq> set ((\<Pi>)\<^sub>\<V>)"
+ and "set (add_effects_of op) \<subseteq> set ((\<Pi>)\<^sub>\<V>)"
+ and "set (delete_effects_of op) \<subseteq> set ((\<Pi>)\<^sub>\<V>)"
+ and "disjnt (set (add_effects_of op)) (set (delete_effects_of op))"
+ unfolding disjnt_def
+ by fast+
+ qed
+
+lemma effect_to_assignments_i:
+ assumes "as = effect_to_assignments op"
+ shows "as = (map (\<lambda>v. (v, True)) (add_effects_of op)
+ @ map (\<lambda>v. (v, False)) (delete_effects_of op))"
+ using assms
+ unfolding effect_to_assignments_def effect__strips_def
+ by auto
+
+lemma effect_to_assignments_ii:
+ \<comment> \<open> NOTE \<open>effect_to_assignments\<close> can be simplified drastically given that only atomic effects
+ and the add-effects as well as delete-effects lists only consist of variables.\<close>
+ assumes "as = effect_to_assignments op"
+ obtains as\<^sub>1 as\<^sub>2
+ where "as = as\<^sub>1 @ as\<^sub>2"
+ and "as\<^sub>1 = map (\<lambda>v. (v, True)) (add_effects_of op)"
+ and "as\<^sub>2 = map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ by (simp add: assms effect__strips_def effect_to_assignments_def)
+
+\<comment> \<open> NOTE Show that for every variable \<open>v\<close> in either the add effect list or the delete effect
+list, there exists an assignment in \isaname{effect_to_assignments op} representing setting \<open>v\<close> to
+true respectively setting \<open>v\<close> to false. Note that the first assumption amounts to saying that
+the add effect list is not empty. This also requires us to split lemma
+\isaname{effect_to_assignments_iii} into two separate lemmas since add and delete effect lists are
+not required to both contain at least one variable simultaneously. \<close>
+lemma effect_to_assignments_iii_a:
+ fixes v
+ assumes "v \<in> set (add_effects_of op)"
+ and "as = effect_to_assignments op"
+ obtains a where "a \<in> set as" "a = (v, True)"
+ proof -
+ let ?add_assignments = "(\<lambda>v. (v, True)) ` set (add_effects_of op)"
+ let ?delete_assignments = "(\<lambda>v. (v, False)) ` set (delete_effects_of op)"
+ obtain as\<^sub>1 as\<^sub>2
+ where a1: "as = as\<^sub>1 @ as\<^sub>2"
+ and a2: "as\<^sub>1 = map (\<lambda>v. (v, True)) (add_effects_of op)"
+ and a3: "as\<^sub>2 = map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ using assms(2) effect_to_assignments_ii
+ by blast
+ then have b: "set as
+ = ?add_assignments \<union> ?delete_assignments"
+ by auto
+ \<comment> \<open> NOTE The existence of an assignment as proposed can be shown by the following sequence of
+ set inclusions. \<close>
+ {
+ from b have "?add_assignments \<subseteq> set as"
+ by blast
+ moreover have "{(v, True)} \<subseteq> ?add_assignments"
+ using assms(1) a2
+ by blast
+ ultimately have "\<exists>a. a \<in> set as \<and> a = (v, True)"
+ by blast
+ }
+ then show ?thesis
+ using that
+ by blast
+ qed
+
+lemma effect_to_assignments_iii_b:
+ \<comment> \<open> NOTE This proof is symmetrical to the one above. \<close>
+ fixes v
+ assumes "v \<in> set (delete_effects_of op)"
+ and "as = effect_to_assignments op"
+ obtains a where "a \<in> set as" "a = (v, False)"
+ proof -
+ let ?add_assignments = "(\<lambda>v. (v, True)) ` set (add_effects_of op)"
+ let ?delete_assignments = "(\<lambda>v. (v, False)) ` set (delete_effects_of op)"
+ obtain as\<^sub>1 as\<^sub>2
+ where a1: "as = as\<^sub>1 @ as\<^sub>2"
+ and a2: "as\<^sub>1 = map (\<lambda>v. (v, True)) (add_effects_of op)"
+ and a3: "as\<^sub>2 = map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ using assms(2) effect_to_assignments_ii
+ by blast
+ then have b: "set as
+ = ?add_assignments \<union> ?delete_assignments"
+ by auto
+ \<comment> \<open> NOTE The existence of an assignment as proposed can be shown by the following sequence of
+ set inclusions. \<close>
+ {
+ from b have "?delete_assignments \<subseteq> set as"
+ by blast
+ moreover have "{(v, False)} \<subseteq> ?delete_assignments"
+ using assms(1) a2
+ by blast
+ ultimately have "\<exists>a. a \<in> set as \<and> a = (v, False)"
+ by blast
+ }
+ then show ?thesis
+ using that
+ by blast
+ qed
+
+lemma effect__strips_i:
+ fixes op
+ assumes "e = effect__strips op"
+ obtains es\<^sub>1 es\<^sub>2
+ where "e = (es\<^sub>1 @ es\<^sub>2)"
+ and "es\<^sub>1 = map (\<lambda>v. (v, True)) (add_effects_of op)"
+ and "es\<^sub>2 = map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ proof -
+ obtain es\<^sub>1 es\<^sub>2 where a: "e = (es\<^sub>1 @ es\<^sub>2)"
+ and b: "es\<^sub>1 = map (\<lambda>v. (v, True)) (add_effects_of op)"
+ and c: "es\<^sub>2 = map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ using assms(1)
+ unfolding effect__strips_def
+ by blast
+ then show ?thesis
+ using that
+ by force
+ qed
+
+lemma effect__strips_ii:
+ fixes op
+ assumes "e = ConjunctiveEffect (es\<^sub>1 @ es\<^sub>2)"
+ and "es\<^sub>1 = map (\<lambda>v. (v, True)) (add_effects_of op)"
+ and "es\<^sub>2 = map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ shows "\<forall>v \<in> set (add_effects_of op). (\<exists>e' \<in> set es\<^sub>1. e' = (v, True))"
+ and "\<forall>v \<in> set (delete_effects_of op). (\<exists>e' \<in> set es\<^sub>2. e' = (v, False))"
+ proof
+ \<comment> \<open> NOTE Show that for each variable \<open>v\<close> in the add effect list, we can obtain an atomic effect
+ with true value. \<close>
+ fix v
+ {
+ assume a: "v \<in> set (add_effects_of op)"
+ have "set es\<^sub>1 = (\<lambda>v. (v, True)) ` set (add_effects_of op)"
+ using assms(2) List.set_map
+ by auto
+ then obtain e'
+ where "e' \<in> set es\<^sub>1"
+ and "e' = (\<lambda>v. (v, True)) v"
+ using a
+ by blast
+ then have "\<exists>e' \<in> set es\<^sub>1. e' = (v, True)"
+ by blast
+ }
+ thus "v \<in> set (add_effects_of op) \<Longrightarrow> \<exists>e' \<in> set es\<^sub>1. e' = (v, True)"
+ by fast
+ \<comment> \<open> NOTE the proof is symmetrical to the one above: for each variable v in the delete effect list,
+ we can obtain an atomic effect with v being false. \<close>
+ next
+ {
+ fix v
+ assume a: "v \<in> set (delete_effects_of op)"
+ have "set es\<^sub>2 = (\<lambda>v. (v, False)) ` set (delete_effects_of op)"
+ using assms(3) List.set_map
+ by force
+ then obtain e''
+ where "e'' \<in> set es\<^sub>2"
+ and "e'' = (\<lambda>v. (v, False)) v"
+ using a
+ by blast
+ then have "\<exists>e'' \<in> set es\<^sub>2. e'' = (v, False)"
+ by blast
+ }
+ thus "\<forall>v\<in>set (delete_effects_of op). \<exists>e'\<in>set es\<^sub>2. e' = (v, False)"
+ by fast
+ qed
+
+(* TODO refactor theory Appendix AND make visible? *)
+lemma map_of_constant_assignments_dom:
+ \<comment> \<open> NOTE ancillary lemma used in the proof below. \<close>
+ assumes "m = map_of (map (\<lambda>v. (v, d)) vs)"
+ shows "dom m = set vs"
+ proof -
+ let ?vs' = "map (\<lambda>v. (v, d)) vs"
+ have "dom m = fst ` set ?vs'"
+ using assms(1) dom_map_of_conv_image_fst
+ by metis
+ moreover have "fst ` set ?vs' = set vs"
+ by force
+ ultimately show ?thesis
+ by argo
+ qed
+
+lemma effect__strips_iii_a:
+ assumes "s' = (s \<then> op)"
+ shows "\<And>v. v \<in> set (add_effects_of op) \<Longrightarrow> s' v = Some True"
+ proof -
+ fix v
+ assume a: "v \<in> set (add_effects_of op)"
+ let ?as = "effect_to_assignments op"
+ obtain as\<^sub>1 as\<^sub>2 where b: "?as = as\<^sub>1 @ as\<^sub>2"
+ and c: "as\<^sub>1 = map (\<lambda>v. (v, True)) (add_effects_of op)"
+ and "as\<^sub>2 = map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ using effect_to_assignments_ii
+ by blast
+ have d: "map_of ?as = map_of as\<^sub>2 ++ map_of as\<^sub>1"
+ using b Map.map_of_append
+ by auto
+ {
+ \<comment> \<open> TODO refactor? \<close>
+ let ?vs = "add_effects_of op"
+ have "?vs \<noteq> []"
+ using a
+ by force
+ then have "dom (map_of as\<^sub>1) = set (add_effects_of op)"
+ using c map_of_constant_assignments_dom
+ by metis
+ then have "v \<in> dom (map_of as\<^sub>1)"
+ using a
+ by blast
+ then have "map_of ?as v = map_of as\<^sub>1 v"
+ using d
+ by force
+ } moreover {
+ let ?f = "\<lambda>_. True"
+ from c have "map_of as\<^sub>1 = (Some \<circ> ?f) |` (set (add_effects_of op))"
+ using map_of_map_restrict
+ by fast
+ then have "map_of as\<^sub>1 v = Some True"
+ using a
+ by auto
+ }
+ moreover have "s' = s ++ map_of as\<^sub>2 ++ map_of as\<^sub>1"
+ using assms(1)
+ unfolding execute_operator_def
+ using b
+ by simp
+ ultimately show "s' v = Some True"
+ by simp
+ qed
+
+(* TODO In contrast to the proof above we need proof preparation with auto. Why? *)
+lemma effect__strips_iii_b:
+ assumes "s' = (s \<then> op)"
+ shows "\<And>v. v \<in> set (delete_effects_of op) \<and> v \<notin> set (add_effects_of op) \<Longrightarrow> s' v = Some False"
+ proof (auto)
+ fix v
+ assume a1: "v \<notin> set (add_effects_of op)" and a2: "v \<in> set (delete_effects_of op)"
+ let ?as = "effect_to_assignments op"
+ obtain as\<^sub>1 as\<^sub>2 where b: "?as = as\<^sub>1 @ as\<^sub>2"
+ and c: "as\<^sub>1 = map (\<lambda>v. (v, True)) (add_effects_of op)"
+ and d: "as\<^sub>2 = map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ using effect_to_assignments_ii
+ by blast
+ have e: "map_of ?as = map_of as\<^sub>2 ++ map_of as\<^sub>1"
+ using b Map.map_of_append
+ by auto
+ {
+ have "dom (map_of as\<^sub>1) = set (add_effects_of op)"
+ using c map_of_constant_assignments_dom
+ by metis
+ then have "v \<notin> dom (map_of as\<^sub>1)"
+ using a1
+ by blast
+ } note f = this
+ {
+ let ?vs = "delete_effects_of op"
+ have "?vs \<noteq> []"
+ using a2
+ by force
+ then have "dom (map_of as\<^sub>2) = set ?vs"
+ using d map_of_constant_assignments_dom
+ by metis
+ } note g = this
+ {
+ have "s' = s ++ map_of as\<^sub>2 ++ map_of as\<^sub>1"
+ using assms(1)
+ unfolding execute_operator_def
+ using b
+ by simp
+ thm f map_add_dom_app_simps(3)[OF f, of "s ++ map_of as\<^sub>2"]
+ moreover have "s' v = (s ++ map_of as\<^sub>2) v"
+ using calculation map_add_dom_app_simps(3)[OF f, of "s ++ map_of as\<^sub>2"]
+ by blast
+ moreover have "v \<in> dom (map_of as\<^sub>2)"
+ using a2 g
+ by argo
+ ultimately have "s' v = map_of as\<^sub>2 v"
+ by fastforce
+ }
+ moreover
+ {
+ let ?f = "\<lambda>_. False"
+ from d have "map_of as\<^sub>2 = (Some \<circ> ?f) |` (set (delete_effects_of op))"
+ using map_of_map_restrict
+ by fast
+ then have "map_of as\<^sub>2 v = Some False"
+ using a2
+ by force
+ }
+ ultimately show " s' v = Some False"
+ by argo
+ qed
+
+(* TODO We need proof preparation with auto. Why? *)
+lemma effect__strips_iii_c:
+ assumes "s' = (s \<then> op)"
+ shows "\<And>v. v \<notin> set (add_effects_of op) \<and> v \<notin> set (delete_effects_of op) \<Longrightarrow> s' v = s v"
+ proof (auto)
+ fix v
+ assume a1: "v \<notin> set (add_effects_of op)" and a2: "v \<notin> set (delete_effects_of op)"
+ let ?as = "effect_to_assignments op"
+ obtain as\<^sub>1 as\<^sub>2 where b: "?as = as\<^sub>1 @ as\<^sub>2"
+ and c: "as\<^sub>1 = map (\<lambda>v. (v, True)) (add_effects_of op)"
+ and d: "as\<^sub>2 = map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ using effect_to_assignments_ii
+ by blast
+ have e: "map_of ?as = map_of as\<^sub>2 ++ map_of as\<^sub>1"
+ using b Map.map_of_append
+ by auto
+ {
+ have "dom (map_of as\<^sub>1) = set (add_effects_of op)"
+ using c map_of_constant_assignments_dom
+ by metis
+ then have "v \<notin> dom (map_of as\<^sub>1)"
+ using a1
+ by blast
+ } moreover {
+ have "dom (map_of as\<^sub>2) = set (delete_effects_of op)"
+ using d map_of_constant_assignments_dom
+ by metis
+ then have "v \<notin> dom (map_of as\<^sub>2)"
+ using a2
+ by blast
+ }
+ ultimately show "s' v = s v"
+ using assms(1)
+ unfolding execute_operator_def
+ by (simp add: b map_add_dom_app_simps(3))
+ qed
+
+text \<open>The following theorem combines three preceding sublemmas which show
+that the following properties hold for the successor state \<open>s' \<equiv> execute_operator op s\<close>
+obtained by executing an operator \<open>op\<close> in a state \<open>s\<close>:
+\footnote{Lemmas \path{effect__strips_iii_a}, \path{effect__strips_iii_b}, and
+\path{effect__strips_iii_c} (not shown).}
+
+\begin{itemize}
+ \item every add effect is satisfied in \<open>s'\<close> (sublemma \isaname{effect__strips_iii_a}); and,
+ \item every delete effect that is not also an add effect is not satisfied in \<open>s'\<close> (sublemma
+\isaname{effect__strips_iii_b}); and finally
+ \item the state remains unchanged---i.e. \<open>s' v = s v\<close>---for all variables which are neither an
+add effect nor a delete effect.
+\end{itemize} \<close>
+
+(* TODO? Rewrite theorem \<open>operator_effect__strips\<close> to match \<open>s ++ map_of (
+effect_to_assignments op)\<close> rather than \<open>execute_operator \<Pi> op s\<close> since we need this
+form later on for the parallel execution theorem? *)
+theorem operator_effect__strips:
+ assumes "s' = (s \<then> op)"
+ shows
+ "\<And>v.
+ v \<in> set (add_effects_of op)
+ \<Longrightarrow> s' v = Some True"
+ and "\<And>v.
+ v \<notin> set (add_effects_of op) \<and> v \<in> set (delete_effects_of op)
+ \<Longrightarrow> s' v = Some False"
+ and "\<And>v.
+ v \<notin> set (add_effects_of op) \<and> v \<notin> set (delete_effects_of op)
+ \<Longrightarrow> s' v = s v"
+proof (auto)
+ show "\<And>v.
+ v \<in> set (add_effects_of op)
+ \<Longrightarrow> s' v = Some True"
+ using assms effect__strips_iii_a
+ by fast
+next
+ show "\<And>v.
+ v \<notin> set (add_effects_of op)
+ \<Longrightarrow> v \<in> set (delete_effects_of op)
+ \<Longrightarrow> s' v = Some False"
+ using assms effect__strips_iii_b
+ by fast
+next
+ show "\<And>v.
+ v \<notin> set (add_effects_of op)
+ \<Longrightarrow> v \<notin> set (delete_effects_of op)
+ \<Longrightarrow> s' v = s v"
+ using assms effect__strips_iii_c
+ by metis
+qed
+
+subsection "Parallel Plan Semantics"
+
+definition "are_all_operators_applicable s ops
+ \<equiv> list_all (\<lambda>op. is_operator_applicable_in s op) ops"
+
+definition "are_operator_effects_consistent op\<^sub>1 op\<^sub>2 \<equiv> let
+ add\<^sub>1 = add_effects_of op\<^sub>1
+ ; add\<^sub>2 = add_effects_of op\<^sub>2
+ ; del\<^sub>1 = delete_effects_of op\<^sub>1
+ ; del\<^sub>2 = delete_effects_of op\<^sub>2
+ in \<not>list_ex (\<lambda>v. list_ex ((=) v) del\<^sub>2) add\<^sub>1 \<and> \<not>list_ex (\<lambda>v. list_ex ((=) v) add\<^sub>2) del\<^sub>1"
+
+definition "are_all_operator_effects_consistent ops \<equiv>
+ list_all (\<lambda>op. list_all (are_operator_effects_consistent op) ops) ops"
+
+definition execute_parallel_operator
+ :: "'variable strips_state
+ \<Rightarrow> 'variable strips_operator list
+ \<Rightarrow> 'variable strips_state"
+ where "execute_parallel_operator s ops
+ \<equiv> foldl (++) s (map (map_of \<circ> effect_to_assignments) ops)"
+text \<open> The parallel STRIPS execution semantics is defined in similar way as the serial STRIPS
+execution semantics. However, the applicability test is lifted to parallel operators and we
+additionally test for operator consistency (which was unecessary in the serial case). \<close>
+
+fun execute_parallel_plan
+ :: "'variable strips_state
+ \<Rightarrow> 'variable strips_parallel_plan
+ \<Rightarrow> 'variable strips_state"
+ where "execute_parallel_plan s [] = s"
+ | "execute_parallel_plan s (ops # opss) = (if
+ are_all_operators_applicable s ops
+ \<and> are_all_operator_effects_consistent ops
+ then execute_parallel_plan (execute_parallel_operator s ops) opss
+ else s)"
+
+definition "are_operators_interfering op\<^sub>1 op\<^sub>2
+ \<equiv> list_ex (\<lambda>v. list_ex ((=) v) (delete_effects_of op\<^sub>1)) (precondition_of op\<^sub>2)
+ \<or> list_ex (\<lambda>v. list_ex ((=) v) (precondition_of op\<^sub>1)) (delete_effects_of op\<^sub>2)"
+
+(* TODO rewrite as inductive predicate *)
+primrec are_all_operators_non_interfering
+ :: "'variable strips_operator list \<Rightarrow> bool"
+ where "are_all_operators_non_interfering [] = True"
+ | "are_all_operators_non_interfering (op # ops)
+ = (list_all (\<lambda>op'. \<not>are_operators_interfering op op') ops
+ \<and> are_all_operators_non_interfering ops)"
+
+text \<open> Since traces mirror the execution semantics, the same is true for the definition of
+parallel STRIPS plan traces. \<close>
+
+fun trace_parallel_plan_strips
+ :: "'variable strips_state \<Rightarrow> 'variable strips_parallel_plan \<Rightarrow> 'variable strips_state list"
+ where "trace_parallel_plan_strips s [] = [s]"
+ | "trace_parallel_plan_strips s (ops # opss) = s # (if
+ are_all_operators_applicable s ops
+ \<and> are_all_operator_effects_consistent ops
+ then trace_parallel_plan_strips (execute_parallel_operator s ops) opss
+ else [])"
+
+text \<open> Similarly, the definition of parallel solutions requires that the parallel execution
+semantics transforms the initial problem into the goal state of the problem and that every
+operator of every parallel operator in the parallel plan is an operator that is defined in the
+problem description. \<close>
+
+definition is_parallel_solution_for_problem
+ where "is_parallel_solution_for_problem \<Pi> \<pi>
+ \<equiv> (strips_problem.goal_of \<Pi>) \<subseteq>\<^sub>m execute_parallel_plan
+ (strips_problem.initial_of \<Pi>) \<pi>
+ \<and> list_all (\<lambda>ops. list_all (\<lambda>op.
+ ListMem op (strips_problem.operators_of \<Pi>)) ops) \<pi>"
+
+
+(* TODO rename are_all_operators_applicable_in_set *)
+lemma are_all_operators_applicable_set:
+ "are_all_operators_applicable s ops
+ \<longleftrightarrow> (\<forall>op \<in> set ops. \<forall>v \<in> set (precondition_of op). s v = Some True)"
+ unfolding are_all_operators_applicable_def
+ STRIPS_Representation.is_operator_applicable_in_def list_all_iff
+ by presburger
+
+(* TODO rename are_all_operators_applicable_in_cons *)
+lemma are_all_operators_applicable_cons:
+ assumes "are_all_operators_applicable s (op # ops)"
+ shows "is_operator_applicable_in s op"
+ and "are_all_operators_applicable s ops"
+ proof -
+ from assms have a: "list_all (\<lambda>op. is_operator_applicable_in s op) (op # ops)"
+ unfolding are_all_operators_applicable_def is_operator_applicable_in_def
+ STRIPS_Representation.is_operator_applicable_in_def
+ by blast
+ then have "is_operator_applicable_in s op"
+ by fastforce
+ moreover {
+ from a have "list_all (\<lambda>op. is_operator_applicable_in s op) ops"
+ by simp
+ then have "are_all_operators_applicable s ops"
+ using are_all_operators_applicable_def is_operator_applicable_in_def
+ STRIPS_Representation.is_operator_applicable_in_def
+ by blast
+ }
+ ultimately show "is_operator_applicable_in s op"
+ and "are_all_operators_applicable s ops"
+ by fast+
+ qed
+
+lemma are_operator_effects_consistent_set:
+ assumes "op\<^sub>1 \<in> set ops"
+ and "op\<^sub>2 \<in> set ops"
+ shows "are_operator_effects_consistent op\<^sub>1 op\<^sub>2
+ = (set (add_effects_of op\<^sub>1) \<inter> set (delete_effects_of op\<^sub>2) = {}
+ \<and> set (delete_effects_of op\<^sub>1) \<inter> set (add_effects_of op\<^sub>2) = {})"
+ proof -
+ have "(\<not>list_ex (\<lambda>v. list_ex ((=) v) (delete_effects_of op\<^sub>2)) (add_effects_of op\<^sub>1))
+ = (set (add_effects_of op\<^sub>1) \<inter> set (delete_effects_of op\<^sub>2) = {})"
+ using list_ex_intersection[of "delete_effects_of op\<^sub>2" "add_effects_of op\<^sub>1"]
+ by meson
+ moreover have "(\<not>list_ex (\<lambda>v. list_ex ((=) v) (add_effects_of op\<^sub>2)) (delete_effects_of op\<^sub>1))
+ = (set (delete_effects_of op\<^sub>1) \<inter> set (add_effects_of op\<^sub>2) = {})"
+ using list_ex_intersection[of "add_effects_of op\<^sub>2" "delete_effects_of op\<^sub>1"]
+ by meson
+ ultimately show "are_operator_effects_consistent op\<^sub>1 op\<^sub>2
+ = (set (add_effects_of op\<^sub>1) \<inter> set (delete_effects_of op\<^sub>2) = {}
+ \<and> set (delete_effects_of op\<^sub>1) \<inter> set (add_effects_of op\<^sub>2) = {})"
+ unfolding are_operator_effects_consistent_def
+ by presburger
+ qed
+
+lemma are_all_operator_effects_consistent_set:
+ "are_all_operator_effects_consistent ops
+ \<longleftrightarrow> (\<forall>op\<^sub>1 \<in> set ops. \<forall>op\<^sub>2 \<in> set ops.
+ (set (add_effects_of op\<^sub>1) \<inter> set (delete_effects_of op\<^sub>2) = {})
+ \<and> (set (delete_effects_of op\<^sub>1) \<inter> set (add_effects_of op\<^sub>2) = {}))"
+ proof -
+ {
+ fix op\<^sub>1 op\<^sub>2
+ assume "op\<^sub>1 \<in> set ops" and "op\<^sub>2 \<in> set ops"
+ hence "are_operator_effects_consistent op\<^sub>1 op\<^sub>2
+ = (set (add_effects_of op\<^sub>1) \<inter> set (delete_effects_of op\<^sub>2) = {}
+ \<and> set (delete_effects_of op\<^sub>1) \<inter> set (add_effects_of op\<^sub>2) = {})"
+ using are_operator_effects_consistent_set[of op\<^sub>1 ops op\<^sub>2]
+ by fast
+ }
+ thus ?thesis
+ unfolding are_all_operator_effects_consistent_def list_all_iff
+ by force
+ qed
+
+lemma are_all_effects_consistent_tail:
+ assumes "are_all_operator_effects_consistent (op # ops)"
+ shows "are_all_operator_effects_consistent ops"
+ proof -
+ from assms
+ have a: "list_all (\<lambda>op'. list_all (are_operator_effects_consistent op')
+ (Cons op ops)) (Cons op ops)"
+ unfolding are_all_operator_effects_consistent_def
+ by blast
+ then have b_1: "list_all (are_operator_effects_consistent op) (op # ops)"
+ and b_2: "list_all (\<lambda>op'. list_all (are_operator_effects_consistent op') (op # ops)) ops"
+ by force+
+ then have "list_all (are_operator_effects_consistent op) ops"
+ by simp
+ moreover
+ {
+ {
+ fix z
+ assume "z \<in> set (Cons op ops)"
+ and "list_all (are_operator_effects_consistent z) (op # ops)"
+ then have "list_all (are_operator_effects_consistent z) ops"
+ by auto
+ }
+ then have "list_all (\<lambda>op'. list_all (are_operator_effects_consistent op') ops) ops"
+ using list.pred_mono_strong[of
+ "(\<lambda>op'. list_all (are_operator_effects_consistent op') (op # ops))"
+ "Cons op ops" "(\<lambda>op'. list_all (are_operator_effects_consistent op') ops)"
+ ] a
+ by fastforce
+ }
+ ultimately have "list_all (are_operator_effects_consistent op) ops
+ \<and> list_all (\<lambda>op'. list_all (are_operator_effects_consistent op') ops) ops"
+ by blast
+ then show ?thesis
+ using are_all_operator_effects_consistent_def
+ by fast
+ qed
+
+lemma are_all_operators_non_interfering_tail:
+ assumes "are_all_operators_non_interfering (op # ops)"
+ shows "are_all_operators_non_interfering ops"
+ using assms
+ unfolding are_all_operators_non_interfering_def
+ by simp
+
+lemma are_operators_interfering_symmetric:
+ assumes "are_operators_interfering op\<^sub>1 op\<^sub>2"
+ shows "are_operators_interfering op\<^sub>2 op\<^sub>1"
+ using assms
+ unfolding are_operators_interfering_def list_ex_iff
+ by fast
+
+\<comment> \<open> A small technical characterizing operator lists with property
+\isaname{are_all_operators_non_interfering ops}. We show that pairs of distinct operators which interfere
+with one another cannot both be contained in the corresponding operator set. \<close>
+lemma are_all_operators_non_interfering_set_contains_no_distinct_interfering_operator_pairs:
+ assumes "are_all_operators_non_interfering ops"
+ and "are_operators_interfering op\<^sub>1 op\<^sub>2"
+ and "op\<^sub>1 \<noteq> op\<^sub>2"
+ shows "op\<^sub>1 \<notin> set ops \<or> op\<^sub>2 \<notin> set ops"
+ using assms
+ proof (induction ops)
+ case (Cons op ops)
+ thm Cons.IH[OF _ Cons.prems(2, 3)]
+ have nb\<^sub>1: "\<forall>op' \<in> set ops. \<not>are_operators_interfering op op'"
+ and nb\<^sub>2: "are_all_operators_non_interfering ops"
+ using Cons.prems(1)
+ unfolding are_all_operators_non_interfering.simps(2) list_all_iff
+ by blast+
+ then consider (A) "op = op\<^sub>1"
+ | (B) "op = op\<^sub>2"
+ | (C) "op \<noteq> op\<^sub>1 \<and> op \<noteq> op\<^sub>2"
+ by blast
+ thus ?case
+ proof (cases)
+ case A
+ {
+ assume "op\<^sub>2 \<in> set (op # ops)"
+ then have "op\<^sub>2 \<in> set ops"
+ using Cons.prems(3) A
+ by force
+ then have "\<not>are_operators_interfering op\<^sub>1 op\<^sub>2"
+ using nb\<^sub>1 A
+ by fastforce
+ hence False
+ using Cons.prems(2)..
+ }
+ thus ?thesis
+ by blast
+ next
+ case B
+ {
+ assume "op\<^sub>1 \<in> set (op # ops)"
+ then have "op\<^sub>1 \<in> set ops"
+ using Cons.prems(3) B
+ by force
+ then have "\<not>are_operators_interfering op\<^sub>1 op\<^sub>2"
+ using nb\<^sub>1 B are_operators_interfering_symmetric
+ by blast
+ hence False
+ using Cons.prems(2)..
+ }
+ thus ?thesis
+ by blast
+ next
+ case C
+ thus ?thesis
+ using Cons.IH[OF nb\<^sub>2 Cons.prems(2, 3)]
+ by force
+ qed
+ qed simp
+
+(* TODO The recurring \<open>list_all \<leadsto> \<forall>\<close> transformations could be refactored into a general
+lemma.
+ TODO refactor (also used in lemma \<open>execute_serial_plan_split_i\<close>). *)
+lemma execute_parallel_plan_precondition_cons_i:
+ fixes s :: "('variable, bool) state"
+ assumes "\<not>are_operators_interfering op op'"
+ and "is_operator_applicable_in s op"
+ and "is_operator_applicable_in s op'"
+ shows "is_operator_applicable_in (s ++ map_of (effect_to_assignments op)) op'"
+ proof -
+ let ?s' = "s ++ map_of (effect_to_assignments op)"
+ \<comment> \<open> TODO slightly hackish to exploit the definition of \<open>execute_operator\<close>, but we
+ otherwise have to rewrite theorem \<open>operator_effect__strips\<close> (which is a todo as of now). \<close>
+ {
+ have a: "?s' = s \<then> op"
+ by (simp add: execute_operator_def)
+ then have "\<And>v. v \<in> set (add_effects_of op) \<Longrightarrow> ?s' v = Some True"
+ and "\<And>v. v \<notin> set (add_effects_of op) \<and> v \<in> set (delete_effects_of op) \<Longrightarrow> ?s' v = Some False"
+ and "\<And>v. v \<notin> set (add_effects_of op) \<and> v \<notin> set (delete_effects_of op) \<Longrightarrow> ?s' v = s v"
+ using operator_effect__strips
+ by metis+
+ }
+ note a = this
+ \<comment> \<open> TODO refactor lemma \<open>not_have_interference_set\<close>. \<close>
+ {
+ fix v
+ assume \<alpha>: "v \<in> set (precondition_of op')"
+ {
+ fix v
+ have "\<not>list_ex ((=) v) (delete_effects_of op)
+ = list_all (\<lambda>v'. \<not>v = v') (delete_effects_of op)"
+ using not_list_ex_equals_list_all_not[
+ where P="(=) v" and xs="delete_effects_of op"]
+ by blast
+ } moreover {
+ from assms(1)
+ have "\<not>list_ex (\<lambda>v. list_ex ((=) v) (delete_effects_of op)) (precondition_of op')"
+ unfolding are_operators_interfering_def
+ by blast
+ then have "list_all (\<lambda>v. \<not>list_ex ((=) v) (delete_effects_of op)) (precondition_of op')"
+ using not_list_ex_equals_list_all_not[
+ where P="\<lambda>v. list_ex ((=) v) (delete_effects_of op)" and xs="precondition_of op'"]
+ by blast
+ }
+ ultimately have \<beta>:
+ "list_all (\<lambda>v. list_all (\<lambda>v'. \<not>v = v') (delete_effects_of op)) (precondition_of op')"
+ by presburger
+ moreover {
+ fix v
+ have "list_all (\<lambda>v'. \<not>v = v') (delete_effects_of op)
+ = (\<forall>v' \<in> set (delete_effects_of op). \<not>v = v')"
+ using list_all_iff [where P="\<lambda>v'. \<not>v = v'" and x="delete_effects_of op"]
+ .
+ }
+ ultimately have "\<forall>v \<in> set (precondition_of op'). \<forall>v' \<in> set (delete_effects_of op). \<not>v = v'"
+ using \<beta> list_all_iff[
+ where P="\<lambda>v. list_all (\<lambda>v'. \<not>v = v') (delete_effects_of op)"
+ and x="precondition_of op'"]
+ by presburger
+ then have "v \<notin> set (delete_effects_of op)"
+ using \<alpha>
+ by fast
+ }
+ note b = this
+ {
+ fix v
+ assume a: "v \<in> set (precondition_of op')"
+ have "list_all (\<lambda>v. s v = Some True) (precondition_of op')"
+ using assms(3)
+ unfolding is_operator_applicable_in_def
+ STRIPS_Representation.is_operator_applicable_in_def
+ by presburger
+ then have "\<forall>v \<in> set (precondition_of op'). s v = Some True"
+ using list_all_iff[where P="\<lambda>v. s v = Some True" and x="precondition_of op'"]
+ by blast
+ then have "s v = Some True"
+ using a
+ by blast
+ }
+ note c = this
+ {
+ fix v
+ assume d: "v \<in> set (precondition_of op')"
+ then have "?s' v = Some True"
+ proof (cases "v \<in> set (add_effects_of op)")
+ case True
+ then show ?thesis
+ using a
+ by blast
+ next
+ case e: False
+ then show ?thesis
+ proof (cases "v \<in> set (delete_effects_of op)")
+ case True
+ then show ?thesis
+ using assms(1) b d
+ by fast
+ next
+ case False
+ then have "?s' v = s v"
+ using a e
+ by blast
+ then show ?thesis
+ using c d
+ by presburger
+ qed
+ qed
+ }
+ then have "list_all (\<lambda>v. ?s' v = Some True) (precondition_of op')"
+ using list_all_iff[where P="\<lambda>v. ?s' v = Some True" and x="precondition_of op'"]
+ by blast
+ then show ?thesis
+ unfolding is_operator_applicable_in_def
+ STRIPS_Representation.is_operator_applicable_in_def
+ by auto
+ qed
+
+\<comment> \<open> The third assumption \<open>are_all_operators_non_interfering (a # ops)\<close>" is not part of the
+precondition of \isaname{execute_parallel_operator} but is required for the proof of the
+subgoal hat applicable is maintained. \<close>
+lemma execute_parallel_plan_precondition_cons:
+ fixes a :: "'variable strips_operator"
+ assumes "are_all_operators_applicable s (a # ops)"
+ and "are_all_operator_effects_consistent (a # ops)"
+ and "are_all_operators_non_interfering (a # ops)"
+ shows "are_all_operators_applicable (s ++ map_of (effect_to_assignments a)) ops"
+ and "are_all_operator_effects_consistent ops"
+ and "are_all_operators_non_interfering ops"
+ using are_all_effects_consistent_tail[OF assms(2)]
+ are_all_operators_non_interfering_tail[OF assms(3)]
+ proof -
+ let ?s' = "s ++ map_of (effect_to_assignments a)"
+ have nb\<^sub>1: "\<forall>op \<in> set (a # ops). is_operator_applicable_in s op"
+ using assms(1) are_all_operators_applicable_set
+ unfolding are_all_operators_applicable_def is_operator_applicable_in_def
+ STRIPS_Representation.is_operator_applicable_in_def list_all_iff
+ by blast
+ have nb\<^sub>2: "\<forall>op \<in> set ops. \<not>are_operators_interfering a op"
+ using assms(3)
+ unfolding are_all_operators_non_interfering_def list_all_iff
+ by simp
+ have nb\<^sub>3: "is_operator_applicable_in s a"
+ using assms(1) are_all_operators_applicable_set
+ unfolding are_all_operators_applicable_def is_operator_applicable_in_def
+ STRIPS_Representation.is_operator_applicable_in_def list_all_iff
+ by force
+ {
+ fix op
+ assume op_in_ops: "op \<in> set ops"
+ hence "is_operator_applicable_in ?s' op"
+ using execute_parallel_plan_precondition_cons_i[of a op] nb\<^sub>1 nb\<^sub>2 nb\<^sub>3
+ by force
+ }
+ then show "are_all_operators_applicable ?s' ops"
+ unfolding are_all_operators_applicable_def list_all_iff
+ is_operator_applicable_in_def
+ by blast
+ qed
+
+lemma execute_parallel_operator_cons[simp]:
+ "execute_parallel_operator s (op # ops)
+ = execute_parallel_operator (s ++ map_of (effect_to_assignments op)) ops"
+ unfolding execute_parallel_operator_def
+ by simp
+
+lemma execute_parallel_operator_cons_equals:
+ assumes "are_all_operators_applicable s (a # ops)"
+ and "are_all_operator_effects_consistent (a # ops)"
+ and "are_all_operators_non_interfering (a # ops)"
+ shows "execute_parallel_operator s (a # ops)
+ = execute_parallel_operator (s ++ map_of (effect_to_assignments a)) ops"
+ proof -
+ let ?s' = "s ++ map_of (effect_to_assignments a)"
+ {
+ from assms(1, 2)
+ have "execute_parallel_operator s (Cons a ops)
+ = foldl (++) s (map (map_of \<circ> effect_to_assignments) (Cons a ops))"
+ unfolding execute_parallel_operator_def
+ by presburger
+ also have "\<dots> = foldl (++) (?s')
+ (map (map_of \<circ> effect_to_assignments) ops)"
+ by auto
+ finally have "execute_parallel_operator s (Cons a ops)
+ = foldl (++) (?s')
+ (map (map_of \<circ> effect_to_assignments) ops)"
+ using execute_parallel_operator_def
+ by blast
+ }
+ \<comment> \<open> NOTE the precondition of \isaname{execute_parallel} for \<open>a # ops\<close> is also true for the tail
+ list and \<open>state ?s'\<close> as shown in lemma
+ \isaname{execute_parallel_operator_precondition_cons}. Hence the precondition for the r.h.s.
+ of the goal also holds. \<close>
+ moreover have "execute_parallel_operator ?s' ops
+ = foldl (++) (s ++ (map_of \<circ> effect_to_assignments) a)
+ (map (map_of \<circ> effect_to_assignments) ops)"
+ by (simp add: execute_parallel_operator_def)
+ ultimately show ?thesis
+ by force
+ qed
+
+\<comment> \<open> We show here that following the lemma above, executing one operator of a parallel
+operator can be replaced by a (single) STRIPS operator execution. \<close>
+corollary execute_parallel_operator_cons_equals_corollary:
+ assumes "are_all_operators_applicable s (a # ops)"
+ shows "execute_parallel_operator s (a # ops)
+ = execute_parallel_operator (s \<then> a) ops"
+ proof -
+ let ?s' = "s ++ map_of (effect_to_assignments a)"
+ from assms
+ have "execute_parallel_operator s (a # ops)
+ = execute_parallel_operator (s ++ map_of (effect_to_assignments a)) ops"
+ using execute_parallel_operator_cons_equals
+ by simp
+ moreover have "?s' = s \<then> a"
+ unfolding execute_operator_def
+ by simp
+ ultimately show ?thesis
+ by argo
+ qed
+
+(* TODO duplicate? *)
+lemma effect_to_assignments_simp[simp]: "effect_to_assignments op
+ = map (\<lambda>v. (v, True)) (add_effects_of op) @ map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ by (simp add: effect_to_assignments_i)
+
+lemma effect_to_assignments_set_is[simp]:
+ "set (effect_to_assignments op) = { ((v, a), True) | v a. (v, a) \<in> set (add_effects_of op) }
+ \<union> { ((v, a), False) | v a. (v, a) \<in> set (delete_effects_of op) }"
+proof -
+ obtain as where "effect__strips op = as"
+ and "as = map (\<lambda>v. (v, True)) (add_effects_of op)
+ @ map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ unfolding effect__strips_def
+ by blast
+ moreover have "as
+ = map (\<lambda>v. (v, True)) (add_effects_of op) @ map (\<lambda>v. (v, False)) (delete_effects_of op)"
+ using calculation(2)
+ unfolding map_append map_map comp_apply
+ by auto
+ moreover have "effect_to_assignments op = as"
+ unfolding effect_to_assignments_def calculation(1, 2)
+ by auto
+ ultimately show ?thesis
+ unfolding set_map
+ by auto
+ qed
+
+corollary effect_to_assignments_construction_from_function_graph:
+ assumes "set (add_effects_of op) \<inter> set (delete_effects_of op) = {}"
+ shows "effect_to_assignments op = map
+ (\<lambda>v. (v, if ListMem v (add_effects_of op) then True else False))
+ (add_effects_of op @ delete_effects_of op)"
+ and "effect_to_assignments op = map
+ (\<lambda>v. (v, if ListMem v (delete_effects_of op) then False else True))
+ (add_effects_of op @ delete_effects_of op)"
+ proof -
+ let ?f = "\<lambda>v. (v, if ListMem v (add_effects_of op) then True else False)"
+ and ?g = "\<lambda>v. (v, if ListMem v (delete_effects_of op) then False else True)"
+ {
+ have "map ?f (add_effects_of op @ delete_effects_of op)
+ = map ?f (add_effects_of op) @ map ?f (delete_effects_of op)"
+ using map_append
+ by fast
+ \<comment> \<open> TODO slow. \<close>
+ hence "effect_to_assignments op = map ?f (add_effects_of op @ delete_effects_of op)"
+ using ListMem_iff assms
+ by fastforce
+ } moreover {
+ have "map ?g (add_effects_of op @ delete_effects_of op)
+ = map ?g (add_effects_of op) @ map ?g (delete_effects_of op)"
+ using map_append
+ by fast
+ \<comment> \<open> TODO slow. \<close>
+ hence "effect_to_assignments op = map ?g (add_effects_of op @ delete_effects_of op)"
+ using ListMem_iff assms
+ by fastforce
+ }
+ ultimately show "effect_to_assignments op = map
+ (\<lambda>v. (v, if ListMem v (add_effects_of op) then True else False))
+ (add_effects_of op @ delete_effects_of op)"
+ and "effect_to_assignments op = map
+ (\<lambda>v. (v, if ListMem v (delete_effects_of op) then False else True))
+ (add_effects_of op @ delete_effects_of op)"
+ by blast+
+ qed
+
+corollary map_of_effect_to_assignments_is_none_if:
+ assumes "\<not>v \<in> set (add_effects_of op)"
+ and "\<not>v \<in> set (delete_effects_of op)"
+ shows "map_of (effect_to_assignments op) v = None"
+ proof -
+ let ?l = "effect_to_assignments op"
+ {
+ have "set ?l = { (v, True) | v. v \<in> set (add_effects_of op) }
+ \<union> { (v, False) | v. v \<in> set (delete_effects_of op)}"
+ by auto
+ then have "fst ` set ?l
+ = (fst ` {(v, True) | v. v \<in> set (add_effects_of op)})
+ \<union> (fst ` {(v, False) | v. v \<in> set (delete_effects_of op)})"
+ using image_Un[of fst "{(v, True) | v. v \<in> set (add_effects_of op)}"
+ "{(v, False) | v. v \<in> set (delete_effects_of op)}"]
+ by presburger
+ \<comment> \<open> TODO slow.\<close>
+ also have "\<dots> = (fst ` (\<lambda>v. (v, True)) ` set (add_effects_of op))
+ \<union> (fst ` (\<lambda>v. (v, False)) ` set (delete_effects_of op))"
+ using setcompr_eq_image[of "\<lambda>v. (v, True)" "\<lambda>v. v \<in> set (add_effects_of op)"]
+ setcompr_eq_image[of "\<lambda>v. (v, False)" "\<lambda>v. v \<in> set (delete_effects_of op)"]
+ by simp
+ \<comment> \<open> TODO slow.\<close>
+ also have "\<dots> = id ` set (add_effects_of op) \<union> id ` set (delete_effects_of op)"
+ by force
+ \<comment> \<open> TODO slow.\<close>
+ finally have "fst ` set ?l = set (add_effects_of op) \<union> set (delete_effects_of op)"
+ by auto
+ hence "v \<notin> fst ` set ?l"
+ using assms(1, 2)
+ by blast
+ }
+ thus ?thesis
+ using map_of_eq_None_iff[of ?l v]
+ by blast
+ qed
+
+lemma execute_parallel_operator_positive_effect_if_i:
+ assumes "are_all_operators_applicable s ops"
+ and "are_all_operator_effects_consistent ops"
+ and "op \<in> set ops"
+ and "v \<in> set (add_effects_of op)"
+ shows "map_of (effect_to_assignments op) v = Some True"
+ proof -
+ let ?f = "\<lambda>x. if ListMem x (add_effects_of op) then True else False"
+ and ?l'= " map (\<lambda>v. (v, if ListMem v (add_effects_of op) then True else False))
+ (add_effects_of op @ delete_effects_of op)"
+ have "set (add_effects_of op) \<noteq> {}"
+ using assms(4)
+ by fastforce
+ moreover {
+ have "set (add_effects_of op) \<inter> set (delete_effects_of op) = {}"
+ using are_all_operator_effects_consistent_set assms(2, 3)
+ by fast
+ moreover have "effect_to_assignments op = ?l'"
+ using effect_to_assignments_construction_from_function_graph(1) calculation
+ by fast
+ ultimately have "map_of (effect_to_assignments op) = map_of ?l'"
+ by argo
+ }
+ ultimately have "map_of (effect_to_assignments op) v = Some (?f v)"
+ using Map_Supplement.map_of_from_function_graph_is_some_if[
+ of _ _ "?f", OF _ assms(4)]
+ by simp
+ thus ?thesis
+ using ListMem_iff assms(4)
+ by metis
+ qed
+
+lemma execute_parallel_operator_positive_effect_if:
+ fixes ops
+ assumes "are_all_operators_applicable s ops"
+ and "are_all_operator_effects_consistent ops"
+ and "op \<in> set ops"
+ and "v \<in> set (add_effects_of op)"
+ shows "execute_parallel_operator s ops v = Some True"
+ proof -
+ let ?l = "map (map_of \<circ> effect_to_assignments) ops"
+ have set_l_is: "set ?l = (map_of \<circ> effect_to_assignments) ` set ops"
+ using set_map
+ by fastforce
+ {
+ let ?m = "(map_of \<circ> effect_to_assignments) op"
+ have "?m \<in> set ?l"
+ using assms(3) set_l_is
+ by blast
+ moreover have "?m v = Some True"
+ using execute_parallel_operator_positive_effect_if_i[OF assms]
+ by fastforce
+ ultimately have "\<exists>m \<in> set ?l. m v = Some True"
+ by blast
+ }
+ moreover {
+ fix m'
+ assume "m' \<in> set ?l"
+ then obtain op'
+ where op'_in_set_ops: "op' \<in> set ops"
+ and m'_is: "m' = (map_of \<circ> effect_to_assignments) op'"
+ by auto
+ then have "set (add_effects_of op) \<inter> set (delete_effects_of op') = {}"
+ using assms(2, 3) are_all_operator_effects_consistent_set[of ops]
+ by blast
+ then have "v \<notin> set (delete_effects_of op')"
+ using assms(4)
+ by blast
+ then consider (v_in_set_add_effects) "v \<in> set (add_effects_of op')"
+ | (otherwise) "\<not>v \<in> set (add_effects_of op') \<and> \<not>v \<in> set (delete_effects_of op')"
+ by blast
+ hence "m' v = Some True \<or> m' v = None"
+ proof (cases)
+ case v_in_set_add_effects
+ \<comment> \<open> TODO slow. \<close>
+ thus ?thesis
+ using execute_parallel_operator_positive_effect_if_i[
+ OF assms(1, 2) op'_in_set_ops, of v] m'_is
+ by simp
+ next
+ case otherwise
+ then have "\<not>v \<in> set (add_effects_of op')"
+ and "\<not>v \<in> set (delete_effects_of op')"
+ by blast+
+ thus ?thesis
+ using map_of_effect_to_assignments_is_none_if[of v op'] m'_is
+ by fastforce
+ qed
+ }
+ \<comment> \<open> TODO slow. \<close>
+ ultimately show ?thesis
+ unfolding execute_parallel_operator_def
+ using foldl_map_append_is_some_if[of s v True ?l]
+ by meson
+ qed
+
+lemma execute_parallel_operator_negative_effect_if_i:
+ assumes "are_all_operators_applicable s ops"
+ and "are_all_operator_effects_consistent ops"
+ and "op \<in> set ops"
+ and "v \<in> set (delete_effects_of op)"
+ shows "map_of (effect_to_assignments op) v = Some False"
+ proof -
+ let ?f = "\<lambda>x. if ListMem x (delete_effects_of op) then False else True"
+ and ?l'= " map (\<lambda>v. (v, if ListMem v (delete_effects_of op) then False else True))
+ (add_effects_of op @ delete_effects_of op)"
+ have "set (delete_effects_of op @ add_effects_of op) \<noteq> {}"
+ using assms(4)
+ by fastforce
+ moreover have "v \<in> set (delete_effects_of op @ add_effects_of op)"
+ using assms(4)
+ by simp
+ moreover {
+ have "set (add_effects_of op) \<inter> set (delete_effects_of op) = {}"
+ using are_all_operator_effects_consistent_set assms(2, 3)
+ by fast
+ moreover have "effect_to_assignments op = ?l'"
+ using effect_to_assignments_construction_from_function_graph(2) calculation
+ by blast
+ ultimately have "map_of (effect_to_assignments op) = map_of ?l'"
+ by argo
+ }
+ ultimately have "map_of (effect_to_assignments op) v = Some (?f v)"
+ using Map_Supplement.map_of_from_function_graph_is_some_if[
+ of "add_effects_of op @ delete_effects_of op" v "?f"]
+ by force
+ thus ?thesis
+ using assms(4)
+ unfolding ListMem_iff
+ by presburger
+ qed
+
+lemma execute_parallel_operator_negative_effect_if:
+ assumes "are_all_operators_applicable s ops"
+ and "are_all_operator_effects_consistent ops"
+ and "op \<in> set ops"
+ and "v \<in> set (delete_effects_of op)"
+ shows "execute_parallel_operator s ops v = Some False"
+ proof -
+ let ?l = "map (map_of \<circ> effect_to_assignments) ops"
+ have set_l_is: "set ?l = (map_of \<circ> effect_to_assignments) ` set ops"
+ using set_map
+ by fastforce
+ {
+ let ?m = "(map_of \<circ> effect_to_assignments) op"
+ have "?m \<in> set ?l"
+ using assms(3) set_l_is
+ by blast
+ moreover have "?m v = Some False"
+ using execute_parallel_operator_negative_effect_if_i[OF assms]
+ by fastforce
+ ultimately have "\<exists>m \<in> set ?l. m v = Some False"
+ by blast
+ }
+ moreover {
+ fix m'
+ assume "m' \<in> set ?l"
+ then obtain op'
+ where op'_in_set_ops: "op' \<in> set ops"
+ and m'_is: "m' = (map_of \<circ> effect_to_assignments) op'"
+ by auto
+ then have "set (delete_effects_of op) \<inter> set (add_effects_of op') = {}"
+ using assms(2, 3) are_all_operator_effects_consistent_set[of ops]
+ by blast
+ then have "v \<notin> set (add_effects_of op')"
+ using assms(4)
+ by blast
+ then consider (v_in_set_delete_effects) "v \<in> set (delete_effects_of op')"
+ | (otherwise) "\<not>v \<in> set (add_effects_of op') \<and> \<not>v \<in> set (delete_effects_of op')"
+ by blast
+ hence "m' v = Some False \<or> m' v = None"
+ proof (cases)
+ case v_in_set_delete_effects
+ \<comment> \<open> TODO slow. \<close>
+ thus ?thesis
+ using execute_parallel_operator_negative_effect_if_i[
+ OF assms(1, 2) op'_in_set_ops, of v] m'_is
+ by simp
+ next
+ case otherwise
+ then have "\<not>v \<in> set (add_effects_of op')"
+ and "\<not>v \<in> set (delete_effects_of op')"
+ by blast+
+ thus ?thesis
+ using map_of_effect_to_assignments_is_none_if[of v op'] m'_is
+ by fastforce
+ qed
+ }
+ \<comment> \<open> TODO slow. \<close>
+ ultimately show ?thesis
+ unfolding execute_parallel_operator_def
+ using foldl_map_append_is_some_if[of s v False ?l]
+ by meson
+ qed
+
+lemma execute_parallel_operator_no_effect_if:
+ assumes "\<forall>op \<in> set ops. \<not>v \<in> set (add_effects_of op) \<and> \<not>v \<in> set (delete_effects_of op)"
+ shows "execute_parallel_operator s ops v = s v"
+ using assms
+ unfolding execute_parallel_operator_def
+ proof (induction ops arbitrary: s)
+ case (Cons a ops)
+ let ?f = "map_of \<circ> effect_to_assignments"
+ {
+ have "v \<notin> set (add_effects_of a) \<and> v \<notin> set (delete_effects_of a)"
+ using Cons.prems(1)
+ by force
+ then have "?f a v = None"
+ using map_of_effect_to_assignments_is_none_if[of v a]
+ by fastforce
+ then have "v \<notin> dom (?f a)"
+ by blast
+ hence "(s ++ ?f a) v = s v"
+ using map_add_dom_app_simps(3)[of v "?f a" s]
+ by blast
+ }
+ moreover {
+ have "\<forall>op\<in>set ops. v \<notin> set (add_effects_of op) \<and> v \<notin> set (delete_effects_of op)"
+ using Cons.prems(1)
+ by simp
+ hence "foldl (++) (s ++ ?f a) (map ?f ops) v = (s ++ ?f a) v"
+ using Cons.IH[of "s ++ ?f a"]
+ by blast
+ }
+ moreover {
+ have "map ?f (a # ops) = ?f a # map ?f ops"
+ by force
+ then have "foldl (++) s (map ?f (a # ops))
+ = foldl (++) (s ++ ?f a) (map ?f ops)"
+ using foldl_Cons
+ by force
+ }
+ ultimately show ?case
+ by argo
+ qed fastforce
+
+corollary execute_parallel_operators_strips_none_if:
+ assumes "\<forall>op \<in> set ops. \<not>v \<in> set (add_effects_of op) \<and> \<not>v \<in> set (delete_effects_of op)"
+ and "s v = None"
+ shows "execute_parallel_operator s ops v = None"
+ using execute_parallel_operator_no_effect_if[OF assms(1)] assms(2)
+ by simp
+
+corollary execute_parallel_operators_strips_none_if_contraposition:
+ assumes "\<not>execute_parallel_operator s ops v = None"
+ shows "(\<exists>op \<in> set ops. v \<in> set (add_effects_of op) \<or> v \<in> set (delete_effects_of op))
+ \<or> s v \<noteq> None"
+ proof -
+ let ?P = "(\<forall>op \<in> set ops. \<not>v \<in> set (add_effects_of op) \<and> \<not>v \<in> set (delete_effects_of op))
+ \<and> s v = None"
+ and ?Q = "execute_parallel_operator s ops v = None"
+ have "?P \<Longrightarrow> ?Q"
+ using execute_parallel_operators_strips_none_if[of ops v s]
+ by blast
+ then have "\<not>?P"
+ using contrapos_nn[of ?Q ?P]
+ using assms
+ by argo
+ thus ?thesis
+ by meson
+ qed
+
+text \<open> We will now move on to showing the equivalent to theorem \isaname{operator_effect__strips}
+in \isaname{execute_parallel_operator_effect}.
+Under the condition that for a list of operators \<^term>\<open>ops\<close> all
+operators in the corresponding set are applicable in a given state \<^term>\<open>s\<close> and all operator effects
+are consistent, if an operator \<^term>\<open>op\<close> exists with \<^term>\<open>op \<in> set ops\<close> and with \<^term>\<open>v\<close> being
+an add effect of \<^term>\<open>op\<close>, then the successor state
+
+ @{text[display, indent=4] "s' \<equiv> execute_parallel_operator s ops"}
+
+will evaluate \<^term>\<open>v\<close> to true, that is
+
+ @{text[display, indent=4] "execute_parallel_operator s ops v = Some True"}
+
+Symmetrically, if \<^term>\<open>v\<close> is a delete effect, we have
+
+ @{text[display, indent=4] "execute_parallel_operator s ops v = Some False"}
+
+under the same condition as for the positive effect.
+Lastly, if \<^term>\<open>v\<close> is neither an add effect nor a delete effect for any operator in the
+operator set corresponding to $ops$, then the state after parallel operator execution remains
+unchanged, i.e.
+
+ @{text[display, indent=4] "execute_parallel_operator s ops v = s v"}
+\<close>
+
+theorem execute_parallel_operator_effect:
+ assumes "are_all_operators_applicable s ops"
+ and "are_all_operator_effects_consistent ops"
+shows "op \<in> set ops \<and> v \<in> set (add_effects_of op)
+ \<longrightarrow> execute_parallel_operator s ops v = Some True"
+ and "op \<in> set ops \<and> v \<in> set (delete_effects_of op)
+ \<longrightarrow> execute_parallel_operator s ops v = Some False"
+ and "(\<forall>op \<in> set ops.
+ v \<notin> set (add_effects_of op) \<and> v \<notin> set (delete_effects_of op))
+ \<longrightarrow> execute_parallel_operator s ops v = s v"
+ using execute_parallel_operator_positive_effect_if[OF assms]
+ execute_parallel_operator_negative_effect_if[OF assms]
+ execute_parallel_operator_no_effect_if[of ops v s]
+ by blast+
+
+
+lemma is_parallel_solution_for_problem_operator_set:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "ops \<in> set \<pi>"
+ and "op \<in> set ops"
+ shows "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ proof -
+ have "\<forall>ops \<in> set \<pi>. \<forall>op \<in> set ops. op \<in> set (strips_problem.operators_of \<Pi>)"
+ using assms(1)
+ unfolding is_parallel_solution_for_problem_def list_all_iff ListMem_iff..
+ thus ?thesis
+ using assms(2, 3)
+ by fastforce
+ qed
+
+lemma trace_parallel_plan_strips_not_nil: "trace_parallel_plan_strips I \<pi> \<noteq> []"
+ proof (cases \<pi>)
+ case (Cons a list)
+ then show ?thesis
+ by (cases "are_all_operators_applicable I (hd \<pi>) \<and> are_all_operator_effects_consistent (hd \<pi>)"
+ , simp+)
+ qed simp
+
+corollary length_trace_parallel_plan_gt_0[simp]: "0 < length (trace_parallel_plan_strips I \<pi>)"
+ using trace_parallel_plan_strips_not_nil..
+
+corollary length_trace_minus_one_lt_length_trace[simp]:
+ "length (trace_parallel_plan_strips I \<pi>) - 1 < length (trace_parallel_plan_strips I \<pi>)"
+ using diff_less[OF _ length_trace_parallel_plan_gt_0]
+ by auto
+
+lemma trace_parallel_plan_strips_head_is_initial_state:
+ "trace_parallel_plan_strips I \<pi> ! 0 = I"
+ proof (cases \<pi>)
+ case (Cons a list)
+ then show ?thesis
+ by (cases "are_all_operators_applicable I a \<and> are_all_operator_effects_consistent a", simp+)
+ qed simp
+
+lemma trace_parallel_plan_strips_length_gt_one_if:
+ assumes "k < length (trace_parallel_plan_strips I \<pi>) - 1"
+ shows "1 < length (trace_parallel_plan_strips I \<pi>)"
+ using assms
+ by linarith
+
+\<comment> \<open> This lemma simply shows that the last element of a \<open>trace_parallel_plan_strips execution\<close>
+\<open>step s # trace_parallel_plan_strips s' \<pi>\<close> always is the last element of
+\<open>trace_parallel_plan_strips s' \<pi>\<close> since \<open>trace_parallel_plan_strips\<close> always returns at least a
+singleton list (even if \<open>\<pi> = []\<close>). \<close>
+lemma trace_parallel_plan_strips_last_cons_then:
+ "last (s # trace_parallel_plan_strips s' \<pi>) = last (trace_parallel_plan_strips s' \<pi>)"
+ by (cases \<pi>, simp, force)
+
+text \<open> Parallel plan traces have some important properties that we want to confirm before
+proceeding. Let \<^term>\<open>\<tau> \<equiv> trace_parallel_plan_strips I \<pi>\<close> be a trace for a parallel plan \<^term>\<open>\<pi>\<close>
+with initial state \<^term>\<open>I\<close>.
+
+First, all parallel operators \<^term>\<open>ops = \<pi> ! k\<close> for any index \<^term>\<open>k\<close> with \<^term>\<open>k < length \<tau> - 1\<close>
+(meaning that \<^term>\<open>k\<close> is not the index of the last element).
+must be applicable and their effects must be consistent. Otherwise, the trace would have terminated
+and \<^term>\<open>ops\<close> would have been the last element. This would violate the assumption that \<^term>\<open>k < length \<tau> - 1\<close>
+is not the last index since the index of the last element is \<^term>\<open>length \<tau> - 1\<close>.
+\footnote{More precisely, the index of the last element is \<^term>\<open>length \<tau> - 1\<close> if \<^term>\<open>\<tau>\<close> is not
+empty which is however always true since the trace contains at least the initial state.} \<close>
+
+(* TODO? hide? *)
+lemma trace_parallel_plan_strips_operator_preconditions:
+ assumes "k < length (trace_parallel_plan_strips I \<pi>) - 1"
+ shows "are_all_operators_applicable (trace_parallel_plan_strips I \<pi> ! k) (\<pi> ! k)
+ \<and> are_all_operator_effects_consistent (\<pi> ! k)"
+ using assms
+ proof (induction "\<pi>" arbitrary: I k)
+ \<comment> \<open> NOTE Base case yields contradiction with assumption and can be left to automation. \<close>
+ case (Cons a \<pi>)
+ then show ?case
+ proof (cases "are_all_operators_applicable I a \<and> are_all_operator_effects_consistent a")
+ case True
+ have trace_parallel_plan_strips_cons: "trace_parallel_plan_strips I (a # \<pi>)
+ = I # trace_parallel_plan_strips (execute_parallel_operator I a) \<pi>"
+ using True
+ by simp
+ then show ?thesis
+ proof (cases "k")
+ case 0
+ have "trace_parallel_plan_strips I (a # \<pi>) ! 0 = I"
+ using trace_parallel_plan_strips_cons
+ by simp
+ moreover have "(a # \<pi>) ! 0 = a"
+ by simp
+ ultimately show ?thesis
+ using True 0
+ by presburger
+ next
+ case (Suc k')
+ let ?I' = "execute_parallel_operator I a"
+ have "trace_parallel_plan_strips I (a # \<pi>) ! Suc k' = trace_parallel_plan_strips ?I' \<pi> ! k'"
+ using trace_parallel_plan_strips_cons
+ by simp
+ moreover have "(a # \<pi>) ! Suc k' = \<pi> ! k'"
+ by simp
+ moreover {
+ have "length (trace_parallel_plan_strips I (a # \<pi>))
+ = 1 + length (trace_parallel_plan_strips ?I' \<pi>)"
+ unfolding trace_parallel_plan_strips_cons
+ by simp
+ then have "k' < length (trace_parallel_plan_strips ?I' \<pi>) - 1"
+ using Suc Cons.prems
+ by fastforce
+ hence "are_all_operators_applicable (trace_parallel_plan_strips ?I' \<pi> ! k') (\<pi> ! k')
+ \<and> are_all_operator_effects_consistent (\<pi> ! k')"
+ using Cons.IH[of k']
+ by blast
+ }
+ ultimately show ?thesis
+ using Suc
+ by argo
+ qed
+ next
+ case False
+ then have "trace_parallel_plan_strips I (a # \<pi>) = [I]"
+ by force
+ then have "length (trace_parallel_plan_strips I (a # \<pi>)) - 1 = 0"
+ by simp
+ \<comment> \<open> NOTE Thesis follows from contradiction with assumption. \<close>
+ then show ?thesis
+ using Cons.prems
+ by force
+ qed
+ qed auto
+
+text \<open> Another interesting property that we verify below is that elements of the trace
+store the result of plan prefix execution. This means that for an index \<^term>\<open>k\<close> with\newline
+\<^term>\<open>k < length (trace_parallel_plan_strips I \<pi>)\<close>, the \<^term>\<open>k\<close>-th element of the trace is state
+reached by executing the plan prefix \<^term>\<open>take k \<pi>\<close> consisting of the first \<^term>\<open>k\<close> parallel
+operators of \<^term>\<open>\<pi>\<close>. \<close>
+
+lemma trace_parallel_plan_plan_prefix:
+ assumes "k < length (trace_parallel_plan_strips I \<pi>)"
+ shows "trace_parallel_plan_strips I \<pi> ! k = execute_parallel_plan I (take k \<pi>)"
+ using assms
+ proof (induction \<pi> arbitrary: I k)
+ case (Cons a \<pi>)
+ then show ?case
+ proof (cases "are_all_operators_applicable I a \<and> are_all_operator_effects_consistent a")
+ case True
+ let ?\<sigma> = "trace_parallel_plan_strips I (a # \<pi>)"
+ and ?I' = "execute_parallel_operator I a"
+ have \<sigma>_equals: "?\<sigma> = I # trace_parallel_plan_strips ?I' \<pi>"
+ using True
+ by auto
+ then show ?thesis
+ proof (cases "k = 0")
+ case False
+ obtain k' where k_is_suc_of_k': "k = Suc k'"
+ using not0_implies_Suc[OF False]
+ by blast
+ then have "execute_parallel_plan I (take k (a # \<pi>))
+ = execute_parallel_plan ?I' (take k' \<pi>)"
+ using True
+ by simp
+ moreover have "trace_parallel_plan_strips I (a # \<pi>) ! k
+ = trace_parallel_plan_strips ?I' \<pi> ! k'"
+ using \<sigma>_equals k_is_suc_of_k'
+ by simp
+ moreover {
+ have "k' < length (trace_parallel_plan_strips (execute_parallel_operator I a) \<pi>)"
+ using Cons.prems \<sigma>_equals k_is_suc_of_k'
+ by force
+ hence "trace_parallel_plan_strips ?I' \<pi> ! k'
+ = execute_parallel_plan ?I' (take k' \<pi>)"
+ using Cons.IH[of k' ?I']
+ by blast
+ }
+ ultimately show ?thesis
+ by presburger
+ qed simp
+ next
+ case operator_precondition_violated: False
+ then show ?thesis
+ proof (cases "k = 0")
+ case False
+ then have "trace_parallel_plan_strips I (a # \<pi>) = [I]"
+ using operator_precondition_violated
+ by force
+ moreover have "execute_parallel_plan I (take k (a # \<pi>)) = I"
+ using Cons.prems operator_precondition_violated
+ by force
+ ultimately show ?thesis
+ using Cons.prems nth_Cons_0
+ by auto
+ qed simp
+ qed
+ qed simp
+
+
+lemma length_trace_parallel_plan_strips_lte_length_plan_plus_one:
+ shows "length (trace_parallel_plan_strips I \<pi>) \<le> length \<pi> + 1"
+ proof (induction \<pi> arbitrary: I)
+ case (Cons a \<pi>)
+ then show ?case
+ proof (cases "are_all_operators_applicable I a \<and> are_all_operator_effects_consistent a")
+ case True
+ let ?I' = "execute_parallel_operator I a"
+ {
+ have "trace_parallel_plan_strips I (a # \<pi>) = I # trace_parallel_plan_strips ?I' \<pi>"
+ using True
+ by auto
+ then have "length (trace_parallel_plan_strips I (a # \<pi>))
+ = length (trace_parallel_plan_strips ?I' \<pi>) + 1"
+ by simp
+ moreover have "length (trace_parallel_plan_strips ?I' \<pi>) \<le> length \<pi> + 1"
+ using Cons.IH[of ?I']
+ by blast
+ ultimately have "length (trace_parallel_plan_strips I (a # \<pi>)) \<le> length (a # \<pi>) + 1"
+ by simp
+ }
+ thus ?thesis
+ by blast
+ qed auto
+ qed simp
+
+\<comment> \<open> Show that \<open>\<pi>\<close> is at least a singleton list. \<close>
+lemma plan_is_at_least_singleton_plan_if_trace_has_at_least_two_elements:
+ assumes "k < length (trace_parallel_plan_strips I \<pi>) - 1"
+ obtains ops \<pi>' where "\<pi> = ops # \<pi>'"
+ proof -
+ let ?\<tau> = "trace_parallel_plan_strips I \<pi>"
+ have "length ?\<tau> \<le> length \<pi> + 1"
+ using length_trace_parallel_plan_strips_lte_length_plan_plus_one
+ by fast
+ then have "0 < length \<pi>"
+ using trace_parallel_plan_strips_length_gt_one_if assms
+ by force
+ then obtain k' where "length \<pi> = Suc k'"
+ using gr0_implies_Suc
+ by meson
+ thus ?thesis using that
+ using length_Suc_conv[of \<pi> k']
+ by blast
+ qed
+
+\<comment> \<open> Show that if a parallel plan trace does not have maximum length, in the last state
+reached through operator execution the parallel operator execution condition was violated. \<close>
+corollary length_trace_parallel_plan_strips_lt_length_plan_plus_one_then:
+ assumes "length (trace_parallel_plan_strips I \<pi>) < length \<pi> + 1"
+ shows "\<not>are_all_operators_applicable
+ (execute_parallel_plan I (take (length (trace_parallel_plan_strips I \<pi>) - 1) \<pi>))
+ (\<pi> ! (length (trace_parallel_plan_strips I \<pi>) - 1))
+ \<or> \<not>are_all_operator_effects_consistent (\<pi> ! (length (trace_parallel_plan_strips I \<pi>) - 1))"
+ using assms
+ proof (induction \<pi> arbitrary: I)
+ case (Cons ops \<pi>)
+ let ?\<tau> = "trace_parallel_plan_strips I (ops # \<pi>)"
+ and ?I' = "execute_parallel_operator I ops"
+ show ?case
+ proof (cases "are_all_operators_applicable I ops \<and> are_all_operator_effects_consistent ops")
+ case True
+ then have \<tau>_is: "?\<tau> = I # trace_parallel_plan_strips ?I' \<pi>"
+ by fastforce
+ show ?thesis
+ proof (cases "length (trace_parallel_plan_strips ?I' \<pi>) < length \<pi> + 1")
+ case True
+ then have "\<not> are_all_operators_applicable
+ (execute_parallel_plan ?I'
+ (take (length (trace_parallel_plan_strips ?I' \<pi>) - 1) \<pi>))
+ (\<pi> ! (length (trace_parallel_plan_strips ?I' \<pi>) - 1))
+ \<or> \<not> are_all_operator_effects_consistent
+ (\<pi> ! (length (trace_parallel_plan_strips ?I' \<pi>) - 1))"
+ using Cons.IH[of ?I']
+ by blast
+ moreover have "trace_parallel_plan_strips ?I' \<pi> \<noteq> []"
+ using trace_parallel_plan_strips_not_nil
+ by blast
+ ultimately show ?thesis
+ unfolding take_Cons'
+ by simp
+ next
+ case False
+ then have "length (trace_parallel_plan_strips ?I' \<pi>) \<ge> length \<pi> + 1"
+ by fastforce
+ thm Cons.prems
+ moreover have "length (trace_parallel_plan_strips I (ops # \<pi>))
+ = 1 + length (trace_parallel_plan_strips ?I' \<pi>)"
+ using True
+ by force
+ moreover have "length (trace_parallel_plan_strips ?I' \<pi>)
+ < length (ops # \<pi>)"
+ using Cons.prems calculation(2)
+ by force
+ ultimately have False
+ by fastforce
+ thus ?thesis..
+ qed
+ next
+ case False
+ then have \<tau>_is_singleton: "?\<tau> = [I]"
+ using False
+ by auto
+ then have "ops = (ops # \<pi>) ! (length ?\<tau> - 1)"
+ by fastforce
+ moreover have "execute_parallel_plan I (take (length ?\<tau> - 1) \<pi>) = I"
+ using \<tau>_is_singleton
+ by auto
+ \<comment> \<open> TODO slow. \<close>
+ ultimately show ?thesis
+ using False
+ by auto
+ qed
+ qed simp
+
+lemma trace_parallel_plan_step_effect_is:
+ assumes "k < length (trace_parallel_plan_strips I \<pi>) - 1"
+ shows "trace_parallel_plan_strips I \<pi> ! Suc k
+ = execute_parallel_operator (trace_parallel_plan_strips I \<pi> ! k) (\<pi> ! k)"
+ proof -
+ \<comment> \<open> NOTE Rewrite the proposition using lemma \<open>trace_parallel_plan_strips_subplan\<close>. \<close>
+ {
+ let ?\<tau> = "trace_parallel_plan_strips I \<pi>"
+ have "Suc k < length ?\<tau>"
+ using assms
+ by linarith
+ hence "trace_parallel_plan_strips I \<pi> ! Suc k
+ = execute_parallel_plan I (take (Suc k) \<pi>)"
+ using trace_parallel_plan_plan_prefix[of "Suc k" I \<pi>]
+ by blast
+ }
+ moreover have "execute_parallel_plan I (take (Suc k) \<pi>)
+ = execute_parallel_operator (trace_parallel_plan_strips I \<pi> ! k) (\<pi> ! k)"
+ using assms
+ proof (induction k arbitrary: I \<pi>)
+ case 0
+ then have "execute_parallel_operator (trace_parallel_plan_strips I \<pi> ! 0) (\<pi> ! 0)
+ = execute_parallel_operator I (\<pi> ! 0)"
+ using trace_parallel_plan_strips_head_is_initial_state[of I \<pi>]
+ by argo
+ moreover {
+ obtain ops \<pi>' where "\<pi> = ops # \<pi>'"
+ using plan_is_at_least_singleton_plan_if_trace_has_at_least_two_elements[OF "0.prems"]
+ by blast
+ then have "take (Suc 0) \<pi> = [\<pi> ! 0]"
+ by simp
+ hence "execute_parallel_plan I (take (Suc 0) \<pi>)
+ = execute_parallel_plan I [\<pi> ! 0]"
+ by argo
+ }
+ moreover {
+ have "0 < length (trace_parallel_plan_strips I \<pi>) - 1"
+ using trace_parallel_plan_strips_length_gt_one_if "0.prems"
+ by fastforce
+ hence "are_all_operators_applicable I (\<pi> ! 0)
+ \<and> are_all_operator_effects_consistent (\<pi> ! 0)"
+ using trace_parallel_plan_strips_operator_preconditions[of 0 I \<pi>]
+ trace_parallel_plan_strips_head_is_initial_state[of I \<pi>]
+ by argo
+ }
+ ultimately show ?case
+ by auto
+ next
+ case (Suc k)
+ obtain ops \<pi>' where \<pi>_split: "\<pi> = ops # \<pi>'"
+ using plan_is_at_least_singleton_plan_if_trace_has_at_least_two_elements[OF Suc.prems]
+ by blast
+ let ?I' = "execute_parallel_operator I ops"
+ {
+ have "length (trace_parallel_plan_strips I \<pi>) =
+ 1 + length (trace_parallel_plan_strips ?I' \<pi>')"
+ using Suc.prems \<pi>_split
+ by fastforce
+ then have "k < length (trace_parallel_plan_strips ?I' \<pi>')"
+ using Suc.prems
+ by fastforce
+ moreover have "trace_parallel_plan_strips I \<pi> ! Suc k
+ = trace_parallel_plan_strips ?I' \<pi>' ! k"
+ using Suc.prems \<pi>_split
+ by force
+ ultimately have "trace_parallel_plan_strips I \<pi> ! Suc k
+ = execute_parallel_plan ?I' (take k \<pi>')"
+ using trace_parallel_plan_plan_prefix[of k ?I' \<pi>']
+ by argo
+ }
+ moreover have "execute_parallel_plan I (take (Suc (Suc k)) \<pi>)
+ = execute_parallel_plan ?I' (take (Suc k) \<pi>')"
+ using Suc.prems \<pi>_split
+ by fastforce
+ moreover {
+ have "0 < length (trace_parallel_plan_strips I \<pi>) - 1"
+ using Suc.prems
+ by linarith
+ hence "are_all_operators_applicable I (\<pi> ! 0)
+ \<and> are_all_operator_effects_consistent (\<pi> ! 0)"
+ using trace_parallel_plan_strips_operator_preconditions[of 0 I \<pi>]
+ trace_parallel_plan_strips_head_is_initial_state[of I \<pi>]
+ by argo
+ }
+ ultimately show ?case
+ using Suc.IH Suc.prems \<pi>_split
+ by auto
+ qed
+ ultimately show ?thesis
+ using assms
+ by argo
+ qed
+
+\<comment> \<open> Show that every state in a plan execution trace of a valid problem description is defined
+for all problem variables. This is true because the initial state is defined for all problem
+variables—by definition of @{text "is_valid_problem_strips \<Pi>"}—and no operator can remove a
+previously defined variable (only positive and negative effects are possible). \<close>
+(* TODO refactor \<open>STRIPS_Semantics\<close> + abstract/concretize first two assumptions (e.g. second one
+only needs all operators are problem operators)? *)
+lemma trace_parallel_plan_strips_none_if:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "is_valid_problem_strips \<Pi>"
+ and "is_parallel_solution_for_problem \<Pi> \<pi>"
+ and "k < length (trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>)"
+ shows "(trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi> ! k) v = None \<longleftrightarrow> v \<notin> set ((\<Pi>)\<^sub>\<V>)"
+ proof -
+ let ?vs = "strips_problem.variables_of \<Pi>"
+ and ?ops = "strips_problem.operators_of \<Pi>"
+ and ?\<tau> = "trace_parallel_plan_strips ((\<Pi>)\<^sub>I) \<pi>"
+ and ?I = "strips_problem.initial_of \<Pi>"
+ show ?thesis
+ using assms
+ proof (induction k)
+ case 0
+ have "?\<tau> ! 0 = ?I"
+ using trace_parallel_plan_strips_head_is_initial_state
+ by auto
+ then show ?case
+ using is_valid_problem_strips_initial_of_dom[OF assms(1)]
+ by auto
+ next
+ case (Suc k)
+ have k_lt_length_\<tau>_minus_one: "k < length ?\<tau> - 1"
+ using Suc.prems(3)
+ by linarith
+ then have IH: "(trace_parallel_plan_strips ?I \<pi> ! k) v = None \<longleftrightarrow> v \<notin>set ((\<Pi>)\<^sub>\<V>)"
+ using Suc.IH[OF Suc.prems(1, 2)]
+ by force
+ have \<tau>_Suc_k_is: "(?\<tau> ! Suc k) = execute_parallel_operator (?\<tau> ! k) (\<pi> ! k)"
+ using trace_parallel_plan_step_effect_is[OF k_lt_length_\<tau>_minus_one].
+ have all_operators_applicable: "are_all_operators_applicable (?\<tau> ! k) (\<pi> ! k)"
+ and all_effects_consistent: "are_all_operator_effects_consistent (\<pi> ! k)"
+ using trace_parallel_plan_strips_operator_preconditions[OF k_lt_length_\<tau>_minus_one]
+ by simp+
+ show ?case
+ proof (rule iffI)
+ assume \<tau>_Suc_k_of_v_is_None: "(?\<tau> ! Suc k) v = None"
+ show "v \<notin> set ((\<Pi>)\<^sub>\<V>)"
+ proof (rule ccontr)
+ assume "\<not>v \<notin> set ((\<Pi>)\<^sub>\<V>)"
+ then have v_in_set_vs: "v \<in> set((\<Pi>)\<^sub>\<V>)"
+ by blast
+ show False
+ proof (cases "\<exists>op \<in> set (\<pi> ! k).
+ v \<in> set (add_effects_of op) \<or> v \<in> set (delete_effects_of op)")
+ case True
+ then obtain op
+ where op_in_\<pi>\<^sub>k: "op \<in> set (\<pi> ! k)"
+ and "v \<in> set (add_effects_of op) \<or> v \<in> set (delete_effects_of op)"..
+ then consider (A) "v \<in> set (add_effects_of op)"
+ | (B) "v \<in> set (delete_effects_of op)"
+ by blast
+ thus False
+ using execute_parallel_operator_positive_effect_if[OF
+ all_operators_applicable all_effects_consistent op_in_\<pi>\<^sub>k]
+ execute_parallel_operator_negative_effect_if[OF
+ all_operators_applicable all_effects_consistent op_in_\<pi>\<^sub>k]
+ \<tau>_Suc_k_of_v_is_None \<tau>_Suc_k_is
+ by (cases, fastforce+)
+ next
+ case False
+ then have "\<forall>op \<in> set (\<pi> ! k).
+ v \<notin> set (add_effects_of op) \<and> v \<notin> set (delete_effects_of op)"
+ by blast
+ then have "(?\<tau> ! Suc k) v = (?\<tau> ! k) v"
+ using execute_parallel_operator_no_effect_if \<tau>_Suc_k_is
+ by fastforce
+ then have "v \<notin> set ((\<Pi>)\<^sub>\<V>)"
+ using IH \<tau>_Suc_k_of_v_is_None
+ by simp
+ thus False
+ using v_in_set_vs
+ by blast
+ qed
+ qed
+ next
+ assume v_notin_vs: "v \<notin> set ((\<Pi>)\<^sub>\<V>)"
+ {
+ fix op
+ assume op_in_\<pi>\<^sub>k: "op \<in> set (\<pi> ! k)"
+ {
+ have "1 < length ?\<tau>"
+ using trace_parallel_plan_strips_length_gt_one_if[OF k_lt_length_\<tau>_minus_one].
+ then have "0 < length ?\<tau> - 1"
+ using k_lt_length_\<tau>_minus_one
+ by linarith
+ moreover have "length ?\<tau> - 1 \<le> length \<pi>"
+ using length_trace_parallel_plan_strips_lte_length_plan_plus_one le_diff_conv
+ by blast
+ then have "k < length \<pi>"
+ using k_lt_length_\<tau>_minus_one
+ by force
+ hence "\<pi> ! k \<in> set \<pi>"
+ by simp
+ }
+ then have op_in_ops: "op \<in> set ?ops"
+ using is_parallel_solution_for_problem_operator_set[OF assms(2) _ op_in_\<pi>\<^sub>k]
+ by force
+ hence "v \<notin> set (add_effects_of op)" and "v \<notin> set (delete_effects_of op)"
+ subgoal
+ using is_valid_problem_strips_operator_variable_sets(2) assms(1) op_in_ops
+ v_notin_vs
+ by auto
+ subgoal
+ using is_valid_problem_strips_operator_variable_sets(3) assms(1) op_in_ops
+ v_notin_vs
+ by auto
+ done
+ }
+ then have "(?\<tau> ! Suc k) v = (?\<tau> ! k) v"
+ using execute_parallel_operator_no_effect_if \<tau>_Suc_k_is
+ by metis
+ thus "(?\<tau> ! Suc k) v = None"
+ using IH v_notin_vs
+ by fastforce
+ qed
+ qed
+ qed
+
+text \<open> Finally, given initial and goal states \<^term>\<open>I\<close> and \<^term>\<open>G\<close>, we can show that it's
+equivalent to say that \<^term>\<open>\<pi>\<close> is a solution for \<^term>\<open>I\<close> and \<^term>\<open>G\<close>---i.e.
+\<^term>\<open>G \<subseteq>\<^sub>m execute_parallel_plan I \<pi>\<close>---and
+that the goal state is subsumed by the last element of the trace of \<^term>\<open>\<pi>\<close> with initial state
+\<^term>\<open>I\<close>. \<close>
+
+lemma execute_parallel_plan_reaches_goal_iff_goal_is_last_element_of_trace:
+ "G \<subseteq>\<^sub>m execute_parallel_plan I \<pi>
+ \<longleftrightarrow> G \<subseteq>\<^sub>m last (trace_parallel_plan_strips I \<pi>)"
+ proof -
+ let ?LHS = "G \<subseteq>\<^sub>m execute_parallel_plan I \<pi>"
+ and ?RHS = "G \<subseteq>\<^sub>m last (trace_parallel_plan_strips I \<pi>)"
+ show ?thesis
+ proof (rule iffI)
+ assume ?LHS
+ thus ?RHS
+ proof (induction \<pi> arbitrary: I)
+ \<comment> \<open> NOTE Nil case follows from simplification. \<close>
+ case (Cons a \<pi>)
+ thus ?case
+ using Cons.prems
+ proof (cases "are_all_operators_applicable I a \<and> are_all_operator_effects_consistent a")
+ case True
+ let ?I' = "execute_parallel_operator I a"
+ {
+ have "execute_parallel_plan I (a # \<pi>) = execute_parallel_plan ?I' \<pi>"
+ using True
+ by auto
+ then have "G \<subseteq>\<^sub>m execute_parallel_plan ?I' \<pi>"
+ using Cons.prems
+ by presburger
+ hence "G \<subseteq>\<^sub>m last (trace_parallel_plan_strips ?I' \<pi>)"
+ using Cons.IH[of ?I']
+ by blast
+ }
+ moreover {
+ have "trace_parallel_plan_strips I (a # \<pi>)
+ = I # trace_parallel_plan_strips ?I' \<pi>"
+ using True
+ by simp
+ then have "last (trace_parallel_plan_strips I (a # \<pi>))
+ = last (I # trace_parallel_plan_strips ?I' \<pi>)"
+ by argo
+ hence "last (trace_parallel_plan_strips I (a # \<pi>))
+ = last (trace_parallel_plan_strips ?I' \<pi>)"
+ using trace_parallel_plan_strips_last_cons_then[of I ?I' \<pi>]
+ by argo
+ }
+ ultimately show ?thesis
+ by argo
+ qed force
+ qed simp
+ next
+ assume ?RHS
+ thus ?LHS
+ proof (induction \<pi> arbitrary: I)
+ \<comment> \<open> NOTE Nil case follows from simplification. \<close>
+ case (Cons a \<pi>)
+ thus ?case
+ proof (cases "are_all_operators_applicable I a \<and> are_all_operator_effects_consistent a")
+ case True
+ let ?I' = "execute_parallel_operator I a"
+ {
+ have "trace_parallel_plan_strips I (a # \<pi>) = I # (trace_parallel_plan_strips ?I' \<pi>)"
+ using True
+ by simp
+ then have "last (trace_parallel_plan_strips I (a # \<pi>))
+ = last (trace_parallel_plan_strips ?I' \<pi>)"
+ using trace_parallel_plan_strips_last_cons_then[of I ?I' \<pi>]
+ by argo
+ hence "G \<subseteq>\<^sub>m last (trace_parallel_plan_strips ?I' \<pi>)"
+ using Cons.prems
+ by argo
+ }
+ thus ?thesis
+ using True Cons
+ by simp
+ next
+ case False
+ then have "last (trace_parallel_plan_strips I (a # \<pi>)) = I"
+ and "execute_parallel_plan I (a # \<pi>) = I"
+ by (fastforce, force)
+ thus ?thesis
+ using Cons.prems
+ by argo
+ qed
+ qed fastforce
+ qed
+ qed
+
+subsection "Serializable Parallel Plans"
+
+text \<open> With the groundwork on parallel and serial execution of STRIPS in place we can now address
+the question under which conditions a parallel solution to a problem corresponds to a serial
+solution and vice versa.
+As we will see (in theorem \ref{isathm:embedding-serial-strips-plan}), while a serial plan can
+be trivially rewritten as a parallel plan consisting of singleton operator list for each operator
+in the plan, the condition for parallel plan solutions also involves non interference. \<close>
+
+
+\<comment> \<open> Given that non interference implies that operator execution order can be switched
+arbitrarily, it stands to reason that parallel operator execution can be serialized if non
+interference is mandated in addition to the regular parallel execution condition (applicability and
+effect consistency). This is in fact true as we show in the lemma below
+\footnote{In the source literatur it is required that $\mathrm{app}_S(s)$ is defined which requires that
+$\mathrm{app}_o(s)$ is defined for every $o \in S$. This again means that the preconditions
+hold in $s$ and the set of effects is consistent which translates to the execution condition
+in \<open>execute_parallel_operator\<close>.
+\cite[Lemma 2.11., p.1037]{DBLP:journals/ai/RintanenHN06}
+
+Also, the proposition \cite[Lemma 2.11., p.1037]{DBLP:journals/ai/RintanenHN06} is in fact
+proposed to be true for any total ordering of the operator set but we only proof it for the
+implicit total ordering induced by the specific order in the operator list of the problem
+statement.} \<close>
+(* TODO rename execute_parallel_operator_equals_execute_serial_if *)
+lemma execute_parallel_operator_equals_execute_sequential_strips_if:
+ fixes s :: "('variable, bool) state"
+ assumes "are_all_operators_applicable s ops"
+ and "are_all_operator_effects_consistent ops"
+ and "are_all_operators_non_interfering ops"
+ shows "execute_parallel_operator s ops = execute_serial_plan s ops"
+ using assms
+ proof (induction ops arbitrary: s)
+ case Nil
+ have "execute_parallel_operator s Nil
+ = foldl (++) s (map (map_of \<circ> effect_to_assignments) Nil)"
+ using Nil.prems(1,2)
+ unfolding execute_parallel_operator_def
+ by presburger
+ also have "\<dots> = s"
+ by simp
+ finally have "execute_parallel_operator s Nil = s"
+ by blast
+ moreover have "execute_serial_plan s Nil = s"
+ by auto
+ ultimately show ?case
+ by simp
+ next
+ case (Cons a ops)
+ \<comment> \<open> NOTE Use the preceding lemmas to show that the premises hold for the sublist and use the IH
+ to obtain the theorem for the sublist ops. \<close>
+ have a: "is_operator_applicable_in s a"
+ using are_all_operators_applicable_cons Cons.prems(1)
+ by blast+
+ let ?s' = "s ++ map_of (effect_to_assignments a)"
+ {
+ from Cons.prems
+ have "are_all_operators_applicable ?s' ops"
+ and "are_all_operator_effects_consistent ops"
+ and "are_all_operators_non_interfering ops"
+ using execute_parallel_plan_precondition_cons
+ by blast+
+ then have "execute_serial_plan ?s' ops
+ = execute_parallel_operator ?s' ops"
+ using Cons.IH
+ by presburger
+ }
+ moreover from Cons.prems
+ have "execute_parallel_operator s (Cons a ops)
+ = execute_parallel_operator ?s' ops"
+ using execute_parallel_operator_cons_equals_corollary
+ unfolding execute_operator_def
+ by simp
+ moreover
+ from a have "execute_serial_plan s (Cons a ops)
+ = execute_serial_plan ?s' ops"
+ unfolding execute_serial_plan_def execute_operator_def
+ is_operator_applicable_in_def
+ by fastforce
+ ultimately show ?case
+ by argo
+ qed
+
+lemma execute_serial_plan_split_i:
+ assumes "are_all_operators_applicable s (op # \<pi>)"
+ and "are_all_operators_non_interfering (op # \<pi>)"
+ shows "are_all_operators_applicable (s \<then> op) \<pi>"
+ using assms
+ proof (induction \<pi> arbitrary: s)
+ case Nil
+ then show ?case
+ unfolding are_all_operators_applicable_def
+ by simp
+ next
+ case (Cons op' \<pi>)
+ let ?t = "s \<then> op"
+ {
+ fix x
+ assume "x \<in> set (op' # \<pi>)"
+ moreover have "op \<in> set (op # op' # \<pi>)"
+ by simp
+ moreover have "\<not>are_operators_interfering op x"
+ using Cons.prems(2) calculation(1)
+ unfolding are_all_operators_non_interfering_def list_all_iff
+ by fastforce
+ moreover have "is_operator_applicable_in s op"
+ using Cons.prems(1)
+ unfolding are_all_operators_applicable_def list_all_iff
+ is_operator_applicable_in_def
+ by force
+ moreover have "is_operator_applicable_in s x"
+ using are_all_operators_applicable_cons(2)[OF Cons.prems(1)] calculation(1)
+ unfolding are_all_operators_applicable_def list_all_iff
+ is_operator_applicable_in_def
+ by fast
+ ultimately have "is_operator_applicable_in ?t x"
+ using execute_parallel_plan_precondition_cons_i[of op x s]
+ by (auto simp: execute_operator_def)
+ }
+ thus ?case
+ using are_all_operators_applicable_cons(2)
+ unfolding is_operator_applicable_in_def
+ STRIPS_Representation.is_operator_applicable_in_def
+ are_all_operators_applicable_def list_all_iff
+ by simp
+ qed
+
+\<comment> \<open> Show that plans $\pi$ can be split into separate executions of partial plans $\pi_1$ and
+$\pi_2$ with $\pi = \pi_1 @ \pi_2$, if all operators in $\pi_1$ are applicable in the given state
+$s$ and there is no interference between subsequent operators in $\pi_1$. This is the case because
+non interference ensures that no precondition for any operator in $\pi_1$ is negated by the
+execution of a preceding operator. Note that the non interference constraint excludes partial
+plans where a precondition is first violated during execution but later restored which would also
+allow splitting but does not meet the non interference constraint (which must hold for all
+possible executing orders). \<close>
+lemma execute_serial_plan_split:
+ fixes s :: "('variable, bool) state"
+ assumes "are_all_operators_applicable s \<pi>\<^sub>1"
+ and "are_all_operators_non_interfering \<pi>\<^sub>1"
+ shows "execute_serial_plan s (\<pi>\<^sub>1 @ \<pi>\<^sub>2)
+ = execute_serial_plan (execute_serial_plan s \<pi>\<^sub>1) \<pi>\<^sub>2"
+ using assms
+ proof (induction \<pi>\<^sub>1 arbitrary: s)
+ case (Cons op \<pi>\<^sub>1)
+ let ?t = "s \<then> op"
+ {
+ have "are_all_operators_applicable (s \<then> op) \<pi>\<^sub>1"
+ using execute_serial_plan_split_i[OF Cons.prems(1, 2)].
+ moreover have "are_all_operators_non_interfering \<pi>\<^sub>1"
+ using are_all_operators_non_interfering_tail[OF Cons.prems(2)].
+ ultimately have "execute_serial_plan ?t (\<pi>\<^sub>1 @ \<pi>\<^sub>2) =
+ execute_serial_plan (execute_serial_plan ?t \<pi>\<^sub>1) \<pi>\<^sub>2"
+ using Cons.IH[of ?t]
+ by blast
+ }
+ moreover have "STRIPS_Representation.is_operator_applicable_in s op"
+ using Cons.prems(1)
+ unfolding are_all_operators_applicable_def list_all_iff
+ by fastforce
+ ultimately show ?case
+ unfolding execute_serial_plan_def
+ by simp
+ qed simp
+
+(* TODO refactor *)
+lemma embedding_lemma_i:
+ fixes I :: "('variable, bool) state"
+ assumes "is_operator_applicable_in I op"
+ and "are_operator_effects_consistent op op"
+ shows "I \<then> op = execute_parallel_operator I [op]"
+ proof -
+ have "are_all_operators_applicable I [op]"
+ using assms(1)
+ unfolding are_all_operators_applicable_def list_all_iff is_operator_applicable_in_def
+ by fastforce
+ moreover have "are_all_operator_effects_consistent [op]"
+ unfolding are_all_operator_effects_consistent_def list_all_iff
+ using assms(2)
+ by fastforce
+ moreover have "are_all_operators_non_interfering [op]"
+ by simp
+ moreover have "I \<then> op = execute_serial_plan I [op]"
+ using assms(1)
+ unfolding is_operator_applicable_in_def
+ by (simp add: assms(1) execute_operator_def)
+ ultimately show ?thesis
+ using execute_parallel_operator_equals_execute_sequential_strips_if
+ by force
+ qed
+
+lemma execute_serial_plan_is_execute_parallel_plan_ii:
+ fixes I :: "'variable strips_state"
+ assumes "\<forall>op \<in> set \<pi>. are_operator_effects_consistent op op"
+ and "G \<subseteq>\<^sub>m execute_serial_plan I \<pi>"
+ shows "G \<subseteq>\<^sub>m execute_parallel_plan I (embed \<pi>)"
+ proof -
+ show ?thesis
+ using assms
+ proof (induction \<pi> arbitrary: I)
+ case (Cons op \<pi>)
+ then show ?case
+ proof (cases "is_operator_applicable_in I op")
+ case True
+ let ?J = "I \<then> op"
+ and ?J' = "execute_parallel_operator I [op]"
+ {
+ have "G \<subseteq>\<^sub>m execute_serial_plan ?J \<pi>"
+ using Cons.prems(2) True
+ unfolding is_operator_applicable_in_def
+ by (simp add: True)
+ hence "G \<subseteq>\<^sub>m execute_parallel_plan ?J (embed \<pi>)"
+ using Cons.IH[of ?J] Cons.prems(1)
+ by fastforce
+ }
+ moreover {
+ have "are_all_operators_applicable I [op]"
+ using True
+ unfolding are_all_operators_applicable_def list_all_iff
+ is_operator_applicable_in_def
+ by fastforce
+ moreover have "are_all_operator_effects_consistent [op]"
+ unfolding are_all_operator_effects_consistent_def list_all_iff
+ using Cons.prems(1)
+ by fastforce
+ moreover have "?J = ?J'"
+ using execute_parallel_operator_equals_execute_sequential_strips_if[OF
+ calculation(1, 2)] Cons.prems(1) True
+ unfolding is_operator_applicable_in_def
+ by (simp add: True)
+ ultimately have "execute_parallel_plan I (embed (op # \<pi>))
+ = execute_parallel_plan ?J (embed \<pi>)"
+ by fastforce
+ }
+ ultimately show ?thesis
+ by presburger
+ next
+ case False
+ then have "G \<subseteq>\<^sub>m I"
+ using Cons.prems is_operator_applicable_in_def
+ by simp
+ moreover {
+ have "\<not>are_all_operators_applicable I [op]"
+ using False
+ unfolding are_all_operators_applicable_def list_all_iff
+ is_operator_applicable_in_def
+ by force
+ hence "execute_parallel_plan I (embed (op # \<pi>)) = I"
+ by simp
+ }
+ ultimately show ?thesis
+ by presburger
+ qed
+ qed simp
+ qed
+
+lemma embedding_lemma_iii:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "\<forall>op \<in> set \<pi>. op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ shows "\<forall>ops \<in> set (embed \<pi>). \<forall>op \<in> set ops. op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ proof -
+ (* TODO refactor *)
+ have nb: "set (embed \<pi>) = { [op] | op. op \<in> set \<pi> }"
+ by (induction \<pi>; force)
+ {
+ fix ops
+ assume "ops \<in> set (embed \<pi>)"
+ moreover obtain op where "op \<in> set \<pi>" and "ops = [op]"
+ using nb calculation
+ by blast
+ ultimately have "\<forall>op \<in> set ops. op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using assms(1)
+ by simp
+ }
+ thus ?thesis..
+ qed
+
+text \<open> We show in the following theorem that---as mentioned---a serial solution \<^term>\<open>\<pi>\<close> to a
+STRIPS problem \<^term>\<open>\<Pi>\<close> corresponds directly to a parallel solution obtained by embedding each operator
+in \<^term>\<open>\<pi>\<close> in a list (by use of function \<^term>\<open>embed\<close>). The proof shows this by first
+confirming that
+
+ @{text[display, indent=4] "G \<subseteq>\<^sub>m execute_serial_plan ((\<Pi>)\<^sub>I) \<pi>
+ \<Longrightarrow> G \<subseteq>\<^sub>m execute_serial_plan ((\<Pi>)\<^sub>I) (embed \<pi>)"}
+
+using lemma \isaname{execute_serial_plan_is_execute_parallel_plan_strip_ii}; and
+moreover by showing that
+
+ @{text[display, indent=4] "\<forall>ops \<in> set (embed \<pi>). \<forall>op \<in> set ops. op \<in> (\<Pi>)\<^sub>\<O>"}
+
+meaning that under the given assumptions, all parallel operators of the embedded serial plan are
+again operators in the operator set of the problem. \<close>
+theorem embedding_lemma:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "is_serial_solution_for_problem \<Pi> \<pi>"
+ shows "is_parallel_solution_for_problem \<Pi> (embed \<pi>)"
+ proof -
+ (* TODO refactor \<open>STRIPS_Representation\<close> (characterization of valid operator).
+ *)have nb\<^sub>1: "\<forall>op \<in> set \<pi>. op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using assms(2)
+ unfolding is_serial_solution_for_problem_def list_all_iff ListMem_iff operators_of_def
+ by blast
+ (* TODO refactor lemma is_valid_operator_strips_then
+ *) {
+ fix op
+ assume "op \<in> set \<pi>"
+ moreover have "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using nb\<^sub>1 calculation
+ by fast
+ moreover have "is_valid_operator_strips \<Pi> op"
+ using assms(1) calculation(2)
+ unfolding is_valid_problem_strips_def is_valid_problem_strips_def list_all_iff operators_of_def
+ by meson
+ moreover have "list_all (\<lambda>v. \<not>ListMem v (delete_effects_of op)) (add_effects_of op)"
+ and "list_all (\<lambda>v. \<not>ListMem v (add_effects_of op)) (delete_effects_of op)"
+ using calculation(3)
+ unfolding is_valid_operator_strips_def
+ by meson+
+ moreover have "\<not>list_ex (\<lambda>v. ListMem v (delete_effects_of op)) (add_effects_of op)"
+ and "\<not>list_ex (\<lambda>v. ListMem v (add_effects_of op)) (delete_effects_of op)"
+ using calculation(4, 5) not_list_ex_equals_list_all_not
+ by blast+
+ moreover have "\<not>list_ex (\<lambda>v. list_ex ((=) v) (delete_effects_of op)) (add_effects_of op)"
+ and "\<not>list_ex (\<lambda>v. list_ex ((=) v) (add_effects_of op)) (delete_effects_of op)"
+ using calculation(6, 7)
+ unfolding list_ex_iff ListMem_iff
+ by blast+
+ ultimately have "are_operator_effects_consistent op op"
+ unfolding are_operator_effects_consistent_def Let_def
+ by blast
+ } note nb\<^sub>2 = this
+ moreover {
+ have "(\<Pi>)\<^sub>G \<subseteq>\<^sub>m execute_serial_plan ((\<Pi>)\<^sub>I) \<pi>"
+ using assms(2)
+ unfolding is_serial_solution_for_problem_def
+ by simp
+ hence "(\<Pi>)\<^sub>G \<subseteq>\<^sub>m execute_parallel_plan ((\<Pi>)\<^sub>I) (embed \<pi>)"
+ using execute_serial_plan_is_execute_parallel_plan_ii nb\<^sub>2
+ by blast
+ }
+ moreover have "\<forall>ops \<in> set (embed \<pi>). \<forall>op \<in> set ops. op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using embedding_lemma_iii[OF nb\<^sub>1].
+ ultimately show ?thesis
+ unfolding is_parallel_solution_for_problem_def goal_of_def
+ initial_of_def operators_of_def list_all_iff ListMem_iff
+ by blast
+ qed
+
+lemma flattening_lemma_i:
+ fixes \<Pi>:: "'a strips_problem"
+ assumes "\<forall>ops \<in> set \<pi>. \<forall>op \<in> set ops. op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ shows "\<forall>op \<in> set (concat \<pi>). op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ proof -
+ {
+ fix op
+ assume "op \<in> set (concat \<pi>)"
+ moreover have "op \<in> (\<Union>ops \<in> set \<pi>. set ops)"
+ using calculation
+ unfolding set_concat.
+ then obtain ops where "ops \<in> set \<pi>" and "op \<in> set ops"
+ using UN_iff
+ by blast
+ ultimately have "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using assms
+ by blast
+ }
+ thus ?thesis..
+ qed
+
+lemma flattening_lemma_ii:
+ fixes I :: "'variable strips_state"
+ assumes "\<forall>ops \<in> set \<pi>. \<exists>op. ops = [op] \<and> is_valid_operator_strips \<Pi> op "
+ and "G \<subseteq>\<^sub>m execute_parallel_plan I \<pi>"
+ shows "G \<subseteq>\<^sub>m execute_serial_plan I (concat \<pi>)"
+ proof -
+ let ?\<pi>' = "concat \<pi>"
+ (* TODO refactor lemma is_valid_operator_strips_then *)
+ {
+ fix op
+ assume "is_valid_operator_strips \<Pi> op"
+ moreover have "list_all (\<lambda>v. \<not>ListMem v (delete_effects_of op)) (add_effects_of op)"
+ and "list_all (\<lambda>v. \<not>ListMem v (add_effects_of op)) (delete_effects_of op)"
+ using calculation(1)
+ unfolding is_valid_operator_strips_def
+ by meson+
+ moreover have "\<not>list_ex (\<lambda>v. ListMem v (delete_effects_of op)) (add_effects_of op)"
+ and "\<not>list_ex (\<lambda>v. ListMem v (add_effects_of op)) (delete_effects_of op)"
+ using calculation(2, 3) not_list_ex_equals_list_all_not
+ by blast+
+ moreover have "\<not>list_ex (\<lambda>v. list_ex ((=) v) (delete_effects_of op)) (add_effects_of op)"
+ and "\<not>list_ex (\<lambda>v. list_ex ((=) v) (add_effects_of op)) (delete_effects_of op)"
+ using calculation(4, 5)
+ unfolding list_ex_iff ListMem_iff
+ by blast+
+ ultimately have "are_operator_effects_consistent op op"
+ unfolding are_operator_effects_consistent_def Let_def
+ by blast
+ } note nb\<^sub>1 = this
+ show ?thesis
+ using assms
+ proof (induction \<pi> arbitrary: I)
+ case (Cons ops \<pi>)
+ obtain op where ops_is: "ops = [op]" and is_valid_op: "is_valid_operator_strips \<Pi> op"
+ using Cons.prems(1)
+ by fastforce
+ show ?case
+ proof (cases "are_all_operators_applicable I ops")
+ case True
+ let ?J = "execute_parallel_operator I [op]"
+ and ?J' = "I \<then> op"
+ have nb\<^sub>2: "is_operator_applicable_in I op"
+ using True ops_is
+ unfolding are_all_operators_applicable_def list_all_iff
+ is_operator_applicable_in_def
+ by simp
+ have nb\<^sub>3: "are_operator_effects_consistent op op"
+ using nb\<^sub>1[OF is_valid_op].
+ {
+ then have "are_all_operator_effects_consistent ops"
+ unfolding are_all_operator_effects_consistent_def list_all_iff
+ using ops_is
+ by fastforce
+ hence "G \<subseteq>\<^sub>m execute_parallel_plan ?J \<pi>"
+ using Cons.prems(2) ops_is True
+ by fastforce
+ }
+ moreover have "execute_serial_plan I (concat (ops # \<pi>))
+ = execute_serial_plan ?J' (concat \<pi>)"
+ using ops_is nb\<^sub>2
+ unfolding is_operator_applicable_in_def
+ by (simp add: execute_operator_def nb\<^sub>2)
+ moreover have "?J = ?J'"
+ unfolding execute_parallel_operator_def execute_operator_def comp_apply
+ by fastforce
+ ultimately show ?thesis
+ using Cons.IH Cons.prems
+ by force
+ next
+ case False
+ moreover have "G \<subseteq>\<^sub>m I"
+ using Cons.prems(2) calculation
+ by force
+ moreover {
+ have "\<not>is_operator_applicable_in I op"
+ using ops_is False
+ unfolding are_all_operators_applicable_def list_all_iff
+ is_operator_applicable_in_def
+ by fastforce
+ hence "execute_serial_plan I (concat (ops # \<pi>)) = I"
+ using ops_is is_operator_applicable_in_def
+ by simp
+ }
+ ultimately show ?thesis
+ by argo
+ qed
+ qed force
+ qed
+
+text \<open> The opposite direction is also easy to show if we can normalize the parallel plan to the
+form of an embedded serial plan as shown below. \<close>
+
+lemma flattening_lemma:
+ assumes "is_valid_problem_strips \<Pi>"
+ and "\<forall>ops \<in> set \<pi>. \<exists>op. ops = [op]"
+ and "is_parallel_solution_for_problem \<Pi> \<pi>"
+ shows "is_serial_solution_for_problem \<Pi> (concat \<pi>)"
+ proof -
+ let ?\<pi>' = "concat \<pi>"
+ {
+ have "\<forall>ops \<in> set \<pi>. \<forall>op \<in> set ops. op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using assms(3)
+ unfolding is_parallel_solution_for_problem_def list_all_iff ListMem_iff
+ by force
+ hence "\<forall>op \<in> set ?\<pi>'. op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using flattening_lemma_i
+ by blast
+ }
+ moreover {
+ {
+ fix ops
+ assume "ops \<in> set \<pi>"
+ moreover obtain op where "ops = [op]"
+ using assms(2) calculation
+ by blast
+ moreover have "op \<in> set ((\<Pi>)\<^sub>\<O>)"
+ using assms(3) calculation
+ unfolding is_parallel_solution_for_problem_def list_all_iff ListMem_iff
+ by force
+ moreover have "is_valid_operator_strips \<Pi> op"
+ using assms(1) calculation(3)
+ unfolding is_valid_problem_strips_def Let_def list_all_iff ListMem_iff
+ by simp
+ ultimately have "\<exists>op. ops = [op] \<and> is_valid_operator_strips \<Pi> op"
+ by blast
+ }
+ moreover have "(\<Pi>)\<^sub>G \<subseteq>\<^sub>m execute_parallel_plan ((\<Pi>)\<^sub>I) \<pi>"
+ using assms(3)
+ unfolding is_parallel_solution_for_problem_def
+ by simp
+ ultimately have "(\<Pi>)\<^sub>G \<subseteq>\<^sub>m execute_serial_plan ((\<Pi>)\<^sub>I) ?\<pi>'"
+ using flattening_lemma_ii
+ by blast
+ }
+ ultimately show "is_serial_solution_for_problem \<Pi> ?\<pi>'"
+ unfolding is_serial_solution_for_problem_def list_all_iff ListMem_iff
+ by simp
+ qed
+
+
+text \<open> Finally, we can obtain the important result that a parallel plan with a trace that
+reaches the goal state of a given problem \<^term>\<open>\<Pi>\<close>, and for which both the parallel operator execution
+condition as well as non interference is assured at every point \<^term>\<open>k < length \<pi>\<close>, the flattening of
+the parallel plan \<^term>\<open>concat \<pi>\<close> is a serial solution for the initial and goal state of the problem.
+To wit, by lemma \ref{isathm:parallel-solution-trace-strips} we have
+
+ @{text[display, indent=4] "(G \<subseteq>\<^sub>m execute_parallel_plan I \<pi>)
+ = (G \<subseteq>\<^sub>m last (trace_parallel_plan_strips I \<pi>))"}
+
+so the second assumption entails that \<^term>\<open>\<pi>\<close> is a solution for the initial state and the goal state
+of the problem. (which implicitely means that \<^term>\<open>\<pi>\<close> is a solution
+for the inital state and goal state of the problem). The trace formulation is used in this case
+because it allows us to write the---state dependent---applicability condition more succinctly. The
+proof (shown below) is by structural induction on \<^term>\<open>\<pi>\<close> with arbitrary initial state.\<close>
+
+(* TODO Demote to lemma; add theorem about problem solutions. Move text to theorem. *)
+theorem execute_parallel_plan_is_execute_sequential_plan_if:
+ fixes I :: "('variable, bool) state"
+ assumes "is_valid_problem \<Pi>"
+ and "G \<subseteq>\<^sub>m last (trace_parallel_plan_strips I \<pi>)"
+ and "\<forall>k < length \<pi>.
+ are_all_operators_applicable (trace_parallel_plan_strips I \<pi> ! k) (\<pi> ! k)
+ \<and> are_all_operator_effects_consistent (\<pi> ! k)
+ \<and> are_all_operators_non_interfering (\<pi> ! k)"
+ shows "G \<subseteq>\<^sub>m execute_serial_plan I (concat \<pi>)"
+ using assms
+ proof (induction \<pi> arbitrary: I)
+ case (Cons ops \<pi>)
+ let ?ops' = "take (length ops) (concat (ops # \<pi>))"
+ let ?J = "execute_parallel_operator I ops"
+ and ?J' = "execute_serial_plan I ?ops'"
+ {
+ have "trace_parallel_plan_strips I \<pi> ! 0 = I" and "(ops # \<pi>) ! 0 = ops"
+ unfolding trace_parallel_plan_strips_head_is_initial_state
+ by simp+
+ then have "are_all_operators_applicable I ops"
+ and "are_all_operator_effects_consistent ops"
+ and "are_all_operators_non_interfering ops"
+ using Cons.prems(3)
+ by auto+
+ then have "trace_parallel_plan_strips I (ops # \<pi>)
+ = I # trace_parallel_plan_strips ?J \<pi>"
+ by fastforce
+ } note nb = this
+ {
+ have "last (trace_parallel_plan_strips I (ops # \<pi>))
+ = last (trace_parallel_plan_strips ?J \<pi>)"
+ using trace_parallel_plan_strips_last_cons_then nb
+ by metis
+ hence "G \<subseteq>\<^sub>m last (trace_parallel_plan_strips ?J \<pi>)"
+ using Cons.prems(2)
+ by force
+ }
+ moreover {
+ fix k
+ assume "k < length \<pi>"
+ moreover have "k + 1 < length (ops # \<pi>)"
+ using calculation
+ by force
+ moreover have "\<pi> ! k = (ops # \<pi>) ! (k + 1)"
+ by simp
+ ultimately have "are_all_operators_applicable
+ (trace_parallel_plan_strips ?J \<pi> ! k) (\<pi> ! k)"
+ and "are_all_operator_effects_consistent (\<pi> ! k)"
+ and "are_all_operators_non_interfering (\<pi> ! k)"
+ using Cons.prems(3) nb
+ by force+
+ }
+ ultimately have "G \<subseteq>\<^sub>m execute_serial_plan ?J (concat \<pi>)"
+ using Cons.IH[OF Cons.prems(1), of ?J]
+ by blast
+ moreover {
+ have "execute_serial_plan I (concat (ops # \<pi>))
+ = execute_serial_plan ?J' (concat \<pi>)"
+ using execute_serial_plan_split[of I ops] Cons.prems(3)
+ by auto
+ thm execute_parallel_operator_equals_execute_sequential_strips_if[of I]
+ moreover have "?J = ?J'"
+ using execute_parallel_operator_equals_execute_sequential_strips_if Cons.prems(3)
+ by fastforce
+ ultimately have "execute_serial_plan I (concat (ops # \<pi>))
+ = execute_serial_plan ?J (concat \<pi>)"
+ using execute_serial_plan_split[of I ops] Cons.prems(3)
+ by argo
+ }
+ ultimately show ?case
+ by argo
+ qed force
+
+subsection "Auxiliary lemmas about STRIPS"
+
+lemma set_to_precondition_of_op_is[simp]: "set (to_precondition op)
+ = { (v, True) | v. v \<in> set (precondition_of op) }"
+ unfolding to_precondition_def STRIPS_Representation.to_precondition_def set_map
+ by blast
+
+
+end
diff --git a/thys/Verified_SAT_Based_AI_Planning/Set2_Join_RBT.thy b/thys/Verified_SAT_Based_AI_Planning/Set2_Join_RBT.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/Set2_Join_RBT.thy
@@ -0,0 +1,240 @@
+(*
+ Author: Tobias Nipkow
+*)
+
+(*
+ Author: Mohammad Abdulaziz, copied it from src/HOL/Data_Structures to extend the global interpretation
+*)
+(*<*)
+section "Join-Based Implementation of Sets via RBTs"
+
+theory Set2_Join_RBT
+imports
+ "HOL-Data_Structures.Set2_Join"
+ "HOL-Data_Structures.RBT_Set"
+begin
+
+subsection "Code"
+
+text \<open>
+Function \<open>joinL\<close> joins two trees (and an element).
+Precondition: \<^prop>\<open>bheight l \<le> bheight r\<close>.
+Method:
+Descend along the left spine of \<open>r\<close>
+until you find a subtree with the same \<open>bheight\<close> as \<open>l\<close>,
+then combine them into a new red node.
+\<close>
+fun joinL :: "'a rbt \<Rightarrow> 'a \<Rightarrow> 'a rbt \<Rightarrow> 'a rbt" where
+"joinL l x r =
+ (if bheight l \<ge> bheight r then R l x r
+ else case r of
+ B l' x' r' \<Rightarrow> baliL (joinL l x l') x' r' |
+ R l' x' r' \<Rightarrow> R (joinL l x l') x' r')"
+
+fun joinR :: "'a rbt \<Rightarrow> 'a \<Rightarrow> 'a rbt \<Rightarrow> 'a rbt" where
+"joinR l x r =
+ (if bheight l \<le> bheight r then R l x r
+ else case l of
+ B l' x' r' \<Rightarrow> baliR l' x' (joinR r' x r) |
+ R l' x' r' \<Rightarrow> R l' x' (joinR r' x r))"
+
+definition join :: "'a rbt \<Rightarrow> 'a \<Rightarrow> 'a rbt \<Rightarrow> 'a rbt" where
+"join l x r =
+ (if bheight l > bheight r
+ then paint Black (joinR l x r)
+ else if bheight l < bheight r
+ then paint Black (joinL l x r)
+ else B l x r)"
+
+declare joinL.simps[simp del]
+declare joinR.simps[simp del]
+
+
+subsection "Properties"
+
+subsubsection "Color and height invariants"
+
+lemma invc2_joinL:
+ "\<lbrakk> invc l; invc r; bheight l \<le> bheight r \<rbrakk> \<Longrightarrow>
+ invc2 (joinL l x r)
+ \<and> (bheight l \<noteq> bheight r \<and> color r = Black \<longrightarrow> invc(joinL l x r))"
+proof (induct l x r rule: joinL.induct)
+ case (1 l x r) thus ?case
+ by(auto simp: invc_baliL invc2I joinL.simps[of l x r] split!: tree.splits if_splits)
+qed
+
+lemma invc2_joinR:
+ "\<lbrakk> invc l; invh l; invc r; invh r; bheight l \<ge> bheight r \<rbrakk> \<Longrightarrow>
+ invc2 (joinR l x r)
+ \<and> (bheight l \<noteq> bheight r \<and> color l = Black \<longrightarrow> invc(joinR l x r))"
+proof (induct l x r rule: joinR.induct)
+ case (1 l x r) thus ?case
+ by(fastforce simp: invc_baliR invc2I joinR.simps[of l x r] split!: tree.splits if_splits)
+qed
+
+lemma bheight_joinL:
+ "\<lbrakk> invh l; invh r; bheight l \<le> bheight r \<rbrakk> \<Longrightarrow> bheight (joinL l x r) = bheight r"
+proof (induct l x r rule: joinL.induct)
+ case (1 l x r) thus ?case
+ by(auto simp: bheight_baliL joinL.simps[of l x r] split!: tree.split)
+qed
+
+lemma invh_joinL:
+ "\<lbrakk> invh l; invh r; bheight l \<le> bheight r \<rbrakk> \<Longrightarrow> invh (joinL l x r)"
+proof (induct l x r rule: joinL.induct)
+ case (1 l x r) thus ?case
+ by(auto simp: invh_baliL bheight_joinL joinL.simps[of l x r] split!: tree.split color.split)
+qed
+
+lemma bheight_baliR:
+ "bheight l = bheight r \<Longrightarrow> bheight (baliR l a r) = Suc (bheight l)"
+by (cases "(l,a,r)" rule: baliR.cases) auto
+
+lemma bheight_joinR:
+ "\<lbrakk> invh l; invh r; bheight l \<ge> bheight r \<rbrakk> \<Longrightarrow> bheight (joinR l x r) = bheight l"
+proof (induct l x r rule: joinR.induct)
+ case (1 l x r) thus ?case
+ by(fastforce simp: bheight_baliR joinR.simps[of l x r] split!: tree.split)
+qed
+
+lemma invh_joinR:
+ "\<lbrakk> invh l; invh r; bheight l \<ge> bheight r \<rbrakk> \<Longrightarrow> invh (joinR l x r)"
+proof (induct l x r rule: joinR.induct)
+ case (1 l x r) thus ?case
+ by(fastforce simp: invh_baliR bheight_joinR joinR.simps[of l x r]
+ split!: tree.split color.split)
+qed
+
+(* unused *)
+lemma rbt_join: "\<lbrakk> invc l; invh l; invc r; invh r \<rbrakk> \<Longrightarrow> rbt(join l x r)"
+by(simp add: invc2_joinL invc2_joinR invh_joinL invh_joinR invh_paint rbt_def
+ color_paint_Black join_def)
+
+text \<open>To make sure the the black height is not increased unnecessarily:\<close>
+
+lemma bheight_paint_Black: "bheight(paint Black t) \<le> bheight t + 1"
+by(cases t) auto
+
+lemma "\<lbrakk> rbt l; rbt r \<rbrakk> \<Longrightarrow> bheight(join l x r) \<le> max (bheight l) (bheight r) + 1"
+using bheight_paint_Black[of "joinL l x r"] bheight_paint_Black[of "joinR l x r"]
+ bheight_joinL[of l r x] bheight_joinR[of l r x]
+by(auto simp: max_def rbt_def join_def)
+
+
+subsubsection "Inorder properties"
+
+text "Currently unused. Instead \<^const>\<open>set_tree\<close> and \<^const>\<open>bst\<close> properties are proved directly."
+
+lemma inorder_joinL: "bheight l \<le> bheight r \<Longrightarrow> inorder(joinL l x r) = inorder l @ x # inorder r"
+proof(induction l x r rule: joinL.induct)
+ case (1 l x r)
+ thus ?case by(auto simp: inorder_baliL joinL.simps[of l x r] split!: tree.splits color.splits)
+qed
+
+lemma inorder_joinR:
+ "inorder(joinR l x r) = inorder l @ x # inorder r"
+proof(induction l x r rule: joinR.induct)
+ case (1 l x r)
+ thus ?case by (force simp: inorder_baliR joinR.simps[of l x r] split!: tree.splits color.splits)
+qed
+
+lemma "inorder(join l x r) = inorder l @ x # inorder r"
+by(auto simp: inorder_joinL inorder_joinR inorder_paint join_def
+ split!: tree.splits color.splits if_splits
+ dest!: arg_cong[where f = inorder])
+
+
+subsubsection "Set and bst properties"
+
+lemma set_baliL:
+ "set_tree(baliL l a r) = set_tree l \<union> {a} \<union> set_tree r"
+by(cases "(l,a,r)" rule: baliL.cases) (auto)
+
+lemma set_joinL:
+ "bheight l \<le> bheight r \<Longrightarrow> set_tree (joinL l x r) = set_tree l \<union> {x} \<union> set_tree r"
+proof(induction l x r rule: joinL.induct)
+ case (1 l x r)
+ thus ?case by(auto simp: set_baliL joinL.simps[of l x r] split!: tree.splits color.splits)
+qed
+
+lemma set_baliR:
+ "set_tree(baliR l a r) = set_tree l \<union> {a} \<union> set_tree r"
+by(cases "(l,a,r)" rule: baliR.cases) (auto)
+
+lemma set_joinR:
+ "set_tree (joinR l x r) = set_tree l \<union> {x} \<union> set_tree r"
+proof(induction l x r rule: joinR.induct)
+ case (1 l x r)
+ thus ?case by(force simp: set_baliR joinR.simps[of l x r] split!: tree.splits color.splits)
+qed
+
+lemma set_paint: "set_tree (paint c t) = set_tree t"
+by (cases t) auto
+
+lemma set_join: "set_tree (join l x r) = set_tree l \<union> {x} \<union> set_tree r"
+by(simp add: set_joinL set_joinR set_paint join_def)
+
+lemma bst_baliL:
+ "\<lbrakk>bst l; bst r; \<forall>x\<in>set_tree l. x < a; \<forall>x\<in>set_tree r. a < x\<rbrakk>
+ \<Longrightarrow> bst (baliL l a r)"
+by(cases "(l,a,r)" rule: baliL.cases) (auto simp: ball_Un)
+
+lemma bst_baliR:
+ "\<lbrakk>bst l; bst r; \<forall>x\<in>set_tree l. x < a; \<forall>x\<in>set_tree r. a < x\<rbrakk>
+ \<Longrightarrow> bst (baliR l a r)"
+by(cases "(l,a,r)" rule: baliR.cases) (auto simp: ball_Un)
+
+lemma bst_joinL:
+ "\<lbrakk>bst (Node l (a, n) r); bheight l \<le> bheight r\<rbrakk>
+ \<Longrightarrow> bst (joinL l a r)"
+proof(induction l a r rule: joinL.induct)
+ case (1 l a r)
+ thus ?case
+ by(auto simp: set_baliL joinL.simps[of l a r] set_joinL ball_Un intro!: bst_baliL
+ split!: tree.splits color.splits)
+qed
+
+lemma bst_joinR:
+ "\<lbrakk>bst l; bst r; \<forall>x\<in>set_tree l. x < a; \<forall>y\<in>set_tree r. a < y \<rbrakk>
+ \<Longrightarrow> bst (joinR l a r)"
+proof(induction l a r rule: joinR.induct)
+ case (1 l a r)
+ thus ?case
+ by(auto simp: set_baliR joinR.simps[of l a r] set_joinR ball_Un intro!: bst_baliR
+ split!: tree.splits color.splits)
+qed
+
+lemma bst_paint: "bst (paint c t) = bst t"
+by(cases t) auto
+
+lemma bst_join:
+ "bst (Node l (a, n) r) \<Longrightarrow> bst (join l a r)"
+by(auto simp: bst_paint bst_joinL bst_joinR join_def)
+
+lemma inv_join: "\<lbrakk> invc l; invh l; invc r; invh r \<rbrakk> \<Longrightarrow> invc(join l x r) \<and> invh(join l x r)"
+by (simp add: invc2_joinL invc2_joinR invh_joinL invh_joinR invh_paint join_def)
+
+subsubsection "Interpretation of \<^locale>\<open>Set2_Join\<close> with Red-Black Tree"
+
+global_interpretation RBT: Set2_Join
+where join = join and inv = "\<lambda>t. invc t \<and> invh t"
+defines insert_rbt = RBT.insert and delete_rbt = RBT.delete and split_rbt = RBT.split
+and join2_rbt = RBT.join2 and split_min_rbt = RBT.split_min and inter_rbt = RBT.inter
+proof (standard, goal_cases)
+ case 1 show ?case by (rule set_join)
+next
+ case 2 thus ?case by (simp add: bst_join)
+next
+ case 3 show ?case by simp
+next
+ case 4 thus ?case by (simp add: inv_join)
+next
+ case 5 thus ?case by simp
+qed
+
+text \<open>The invariant does not guarantee that the root node is black. This is not required
+to guarantee that the height is logarithmic in the size --- Exercise.\<close>
+
+end
+
+(*>*)
\ No newline at end of file
diff --git a/thys/Verified_SAT_Based_AI_Planning/Solve_SASP.thy b/thys/Verified_SAT_Based_AI_Planning/Solve_SASP.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/Solve_SASP.thy
@@ -0,0 +1,862 @@
+(*
+ Author: Mohammad Abdulaziz
+*)
+
+theory Solve_SASP
+ imports AST_SAS_Plus_Equivalence "SAT_Solve_SAS_Plus"
+ "HOL-Data_Structures.RBT_Map" "HOL-Library.Code_Target_Nat" HOL.String
+ AI_Planning_Languages_Semantics.SASP_Checker Set2_Join_RBT
+begin
+
+subsection \<open>SAT encoding works for Fast-Downward's representation\<close>
+
+context abs_ast_prob
+begin
+
+theorem is_serial_sol_then_valid_plan_encoded:
+ "\<A> \<Turnstile> \<Phi>\<^sub>\<forall> (\<phi> (prob_with_noop abs_prob)) t \<Longrightarrow>
+ valid_plan
+ (decode_abs_plan
+ (rem_noops
+ (map (\<lambda>op. \<phi>\<^sub>O\<inverse> (prob_with_noop abs_prob) op)
+ (concat (\<Phi>\<inverse> (\<phi> (prob_with_noop abs_prob)) \<A> t)))))"
+ by (fastforce intro!: is_serial_sol_then_valid_plan abs_prob_valid
+ sas_plus_problem_has_serial_solution_iff_i')
+
+lemma length_abs_ast_plan: "length \<pi>s = length (abs_ast_plan \<pi>s)"
+ by (auto simp: abs_ast_plan_def)
+
+theorem valid_plan_then_is_serial_sol_encoded:
+ "valid_plan \<pi>s \<Longrightarrow> length \<pi>s \<le> h \<Longrightarrow> \<exists>\<A>. \<A> \<Turnstile> \<Phi>\<^sub>\<forall> (\<phi> (prob_with_noop abs_prob)) h"
+ apply(subst (asm) length_abs_ast_plan)
+ by (fastforce intro!: sas_plus_problem_has_serial_solution_iff_ii' abs_prob_valid
+ valid_plan_then_is_serial_sol)
+end
+
+section \<open>DIMACS-like semantics for CNF formulae\<close>
+
+text \<open>We now push the SAT encoding towards a lower-level representation by replacing the atoms which
+ have variable IDs and time steps into natural numbers.\<close>
+
+lemma gtD: "((l::nat) < n) \<Longrightarrow> (\<exists>m. n = Suc m \<and> l \<le> m)"
+ by (induction n) auto
+
+locale cnf_to_dimacs =
+ fixes h :: nat and n_ops :: nat
+begin
+
+fun var_to_dimacs where
+ "var_to_dimacs (Operator t k) = 1 + t + k * h"
+| "var_to_dimacs (State t k) = 1 + n_ops * h + t + k * (h)"
+
+definition dimacs_to_var where
+ "dimacs_to_var v \<equiv>
+ if v < 1 + n_ops * h then
+ Operator ((v - 1) mod (h)) ((v - 1) div (h))
+ else
+ (let k = ((v - 1) - n_ops * h) in
+ State (k mod (h)) (k div (h)))"
+
+fun valid_state_var where
+ "valid_state_var (Operator t k) \<longleftrightarrow> t < h \<and> k < n_ops"
+| "valid_state_var (State t k) \<longleftrightarrow> t < h"
+
+lemma State_works:
+"valid_state_var (State t k) \<Longrightarrow>
+ dimacs_to_var (var_to_dimacs (State t k)) =
+ (State t k)"
+ by (induction k) (auto simp add: dimacs_to_var_def add.left_commute Let_def)
+
+lemma Operator_works:
+ "valid_state_var (Operator t k) \<Longrightarrow>
+ dimacs_to_var (var_to_dimacs (Operator t k)) =
+ (Operator t k)"
+ by (induction k) (auto simp add: algebra_simps dimacs_to_var_def gr0_conv_Suc nat_le_iff_add dest!: gtD)
+
+lemma sat_plan_to_dimacs_works:
+ "valid_state_var sv \<Longrightarrow>
+ dimacs_to_var (var_to_dimacs sv) = sv"
+ apply(cases sv)
+ using State_works Operator_works
+ by auto
+
+end
+
+lemma changing_atoms_works:
+ "(\<And>x. P x \<Longrightarrow> (f o g) x = x) \<Longrightarrow> (\<forall>x\<in>atoms phi. P x) \<Longrightarrow> M \<Turnstile> phi \<longleftrightarrow> M o f \<Turnstile> map_formula g phi"
+ by (induction phi) auto
+
+lemma changing_atoms_works':
+ "M o g \<Turnstile> phi \<longleftrightarrow> M \<Turnstile> map_formula g phi"
+ by (induction phi) auto
+
+context cnf_to_dimacs
+begin
+
+lemma sat_plan_to_dimacs:
+ "(\<And>sv. sv\<in>atoms sat_plan_formula \<Longrightarrow> valid_state_var sv) \<Longrightarrow>
+ M \<Turnstile> sat_plan_formula
+ \<longleftrightarrow> M o dimacs_to_var \<Turnstile> map_formula var_to_dimacs sat_plan_formula"
+ by(auto intro!: changing_atoms_works[where P = valid_state_var] simp: sat_plan_to_dimacs_works)
+
+lemma dimacs_to_sat_plan:
+ "M o var_to_dimacs \<Turnstile> sat_plan_formula
+ \<longleftrightarrow> M \<Turnstile> map_formula var_to_dimacs sat_plan_formula"
+ using changing_atoms_works' .
+
+end
+
+locale sat_solve_sasp = abs_ast_prob "\<Pi>" + cnf_to_dimacs "Suc h" "Suc (length ast\<delta>)"
+ for \<Pi> h
+begin
+
+lemma encode_initial_state_valid:
+ "sv \<in> atoms (encode_initial_state Prob) \<Longrightarrow> valid_state_var sv"
+ by (auto simp add: encode_state_variable_def Let_def encode_initial_state_def split: sat_plan_variable.splits bool.splits)
+
+lemma length_operators: "length (operators_of (\<phi> (prob_with_noop abs_prob))) = Suc (length ast\<delta>)"
+ by(simp add: abs_prob_def abs_ast_operator_section_def sas_plus_problem_to_strips_problem_def prob_with_noop_def)
+
+lemma encode_operator_effect_valid_1: "t < h \<Longrightarrow> op \<in> set (operators_of (\<phi> (prob_with_noop abs_prob))) \<Longrightarrow>
+ sv \<in> atoms
+ (\<^bold>\<And>(map (\<lambda>v.
+ \<^bold>\<not>(Atom (Operator t (index (operators_of (\<phi> (prob_with_noop abs_prob))) op)))
+ \<^bold>\<or> Atom (State (Suc t) (index vs v)))
+ asses)) \<Longrightarrow>
+ valid_state_var sv"
+ using length_operators
+ by (induction asses) (auto simp: simp add: cnf_to_dimacs.valid_state_var.simps)
+
+
+lemma encode_operator_effect_valid_2: "t < h \<Longrightarrow> op \<in> set (operators_of (\<phi> (prob_with_noop abs_prob))) \<Longrightarrow>
+ sv \<in> atoms
+ (\<^bold>\<And>(map (\<lambda>v.
+ \<^bold>\<not>(Atom (Operator t (index (operators_of (\<phi> (prob_with_noop abs_prob))) op)))
+ \<^bold>\<or> \<^bold>\<not> (Atom (State (Suc t) (index vs v))))
+ asses)) \<Longrightarrow>
+ valid_state_var sv"
+ using length_operators
+ by (induction asses) (auto simp: simp add: cnf_to_dimacs.valid_state_var.simps)
+
+end
+
+lemma atoms_And_append: "atoms (\<^bold>\<And> (as1 @ as2)) = atoms (\<^bold>\<And> as1) \<union> atoms (\<^bold>\<And> as2)"
+ by (induction as1) auto
+
+context sat_solve_sasp
+begin
+
+lemma encode_operator_effect_valid:
+ "sv \<in> atoms (encode_operator_effect (\<phi> (prob_with_noop abs_prob)) t op) \<Longrightarrow>
+ t < h \<Longrightarrow> op \<in> set (operators_of (\<phi> (prob_with_noop abs_prob))) \<Longrightarrow>
+ valid_state_var sv"
+ by (force simp: encode_operator_effect_def Let_def atoms_And_append
+ intro!: encode_operator_effect_valid_1 encode_operator_effect_valid_2)
+
+end
+
+lemma foldr_And: "foldr (\<^bold>\<and>) as (\<^bold>\<not> \<bottom>) = (\<^bold>\<And> as)"
+ by (induction as) auto
+
+context sat_solve_sasp
+begin
+
+lemma encode_all_operator_effects_valid:
+ "t < Suc h \<Longrightarrow>
+ sv \<in> atoms (encode_all_operator_effects (\<phi> (prob_with_noop abs_prob)) (operators_of (\<phi> (prob_with_noop abs_prob))) t) \<Longrightarrow>
+ valid_state_var sv"
+ unfolding encode_all_operator_effects_def foldr_And
+ by (force simp add: encode_operator_effect_valid)
+
+lemma encode_operator_precondition_valid_1:
+ "t < h \<Longrightarrow> op \<in> set (operators_of (\<phi> (prob_with_noop abs_prob))) \<Longrightarrow>
+ sv \<in> atoms
+ (\<^bold>\<And>(map (\<lambda>v.
+ \<^bold>\<not> (Atom (Operator t (index (operators_of (\<phi> (prob_with_noop abs_prob))) op))) \<^bold>\<or> Atom (State t (f v)))
+ asses)) \<Longrightarrow>
+ valid_state_var sv"
+ using length_operators
+ by (induction asses) (auto simp: simp add: cnf_to_dimacs.valid_state_var.simps)
+
+lemma encode_operator_precondition_valid:
+ "sv \<in> atoms (encode_operator_precondition (\<phi> (prob_with_noop abs_prob)) t op) \<Longrightarrow>
+ t < h \<Longrightarrow> op \<in> set (operators_of (\<phi> (prob_with_noop abs_prob))) \<Longrightarrow>
+ valid_state_var sv"
+ by (force simp: encode_operator_precondition_def Let_def
+ intro!: encode_operator_precondition_valid_1)
+
+lemma encode_all_operator_preconditions_valid:
+ "t < Suc h \<Longrightarrow>
+ sv \<in> atoms (encode_all_operator_preconditions (\<phi> (prob_with_noop abs_prob)) (operators_of (\<phi> (prob_with_noop abs_prob))) t) \<Longrightarrow>
+ valid_state_var sv"
+ unfolding encode_all_operator_preconditions_def foldr_And
+ by (force simp add: encode_operator_precondition_valid)
+
+lemma encode_operators_valid:
+ "sv \<in> atoms (encode_operators (\<phi> (prob_with_noop abs_prob)) t) \<Longrightarrow> t < Suc h \<Longrightarrow>
+ valid_state_var sv"
+ unfolding encode_operators_def Let_def
+ by (force simp add: encode_all_operator_preconditions_valid encode_all_operator_effects_valid)
+
+lemma encode_negative_transition_frame_axiom':
+ "t < h \<Longrightarrow>
+ set deleting_operators \<subseteq> set (operators_of (\<phi> (prob_with_noop abs_prob))) \<Longrightarrow>
+ sv \<in> atoms
+ (\<^bold>\<not>(Atom (State t v_idx))
+ \<^bold>\<or> (Atom (State (Suc t) v_idx)
+ \<^bold>\<or> \<^bold>\<Or> (map (\<lambda>op. Atom (Operator t (index (operators_of (\<phi> (prob_with_noop abs_prob))) op)))
+ deleting_operators))) \<Longrightarrow>
+ valid_state_var sv"
+ by (induction deleting_operators) (auto simp: length_operators[symmetric] cnf_to_dimacs.valid_state_var.simps)
+
+lemma encode_negative_transition_frame_axiom_valid:
+ "sv \<in> atoms (encode_negative_transition_frame_axiom (\<phi> (prob_with_noop abs_prob)) t v) \<Longrightarrow> t < h \<Longrightarrow>
+ valid_state_var sv"
+ unfolding encode_negative_transition_frame_axiom_def Let_def
+ apply(intro encode_negative_transition_frame_axiom'[of t])
+ by auto
+
+lemma encode_positive_transition_frame_axiom_valid:
+ "sv \<in> atoms (encode_positive_transition_frame_axiom (\<phi> (prob_with_noop abs_prob)) t v) \<Longrightarrow> t < h \<Longrightarrow>
+ valid_state_var sv"
+ unfolding encode_positive_transition_frame_axiom_def Let_def
+ apply(intro encode_negative_transition_frame_axiom'[of t])
+ by auto
+
+lemma encode_all_frame_axioms_valid:
+ "sv \<in> atoms (encode_all_frame_axioms (\<phi> (prob_with_noop abs_prob)) t) \<Longrightarrow> t < Suc h \<Longrightarrow>
+ valid_state_var sv"
+ unfolding encode_all_frame_axioms_def Let_def atoms_And_append
+ by (force simp add: encode_negative_transition_frame_axiom_valid encode_positive_transition_frame_axiom_valid)
+
+lemma encode_goal_state_valid:
+ "sv \<in> atoms (encode_goal_state Prob t) \<Longrightarrow> t < Suc h \<Longrightarrow> valid_state_var sv"
+ by (auto simp add: encode_state_variable_def Let_def encode_goal_state_def split: sat_plan_variable.splits bool.splits)
+
+lemma encode_problem_valid:
+ "sv \<in> atoms (encode_problem (\<phi> (prob_with_noop abs_prob)) h) \<Longrightarrow> valid_state_var sv"
+ unfolding encode_problem_def
+ using encode_initial_state_valid encode_operators_valid encode_all_frame_axioms_valid encode_goal_state_valid
+ by fastforce
+
+lemma encode_interfering_operator_pair_exclusion_valid:
+ "sv \<in> atoms (encode_interfering_operator_pair_exclusion (\<phi> (prob_with_noop abs_prob)) t op\<^sub>1 op\<^sub>2) \<Longrightarrow> t < Suc h \<Longrightarrow>
+ op\<^sub>1 \<in> set (operators_of (\<phi> (prob_with_noop abs_prob))) \<Longrightarrow> op\<^sub>2 \<in> set (operators_of (\<phi> (prob_with_noop abs_prob))) \<Longrightarrow>
+ valid_state_var sv"
+ by (auto simp: encode_interfering_operator_pair_exclusion_def Let_def length_operators[symmetric] cnf_to_dimacs.valid_state_var.simps)
+
+lemma encode_interfering_operator_exclusion_valid:
+ "sv \<in> atoms (encode_interfering_operator_exclusion (\<phi> (prob_with_noop abs_prob)) t) \<Longrightarrow> t < Suc h \<Longrightarrow>
+ valid_state_var sv"
+ unfolding encode_interfering_operator_exclusion_def Let_def foldr_And
+ by (force simp add: encode_interfering_operator_pair_exclusion_valid)
+
+lemma encode_problem_with_operator_interference_exclusion_valid:
+ "sv \<in> atoms (encode_problem_with_operator_interference_exclusion (\<phi> (prob_with_noop abs_prob)) h) \<Longrightarrow> valid_state_var sv"
+ unfolding encode_problem_with_operator_interference_exclusion_def
+ using encode_initial_state_valid encode_operators_valid encode_all_frame_axioms_valid encode_goal_state_valid
+ encode_interfering_operator_exclusion_valid
+ by fastforce
+
+lemma planning_by_cnf_dimacs_complete:
+ "valid_plan \<pi>s \<Longrightarrow> length \<pi>s \<le> h \<Longrightarrow>
+ \<exists>M. M \<Turnstile> map_formula var_to_dimacs (\<Phi>\<^sub>\<forall> (\<phi> (prob_with_noop abs_prob)) h)"
+ using valid_plan_then_is_serial_sol_encoded
+ sat_plan_to_dimacs[OF encode_problem_with_operator_interference_exclusion_valid]
+ by meson
+
+lemma planning_by_cnf_dimacs_sound:
+ "\<A> \<Turnstile> map_formula var_to_dimacs (\<Phi>\<^sub>\<forall> (\<phi> (prob_with_noop abs_prob)) t) \<Longrightarrow>
+ valid_plan
+ (decode_abs_plan
+ (rem_noops
+ (map (\<lambda>op. \<phi>\<^sub>O\<inverse> (prob_with_noop abs_prob) op)
+ (concat (\<Phi>\<inverse> (\<phi> (prob_with_noop abs_prob)) (\<A> o var_to_dimacs) t)))))"
+ using changing_atoms_works'
+ by (fastforce intro!: is_serial_sol_then_valid_plan_encoded)
+
+end
+
+subsection \<open>Going from Formualae to DIMACS-like CNF\<close>
+
+text \<open>We now represent the CNF formulae into a very low-level representation that is reminiscent to
+ the DIMACS representation, where a CNF formula is a list of list of integers.\<close>
+
+fun disj_to_dimacs::"nat formula \<Rightarrow> int list" where
+ "disj_to_dimacs (\<phi>\<^sub>1 \<^bold>\<or> \<phi>\<^sub>2) = disj_to_dimacs \<phi>\<^sub>1 @ disj_to_dimacs \<phi>\<^sub>2"
+| "disj_to_dimacs \<bottom> = []"
+| "disj_to_dimacs (Not \<bottom>) = [-1::int,1::int]"
+| "disj_to_dimacs (Atom v) = [int v]"
+| "disj_to_dimacs (Not (Atom v)) = [-(int v)]"
+
+fun cnf_to_dimacs::"nat formula \<Rightarrow> int list list" where
+ "cnf_to_dimacs (\<phi>\<^sub>1 \<^bold>\<and> \<phi>\<^sub>2) = cnf_to_dimacs \<phi>\<^sub>1 @ cnf_to_dimacs \<phi>\<^sub>2"
+| "cnf_to_dimacs d = [disj_to_dimacs d]"
+
+definition "dimacs_lit_to_var l \<equiv> nat (abs l)"
+
+definition "find_max (xs::nat list)\<equiv> (fold max xs 1)"
+
+lemma find_max_works:
+"x \<in> set xs \<Longrightarrow> x \<le> find_max xs" (is "?P \<Longrightarrow> ?Q")
+proof-
+ have "x \<in> set xs \<Longrightarrow> (x::nat) \<le> (fold max xs m)" for m
+ unfolding max_def
+ apply (induction xs arbitrary: m rule: rev_induct)
+ using nat_le_linear
+ by (auto dest: le_trans simp add:)
+ thus "?P \<Longrightarrow> ?Q"
+ by(auto simp add: find_max_def max_def)
+qed
+
+fun formula_vars where
+"formula_vars (\<bottom>) = []" |
+"formula_vars (Atom k) = [k]" |
+"formula_vars (Not F) = formula_vars F" |
+"formula_vars (And F G) = formula_vars F @ formula_vars G" |
+"formula_vars (Imp F G) = formula_vars F @ formula_vars G" |
+"formula_vars (Or F G) = formula_vars F @ formula_vars G"
+
+lemma atoms_formula_vars: "atoms f = set (formula_vars f)"
+ by (induction f) auto
+
+lemma max_var: "v \<in> atoms (f::nat formula) \<Longrightarrow> v \<le> find_max (formula_vars f)"
+ using find_max_works
+ by(simp add: atoms_formula_vars)
+
+definition "dimacs_max_var cs \<equiv> find_max (map (find_max o (map (nat o abs))) cs)"
+
+lemma fold_max_ge: "b \<le> a \<Longrightarrow> (b::nat) \<le> fold (\<lambda>x m. if m \<le> x then x else m) ys a"
+ by (induction ys arbitrary: a b) auto
+
+lemma find_max_append: "find_max (xs @ ys) = max (find_max xs) (find_max ys) "
+ apply(simp only: Max.set_eq_fold[symmetric] append_Cons[symmetric] set_append find_max_def)
+ by (metis List.finite_set Max.union Un_absorb Un_insert_left Un_insert_right list.distinct(1) list.simps(15) set_empty)
+
+definition dimacs_model::"int list \<Rightarrow> int list list \<Rightarrow> bool" where
+ "dimacs_model ls cs \<equiv> (\<forall>c\<in>set cs. (\<exists>l\<in>set ls. l \<in> set c)) \<and>
+ distinct (map dimacs_lit_to_var ls)"
+
+fun model_to_dimacs_model where
+ "model_to_dimacs_model M (v#vs) = (if M v then int v else - (int v)) # (model_to_dimacs_model M vs)"
+| "model_to_dimacs_model _ [] = []"
+
+lemma model_to_dimacs_model_append:
+ "set (model_to_dimacs_model M (vs @ vs')) = set (model_to_dimacs_model M vs) \<union> set (model_to_dimacs_model M vs')"
+ by (induction vs) auto
+
+lemma upt_append_sing: "xs @ [x] = [a..<n_vars] \<Longrightarrow> a < n_vars \<Longrightarrow> (xs = [a..<n_vars - 1] \<and> x = n_vars-1 \<and> n_vars > 0)"
+ by (induction "n_vars") auto
+
+lemma upt_eqD: "upt a b = upt a b' \<Longrightarrow> (b = b' \<or> b' \<le> a \<or> b \<le> a)"
+ by (induction b) (auto dest!: upt_append_sing split: if_splits)
+
+lemma pos_in_model: "M n \<Longrightarrow> 0 < n \<Longrightarrow> n < n_vars \<Longrightarrow> int n \<in> set (model_to_dimacs_model M [1..<n_vars])"
+ by (induction n_vars) (auto simp add: less_Suc_eq model_to_dimacs_model_append )
+
+lemma neg_in_model: "\<not> M n \<Longrightarrow> 0 < n \<Longrightarrow> n < n_vars \<Longrightarrow> - (int n) \<in> set (model_to_dimacs_model M [1..<n_vars])"
+ by (induction n_vars) (auto simp add: less_Suc_eq model_to_dimacs_model_append)
+
+lemma in_model: "0 < n \<Longrightarrow> n < n_vars \<Longrightarrow> int n \<in> set (model_to_dimacs_model M [1..<n_vars]) \<or> - (int n) \<in> set (model_to_dimacs_model M [1..<n_vars])"
+ using pos_in_model neg_in_model
+ by metis
+
+lemma model_to_dimacs_model_all_vars:
+ "(\<forall>v\<in>atoms f. 0 < v \<and> v < n_vars) \<Longrightarrow> is_cnf f \<Longrightarrow> M \<Turnstile> f \<Longrightarrow>
+ (\<forall>n<n_vars. 0 < n \<longrightarrow> (int n \<in> set (model_to_dimacs_model M [(1::nat)..<n_vars]) \<or>
+ -(int n) \<in> set (model_to_dimacs_model M [(1::nat)..<n_vars])))"
+ using in_model neg_in_model pos_in_model
+ by (auto simp add: le_less model_to_dimacs_model_append split: if_splits)
+
+lemma cnf_And: "set (cnf_to_dimacs (f1 \<^bold>\<and> f2)) = set (cnf_to_dimacs f1) \<union> set (cnf_to_dimacs f2)"
+ by auto
+
+lemma one_always_in:
+ "1 < n_vars \<Longrightarrow> 1 \<in> set (model_to_dimacs_model M ([1..<n_vars])) \<or> - 1 \<in> set (model_to_dimacs_model M ([1..<n_vars]))"
+ by (induction n_vars) (auto simp add: less_Suc_eq model_to_dimacs_model_append)
+
+lemma [simp]: "(disj_to_dimacs (f1 \<^bold>\<or> f2)) = (disj_to_dimacs f1) @ (disj_to_dimacs f2)"
+ by auto
+
+lemma [simp]: "(atoms (f1 \<^bold>\<or> f2)) = atoms f1 \<union> atoms f2"
+ by auto
+
+lemma isdisj_disjD: "(is_disj (f1 \<^bold>\<or> f2)) \<Longrightarrow> is_disj f1 \<and> is_disj f2"
+ by (cases f1; auto)
+
+lemma disj_to_dimacs_sound:
+ "1 < n_vars \<Longrightarrow> (\<forall>v\<in>atoms f. 0 < v \<and> v < n_vars) \<Longrightarrow> is_disj f \<Longrightarrow> M \<Turnstile> f
+ \<Longrightarrow> \<exists>l\<in>set (model_to_dimacs_model M [(1::nat)..<n_vars]). l \<in> set (disj_to_dimacs f)"
+ apply(induction f)
+ using neg_in_model pos_in_model one_always_in
+ by (fastforce elim!: is_lit_plus.elims dest!: isdisj_disjD)+
+
+lemma is_cnf_disj: "is_cnf (f1 \<^bold>\<or> f2) \<Longrightarrow> (\<And>f. f1 \<^bold>\<or> f2 = f \<Longrightarrow> is_disj f \<Longrightarrow> P) \<Longrightarrow> P"
+ by auto
+
+lemma cnf_to_dimacs_disj: "is_disj f \<Longrightarrow> cnf_to_dimacs f = [disj_to_dimacs f]"
+ by (induction f) auto
+
+lemma model_to_dimacs_model_all_clauses:
+ "1 < n_vars \<Longrightarrow> (\<forall>v\<in>atoms f. 0 < v \<and> v < n_vars) \<Longrightarrow> is_cnf f \<Longrightarrow> M \<Turnstile> f \<Longrightarrow>
+ c\<in>set (cnf_to_dimacs f) \<Longrightarrow> \<exists>l\<in>set (model_to_dimacs_model M [(1::nat)..<n_vars]). l \<in> set c"
+proof(induction f arbitrary: )
+ case (Not f)
+ then show ?case
+ using in_model neg_in_model
+ by (fastforce elim!: is_lit_plus.elims)+
+next
+ case (Or f1 f2)
+ then show ?case
+ using cnf_to_dimacs_disj disj_to_dimacs_sound
+ by(elim is_cnf_disj, simp)
+qed (insert in_model neg_in_model pos_in_model, auto)
+
+lemma upt_eq_Cons_conv:
+ "(x#xs = [i..<j]) = (i < j \<and> i = x \<and> [i+1..<j] = xs)"
+ using upt_eq_Cons_conv
+ by metis
+
+lemma model_to_dimacs_model_append':
+ "(model_to_dimacs_model M (vs @ vs')) = (model_to_dimacs_model M vs) @ (model_to_dimacs_model M vs')"
+ by (induction vs) auto
+
+lemma model_to_dimacs_neg_nin:
+ "n_vars \<le> x \<Longrightarrow> int x \<notin> set (model_to_dimacs_model M [a..<n_vars])"
+ by (induction n_vars arbitrary: a) (auto simp: model_to_dimacs_model_append')
+
+lemma model_to_dimacs_pos_nin:
+ "n_vars \<le> x \<Longrightarrow> - int x \<notin> set (model_to_dimacs_model M [a..<n_vars])"
+ by (induction n_vars arbitrary: a) (auto simp: model_to_dimacs_model_append')
+
+lemma int_cases2':
+ "z \<noteq> 0 \<Longrightarrow> (\<And>n. 0 \<noteq> (int n) \<Longrightarrow> z = int n \<Longrightarrow> P) \<Longrightarrow> (\<And>n. 0 \<noteq> - (int n) \<Longrightarrow> z = - (int n) \<Longrightarrow> P) \<Longrightarrow> P"
+ by (metis (full_types) int_cases2)
+
+lemma model_to_dimacs_model_distinct:
+ "1 < n_vars \<Longrightarrow> distinct (map dimacs_lit_to_var (model_to_dimacs_model M [1..<n_vars]))"
+ by (induction n_vars)
+ (fastforce elim!: int_cases2'
+ simp add: dimacs_lit_to_var_def model_to_dimacs_model_append'
+ model_to_dimacs_neg_nin model_to_dimacs_pos_nin)+
+
+lemma model_to_dimacs_model_sound:
+ "1 < n_vars \<Longrightarrow> (\<forall>v\<in>atoms f. 0 < v \<and> v < n_vars) \<Longrightarrow> is_cnf f \<Longrightarrow> M \<Turnstile> f \<Longrightarrow>
+ dimacs_model (model_to_dimacs_model M [(1::nat)..<n_vars]) (cnf_to_dimacs f)"
+ unfolding dimacs_model_def
+ using model_to_dimacs_model_all_vars model_to_dimacs_model_all_clauses model_to_dimacs_model_distinct
+ by auto
+
+lemma model_to_dimacs_model_sound_exists:
+ "1 < n_vars \<Longrightarrow> (\<forall>v\<in>atoms f. 0 < v \<and> v < n_vars) \<Longrightarrow> is_cnf f \<Longrightarrow> M \<Turnstile> f \<Longrightarrow>
+ \<exists>M_dimacs. dimacs_model M_dimacs (cnf_to_dimacs f)"
+ using model_to_dimacs_model_sound
+ by metis
+
+definition dimacs_to_atom ::"int \<Rightarrow> nat formula" where
+ "dimacs_to_atom l \<equiv> if (l < 0) then Not (Atom (nat (abs l))) else Atom (nat (abs l))"
+
+definition dimacs_to_disj::"int list \<Rightarrow> nat formula" where
+ "dimacs_to_disj f \<equiv> \<^bold>\<Or> (map dimacs_to_atom f)"
+
+definition dimacs_to_cnf::"int list list \<Rightarrow> nat formula" where
+ "dimacs_to_cnf f \<equiv> \<^bold>\<And>map dimacs_to_disj f"
+
+definition "dimacs_model_to_abs dimacs_M M \<equiv>
+ fold (\<lambda>l M. if (l > 0) then M((nat (abs l)):= True) else M((nat (abs l)):= False)) dimacs_M M"
+
+lemma dimacs_model_to_abs_atom:
+ "0 < x \<Longrightarrow> int x \<in> set dimacs_M \<Longrightarrow> distinct (map dimacs_lit_to_var dimacs_M) \<Longrightarrow> dimacs_model_to_abs dimacs_M M x"
+proof (induction dimacs_M arbitrary: M rule: rev_induct)
+ case (snoc a dimacs_M)
+ thus ?case
+ by (auto simp add: dimacs_model_to_abs_def dimacs_lit_to_var_def image_def)
+qed auto
+
+lemma dimacs_model_to_abs_atom':
+ "0 < x \<Longrightarrow> -(int x) \<in> set dimacs_M \<Longrightarrow> distinct (map dimacs_lit_to_var dimacs_M) \<Longrightarrow> \<not> dimacs_model_to_abs dimacs_M M x"
+proof (induction dimacs_M arbitrary: M rule: rev_induct)
+ case (snoc a dimacs_M)
+ thus ?case
+ by (auto simp add: dimacs_model_to_abs_def dimacs_lit_to_var_def image_def)
+qed auto
+
+lemma model_to_dimacs_model_complete_disj:
+ "(\<forall>v\<in>atoms f. 0 < v \<and> v < n_vars) \<Longrightarrow> is_disj f \<Longrightarrow> distinct (map dimacs_lit_to_var dimacs_M)
+ \<Longrightarrow> dimacs_model dimacs_M (cnf_to_dimacs f) \<Longrightarrow> dimacs_model_to_abs dimacs_M (\<lambda>_. False) \<Turnstile> f"
+ by (induction f)
+ (fastforce elim!: is_lit_plus.elims dest!: isdisj_disjD
+ simp: cnf_to_dimacs_disj dimacs_model_def dimacs_model_to_abs_atom'
+ dimacs_model_to_abs_atom)+
+
+lemma model_to_dimacs_model_complete:
+ "(\<forall>v\<in>atoms f. 0 < v \<and> v < n_vars) \<Longrightarrow> is_cnf f \<Longrightarrow> distinct (map dimacs_lit_to_var dimacs_M)
+ \<Longrightarrow> dimacs_model dimacs_M (cnf_to_dimacs f) \<Longrightarrow> dimacs_model_to_abs dimacs_M (\<lambda>_. False) \<Turnstile> f"
+proof(induction f)
+ case (Not f)
+ then show ?case
+ by (auto elim!: is_lit_plus.elims simp add: dimacs_model_to_abs_atom' dimacs_model_def)
+next
+ case (Or f1 f2)
+ then show ?case
+ using cnf_to_dimacs_disj model_to_dimacs_model_complete_disj
+ by(elim is_cnf_disj, simp add: dimacs_model_def)
+qed (insert dimacs_model_to_abs_atom, auto simp: dimacs_model_def)
+
+lemma model_to_dimacs_model_complete_max_var:
+ "(\<forall>v\<in>atoms f. 0 < v) \<Longrightarrow> is_cnf f \<Longrightarrow>
+ dimacs_model dimacs_M (cnf_to_dimacs f) \<Longrightarrow>
+ dimacs_model_to_abs dimacs_M (\<lambda>_. False) \<Turnstile> f"
+ using le_imp_less_Suc[OF max_var]
+ by (auto intro!: model_to_dimacs_model_complete simp: dimacs_model_def)
+
+lemma model_to_dimacs_model_sound_max_var:
+ "(\<forall>v\<in>atoms f. 0 < v) \<Longrightarrow> is_cnf f \<Longrightarrow> M \<Turnstile> f \<Longrightarrow>
+ dimacs_model (model_to_dimacs_model M [(1::nat)..<(find_max (formula_vars f) + 2)])
+ (cnf_to_dimacs f)"
+ using le_imp_less_Suc[unfolded Suc_eq_plus1, OF max_var]
+ by (fastforce intro!: model_to_dimacs_model_sound)
+
+context sat_solve_sasp
+begin
+
+lemma [simp]: "var_to_dimacs sv > 0"
+ by(cases sv) auto
+
+lemma var_to_dimacs_pos:
+ "v \<in> atoms (map_formula var_to_dimacs f) \<Longrightarrow> 0 < v"
+ by (induction f) auto
+
+lemma map_is_disj: "is_disj f \<Longrightarrow> is_disj (map_formula F f)"
+ by (induction f) (auto elim: is_lit_plus.elims)
+
+lemma map_is_cnf: "is_cnf f \<Longrightarrow> is_cnf (map_formula F f)"
+ by (induction f) (auto elim: is_lit_plus.elims simp: map_is_disj)
+
+lemma planning_dimacs_complete:
+ "valid_plan \<pi>s \<Longrightarrow> length \<pi>s \<le> h \<Longrightarrow>
+ let cnf_formula = (map_formula var_to_dimacs
+ (\<Phi>\<^sub>\<forall> (\<phi> (prob_with_noop abs_prob)) h))
+ in
+ \<exists>dimacs_M. dimacs_model dimacs_M (cnf_to_dimacs cnf_formula)"
+ unfolding Let_def
+ by (fastforce simp: var_to_dimacs_pos
+ dest!: planning_by_cnf_dimacs_complete
+ intro: model_to_dimacs_model_sound_max_var map_is_cnf
+ is_cnf_encode_problem_with_operator_interference_exclusion
+ is_valid_problem_sas_plus_then_strips_transformation_too
+ noops_valid abs_prob_valid)
+
+lemma planning_dimacs_sound:
+ "let cnf_formula =
+ (map_formula var_to_dimacs
+ (\<Phi>\<^sub>\<forall> (\<phi> (prob_with_noop abs_prob)) h))
+ in
+ dimacs_model dimacs_M (cnf_to_dimacs cnf_formula) \<Longrightarrow>
+ valid_plan
+ (decode_abs_plan
+ (rem_noops
+ (map (\<lambda>op. \<phi>\<^sub>O\<inverse> (prob_with_noop abs_prob) op)
+ (concat
+ (\<Phi>\<inverse> (\<phi> (prob_with_noop abs_prob)) ((dimacs_model_to_abs dimacs_M (\<lambda>_. False)) o var_to_dimacs) h)))))"
+ by(fastforce simp: var_to_dimacs_pos Let_def
+ intro: planning_by_cnf_dimacs_sound model_to_dimacs_model_complete_max_var
+ map_is_cnf is_cnf_encode_problem_with_operator_interference_exclusion
+ is_valid_problem_sas_plus_then_strips_transformation_too abs_prob_valid
+ noops_valid)
+
+end
+
+section \<open>Code Generation\<close>
+
+text \<open>We now generate SML code equivalent to the functions that encode a problem as a CNF formula
+ and that decode the model of the given encodings into a plan.\<close>
+
+lemma [code]:
+ "dimacs_model ls cs \<equiv> (list_all (\<lambda>c. list_ex (\<lambda>l. ListMem l c ) ls) cs) \<and>
+ distinct (map dimacs_lit_to_var ls)"
+ unfolding dimacs_model_def
+ by (auto simp: list.pred_set ListMem_iff list_ex_iff )
+
+definition
+"SASP_to_DIMACS h prob \<equiv>
+ cnf_to_dimacs
+ (map_formula
+ (cnf_to_dimacs.var_to_dimacs (Suc h) (Suc (length (ast_problem.ast\<delta> prob))))
+ (\<Phi>\<^sub>\<forall> (\<phi> (prob_with_noop (ast_problem.abs_prob prob))) h))"
+
+lemma planning_dimacs_complete_code:
+ "\<lbrakk>ast_problem.well_formed prob;
+ \<forall>\<pi>\<in>set (ast_problem.ast\<delta> prob). is_standard_operator' \<pi>;
+ ast_problem.valid_plan prob \<pi>s;
+ length \<pi>s \<le> h\<rbrakk> \<Longrightarrow>
+ let cnf_formula = (SASP_to_DIMACS h prob) in
+ \<exists>dimacs_M. dimacs_model dimacs_M cnf_formula"
+ unfolding SASP_to_DIMACS_def Let_def
+ apply(rule sat_solve_sasp.planning_dimacs_complete[unfolded Let_def])
+ apply unfold_locales
+ by auto
+
+definition "SASP_to_DIMACS' h prob \<equiv> SASP_to_DIMACS h (rem_implicit_pres_ops prob)"
+
+lemma planning_dimacs_complete_code':
+ "\<lbrakk>ast_problem.well_formed prob;
+ (\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> consistent_pres_op op);
+ (\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> is_standard_operator op);
+ ast_problem.valid_plan prob \<pi>s;
+ length \<pi>s \<le> h\<rbrakk> \<Longrightarrow>
+ let cnf_formula = (SASP_to_DIMACS' h prob) in
+ \<exists>dimacs_M. dimacs_model dimacs_M cnf_formula"
+ unfolding Let_def SASP_to_DIMACS'_def
+ by (auto simp add: rem_implicit_pres_ops_valid_plan[symmetric] wf_ast_problem_def
+ simp del: rem_implicit_pres.simps
+ intro!: rem_implicit_pres_is_standard_operator'
+ planning_dimacs_complete_code[unfolded Let_def]
+ rem_implicit_pres_ops_well_formed
+ dest!: rem_implicit_pres_ops_in\<delta>D)
+
+text \<open>A function that does the checks required by the completeness theorem above, and returns
+ appropriate error messages if any of the checks fail.\<close>
+
+definition
+ "encode h prob \<equiv>
+ if ast_problem.well_formed prob then
+ if (\<forall>op \<in> set (ast_problem.ast\<delta> prob). consistent_pres_op op) then
+ if (\<forall>op \<in> set (ast_problem.ast\<delta> prob). is_standard_operator op) then
+ Inl (SASP_to_DIMACS' h prob)
+ else
+ Inr (STR ''Error: Conditional effects!'')
+ else
+ Inr (STR ''Error: Preconditions inconsistent'')
+ else
+ Inr (STR ''Error: Problem malformed!'')"
+
+lemma encode_sound:
+ "\<lbrakk>ast_problem.valid_plan prob \<pi>s; length \<pi>s \<le> h;
+ encode h prob = Inl cnf_formula\<rbrakk> \<Longrightarrow>
+ (\<exists>dimacs_M. dimacs_model dimacs_M cnf_formula)"
+ unfolding encode_def
+ by (auto split: if_splits simp: list.pred_set
+ intro: planning_dimacs_complete_code'[unfolded Let_def])
+
+lemma encode_complete:
+ "encode h prob = Inr err \<Longrightarrow>
+ \<not>(ast_problem.well_formed prob \<and> (\<forall>op \<in> set (ast_problem.ast\<delta> prob). consistent_pres_op op) \<and>
+ (\<forall>op \<in> set (ast_problem.ast\<delta> prob). is_standard_operator op))"
+ unfolding encode_def
+ by (auto split: if_splits simp: list.pred_set
+ intro: planning_dimacs_complete_code'[unfolded Let_def])
+
+definition match_pre where
+ "match_pre \<equiv> \<lambda>(x,v) s. s x = Some v"
+
+definition match_pres where
+ "match_pres pres s \<equiv> \<forall>pre\<in>set pres. match_pre pre s"
+
+lemma match_pres_distinct:
+ "distinct (map fst pres) \<Longrightarrow> match_pres pres s \<longleftrightarrow> Map.map_of pres \<subseteq>\<^sub>m s"
+ unfolding match_pres_def match_pre_def
+ using map_le_def map_of_SomeD
+ apply (auto split: prod.splits)
+ apply fastforce
+ using domI map_of_is_SomeI
+ by smt
+
+fun tree_map_of where
+ "tree_map_of updatea T [] = T"
+| "tree_map_of updatea T ((v,a)#m) = updatea v a (tree_map_of updatea T m)"
+
+context Map
+begin
+
+abbreviation "tree_map_of' \<equiv> tree_map_of update"
+
+lemma tree_map_of_invar: "invar T \<Longrightarrow> invar (tree_map_of' T pres)"
+ by (induction pres) (auto simp add: invar_update)
+
+lemma tree_map_of_works: "lookup (tree_map_of' empty pres) x = map_of pres x"
+ by (induction pres) (auto simp: map_empty map_update[OF tree_map_of_invar[OF invar_empty]])
+
+lemma tree_map_of_dom: "dom (lookup (tree_map_of' empty pres)) = dom (map_of pres)"
+ by (induction pres) (auto simp: map_empty map_update[OF tree_map_of_invar[OF invar_empty]] tree_map_of_works)
+end
+
+lemma distinct_if_sorted: "sorted xs \<Longrightarrow> distinct xs"
+ by (induction xs rule: induct_list012) auto
+
+context Map_by_Ordered
+begin
+
+lemma tree_map_of_distinct: "distinct (map fst (inorder (tree_map_of' empty pres)))"
+ apply(induction pres)
+ apply(clarsimp simp: map_empty inorder_empty)
+ using distinct_if_sorted invar_def invar_empty invar_update tree_map_of_invar
+ by blast
+
+end
+
+lemma set_tree_intorder: "set_tree t = set (inorder t)"
+ by (induction t) auto
+
+lemma map_of_eq:
+ "map_of xs = Map.map_of xs"
+ by (induction xs) (auto simp: map_of_simps split: option.split)
+
+lemma lookup_someD: "lookup T x = Some y \<Longrightarrow> \<exists>p. p \<in> set (inorder T) \<and> p = (x, y)"
+ by (induction T) (auto split: if_splits)
+
+lemma map_of_lookup: "sorted1 (inorder T) \<Longrightarrow> Map.map_of (inorder T) = lookup T"
+ apply(induction T)
+ apply (auto split: prod.splits intro!: map_le_antisym
+ simp: lookup_map_of map_add_Some_iff map_of_None2 sorted_wrt_append)
+ using lookup_someD
+ by (force simp: map_of_eq map_add_def map_le_def
+ split: option.splits)+
+
+lemma map_le_cong: "(\<And>x. m1 x = m2 x) \<Longrightarrow> m1 \<subseteq>\<^sub>m s \<longleftrightarrow> m2 \<subseteq>\<^sub>m s"
+ by presburger
+
+lemma match_pres_submap:
+ "match_pres (inorder (M.tree_map_of' empty pres)) s \<longleftrightarrow> Map.map_of pres \<subseteq>\<^sub>m s"
+ using match_pres_distinct[OF M.tree_map_of_distinct]
+ by (smt M.invar_def M.invar_empty M.tree_map_of_invar M.tree_map_of_works map_le_cong map_of_eq map_of_lookup)
+
+lemma [code]:
+ "SAS_Plus_Representation.is_operator_applicable_in s op \<longleftrightarrow>
+ match_pres (inorder (M.tree_map_of' empty (SAS_Plus_Representation.precondition_of op))) s"
+ by (simp add: match_pres_submap SAS_Plus_Representation.is_operator_applicable_in_def)
+
+definition "decode_DIMACS_model dimacs_M h prob \<equiv>
+ (ast_problem.decode_abs_plan prob
+ (rem_noops
+ (map (\<lambda>op. \<phi>\<^sub>O\<inverse> (prob_with_noop (ast_problem.abs_prob prob)) op)
+ (concat
+ (\<Phi>\<inverse> (\<phi> (prob_with_noop (ast_problem.abs_prob prob)))
+ ((dimacs_model_to_abs dimacs_M (\<lambda>_. False)) o
+ (cnf_to_dimacs.var_to_dimacs (Suc h)
+ (Suc (length (ast_problem.ast\<delta> prob)))))
+ h)))))"
+
+lemma planning_dimacs_sound_code:
+ "\<lbrakk>ast_problem.well_formed prob;
+ \<forall>\<pi>\<in>set (ast_problem.ast\<delta> prob). is_standard_operator' \<pi>\<rbrakk> \<Longrightarrow>
+ let
+ cnf_formula = (SASP_to_DIMACS h prob);
+ decoded_plan = decode_DIMACS_model dimacs_M h prob
+ in
+ (dimacs_model dimacs_M cnf_formula \<longrightarrow> ast_problem.valid_plan prob decoded_plan)"
+ unfolding SASP_to_DIMACS_def decode_DIMACS_model_def Let_def
+ apply(rule impI sat_solve_sasp.planning_dimacs_sound[unfolded Let_def])+
+ apply unfold_locales
+ by auto
+
+definition
+ "decode_DIMACS_model' dimacs_M h prob \<equiv>
+ decode_DIMACS_model dimacs_M h (rem_implicit_pres_ops prob)"
+
+lemma planning_dimacs_sound_code':
+ "\<lbrakk>ast_problem.well_formed prob;
+ (\<And>op. op \<in> set (ast_problem.ast\<delta> prob) \<Longrightarrow> consistent_pres_op op);
+ \<forall>\<pi>\<in>set (ast_problem.ast\<delta> prob). is_standard_operator \<pi>\<rbrakk> \<Longrightarrow>
+ let
+ cnf_formula = (SASP_to_DIMACS' h prob);
+ decoded_plan = decode_DIMACS_model' dimacs_M h prob
+ in
+ (dimacs_model dimacs_M cnf_formula \<longrightarrow> ast_problem.valid_plan prob decoded_plan)"
+ unfolding SASP_to_DIMACS'_def decode_DIMACS_model'_def
+ apply(subst rem_implicit_pres_ops_valid_plan[symmetric])
+ by(fastforce simp only: rem_implicit_pres_ops_valid_plan wf_ast_problem_def
+ intro!: rem_implicit_pres_is_standard_operator'
+ rem_implicit_pres_ops_well_formed
+ rev_iffD2[OF _ rem_implicit_pres_ops_valid_plan]
+ planning_dimacs_sound_code wf_ast_problem.intro
+ dest!: rem_implicit_pres_ops_in\<delta>D)+
+
+text \<open>Checking if the model satisfies the formula takes the longest time in the decoding function.
+ We reimplement that part using red black trees, which makes it 10 times faster, on average!\<close>
+
+fun list_to_rbt :: "int list \<Rightarrow> int rbt" where
+ "list_to_rbt [] = Leaf"
+| "list_to_rbt (x#xs) = insert_rbt x (list_to_rbt xs)"
+
+lemma inv_list_to_rbt: "invc (list_to_rbt xs) \<and> invh (list_to_rbt xs)"
+ by (induction xs) (auto simp: rbt_def RBT.inv_insert)
+
+lemma Tree2_list_to_rbt: "Tree2.bst (list_to_rbt xs)"
+ by (induction xs) (auto simp: RBT.bst_insert)
+
+lemma set_list_to_rbt: "Tree2.set_tree (list_to_rbt xs) = set xs"
+ by (induction xs) (simp add: RBT.set_tree_insert Tree2_list_to_rbt)+
+
+text \<open>The following \<close>
+
+lemma dimacs_model_code[code]:
+ "dimacs_model ls cs \<longleftrightarrow>
+ (let tls = list_to_rbt ls in
+ (\<forall>c\<in>set cs. size (inter_rbt (tls) (list_to_rbt c)) \<noteq> 0) \<and>
+ distinct (map dimacs_lit_to_var ls))"
+ using RBT.set_tree_inter[OF Tree2_list_to_rbt Tree2_list_to_rbt]
+ apply (auto simp: dimacs_model_def Let_def set_list_to_rbt inter_rbt_def)
+ apply (metis IntI RBT.set_empty empty_iff)
+ by (metis Tree2.eq_set_tree_empty disjoint_iff_not_equal)
+
+definition
+ "decode M h prob \<equiv>
+ if ast_problem.well_formed prob then
+ if (\<forall>op\<in>set (ast_problem.ast\<delta> prob). consistent_pres_op op) then
+ if (\<forall>op\<in>set (ast_problem.ast\<delta> prob). is_standard_operator op) then
+ if (dimacs_model M (SASP_to_DIMACS' h prob)) then
+ Inl (decode_DIMACS_model' M h prob)
+ else Inr (STR ''Error: Model does not solve the problem!'')
+ else
+ Inr (STR ''Error: Conditional effects!'')
+ else
+ Inr (STR ''Error: Preconditions inconsistent'')
+ else
+ Inr (STR ''Error: Problem malformed!'')"
+
+lemma decode_sound:
+ "decode M h prob = Inl plan \<Longrightarrow>
+ ast_problem.valid_plan prob plan"
+ unfolding decode_def
+ apply (auto split: if_splits simp: list.pred_set)
+ using planning_dimacs_sound_code'
+ by auto
+
+lemma decode_complete:
+ "decode M h prob = Inr err \<Longrightarrow>
+ \<not> (ast_problem.well_formed prob \<and>
+ (\<forall>op \<in> set (ast_problem.ast\<delta> prob). consistent_pres_op op) \<and>
+ (\<forall>\<pi>\<in>set (ast_problem.ast\<delta> prob). is_standard_operator \<pi>) \<and>
+ dimacs_model M (SASP_to_DIMACS' h prob))"
+ unfolding decode_def
+ by (auto split: if_splits simp: list.pred_set)
+
+lemma [code]:
+ "ListMem x' []= False"
+ "ListMem x' (x#xs) = (x' = x \<or> ListMem x' xs)"
+ by (simp add: ListMem_iff)+
+
+lemmas [code] = SASP_to_DIMACS_def ast_problem.abs_prob_def
+ ast_problem.abs_ast_variable_section_def ast_problem.abs_ast_operator_section_def
+ ast_problem.abs_ast_initial_state_def ast_problem.abs_range_map_def
+ ast_problem.abs_ast_goal_def cnf_to_dimacs.var_to_dimacs.simps
+ ast_problem.ast\<delta>_def ast_problem.astDom_def ast_problem.abs_ast_operator_def
+ ast_problem.astI_def ast_problem.astG_def ast_problem.lookup_action_def
+ ast_problem.I_def execute_operator_sas_plus_def ast_problem.decode_abs_plan_def
+
+definition nat_opt_of_integer :: "integer \<Rightarrow> nat option" where
+ "nat_opt_of_integer i = (if (i \<ge> 0) then Some (nat_of_integer i) else None)"
+
+definition max_var :: "int list \<Rightarrow> int" where
+ "max_var xs \<equiv> fold (\<lambda>(x::int) (y::int). if abs x \<ge> abs y then (abs x) else y) xs (0::int)"
+
+export_code encode nat_of_integer integer_of_nat nat_opt_of_integer Inl Inr String.explode
+ String.implode max_var concat char_of_nat Int.nat integer_of_int length int_of_integer
+ in SML module_name exported file "code/generated/SASP_to_DIMACS.sml"
+
+export_code decode nat_of_integer integer_of_nat nat_opt_of_integer Inl Inr String.explode
+ String.implode max_var concat char_of_nat Int.nat integer_of_int length int_of_integer
+ in SML module_name exported file "code/generated/decode_DIMACS_model.sml"
+
+end
\ No newline at end of file
diff --git a/thys/Verified_SAT_Based_AI_Planning/State_Variable_Representation.thy b/thys/Verified_SAT_Based_AI_Planning/State_Variable_Representation.thy
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/State_Variable_Representation.thy
@@ -0,0 +1,26 @@
+(*
+ Author: Mohammad Abdulaziz, Fred Kurz
+*)
+theory State_Variable_Representation
+ imports Main "Propositional_Proof_Systems.Formulas" "Propositional_Proof_Systems.Sema"
+ "Propositional_Proof_Systems.CNF"
+begin
+section "State-Variable Representation"
+
+text \<open> Moving on to the Isabelle implementation of state-variable representation, we
+first add a more concrete representation of states using Isabelle maps. To this end, we add a
+type synonym \isaname{state} for maps of variables to values.
+Since maps can be conveniently constructed from lists of
+assignments---i.e. pairs \<open>(v, a) :: 'variable \<times> 'domain\<close>---we also add a corresponding type
+synonym \isaname{assignment}. \<close>
+
+type_synonym ('variable, 'domain) state = "'variable \<rightharpoonup> 'domain"
+
+type_synonym ('variable, 'domain) assignment = "'variable \<times> 'domain"
+
+text \<open> Effects and effect condition (see \autoref{sub:state-variable-representation}) are
+implemented in a straight forward manner using a datatype with constructors for each effect type.\<close>
+
+type_synonym ('variable, 'domain) Effect = "('variable \<times> 'domain) list"
+
+end
\ No newline at end of file
diff --git a/thys/Verified_SAT_Based_AI_Planning/code/build.sh b/thys/Verified_SAT_Based_AI_Planning/code/build.sh
new file mode 100755
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/code/build.sh
@@ -0,0 +1,5 @@
+#!/bin/bash
+unzip kissat-master.zip
+unzip sml-parse-comb-master.zip
+mlton encode_problem.mlb
+mlton decode_model.mlb
diff --git a/thys/Verified_SAT_Based_AI_Planning/code/compute_plan.sh b/thys/Verified_SAT_Based_AI_Planning/code/compute_plan.sh
new file mode 100755
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/code/compute_plan.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+function help_message(){
+ echo "Usage ./compute_plan.sh horizon problem SAT_solver_executable"
+ echo "Note: horizon is a number\n problem is a SAS+ problem in FastDownward's format\n SAT_solver_executable is a path to an executable that accepts DIMACS SAT formulae in its stdin, and it has to output a model as a sequence of integers with only spaces between them"
+ exit
+}
+
+if [ -z "$1" ]; then
+ help_message
+fi
+
+if [ -z "$2" ]; then
+ help_message
+fi
+
+if [ -z "$3" ]; then
+ help_message
+fi
+
+horizon=$1
+problem=$2
+SAT_Solver=$3
+
+cat $problem | sed -n '/begin_SG/q;p' > /tmp/op_prob
+
+./encode_problem /tmp/op_prob $horizon | sed 's/~/-/g' | $SAT_Solver > /tmp/op_model
+
+./decode_model /tmp/op_prob <(grep "v " /tmp/op_model | sed 's/v //g' | sed 's/ 0//g') $horizon
diff --git a/thys/Verified_SAT_Based_AI_Planning/code/decode_model.mlb b/thys/Verified_SAT_Based_AI_Planning/code/decode_model.mlb
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/code/decode_model.mlb
@@ -0,0 +1,44 @@
+(* Combinator parsing examples *)
+
+$(MLTON_ROOT)/basis/basis.mlb
+
+sml-parse-comb-master/.smackage/lib/cmlib/v2.3.0/cmlib.mlb
+
+(* Parcom proper *)
+local
+
+ sml-parse-comb-master/src/parse.sig
+ sml-parse-comb-master/src/parse.sml
+
+ sml-parse-comb-master/src/charparse.sig
+ sml-parse-comb-master/src/charparse.sml
+
+ sml-parse-comb-master/src/tokparse.sig
+ sml-parse-comb-master/src/tokparse.sml
+ sml-parse-comb-master/src/langparse.sml
+
+in
+
+ signature PARSER_COMBINATORS
+ signature CHAR_PARSER
+ signature MINI_LANGUAGE_DEF
+ signature LANGUAGE_DEF
+ signature TOKEN_PARSER
+
+ structure ParserCombinators
+ structure CharParser
+ structure BasicParser
+
+
+ functor TokenParser
+ functor SimpleStyle
+ functor JavaStyle
+ functor MLStyle
+
+end
+
+
+(*strips.sml*)
+generated/decode_DIMACS_model.sml
+sas_plus.sml
+decode_model.sml
diff --git a/thys/Verified_SAT_Based_AI_Planning/code/decode_model.sml b/thys/Verified_SAT_Based_AI_Planning/code/decode_model.sml
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/code/decode_model.sml
@@ -0,0 +1,164 @@
+(* This is a demo example of a simple grammar for receipts.
+
+ Consider the following EBNF:
+ sas_prob ::= version 0
+*)
+structure LexCNFModel =
+(* An implementation that uses token parser. *)
+struct
+
+ open ParserCombinators
+ open CharParser
+
+ infixr 4 << >>
+ infixr 3 &&
+ infix 2 -- ##
+ infix 2 wth suchthat return guard when
+ infixr 1 || <|> ??
+
+ structure CNFModelDef :> LANGUAGE_DEF =
+ struct
+
+ type scanner = SubstringMonoStreamable.elem CharParser.charParser
+
+ val commentStart = NONE
+ val commentEnd = NONE
+ val commentLine = NONE
+ val nestedComments = false
+
+ val alphaNumUnderDashSpace = try (satisfy (fn c =>
+ (if (Char.isAlpha c)
+ then true
+ else false)) ) ?? "alphanumeric character"
+
+ val identLetter = alphaNumUnderDashSpace (*Idents can only be separated with \n and can contain [Aa-Zz], [0-9], " ", "-", "_"*)
+ val identStart = identLetter
+ val opStart = fail "Operators not supported" : scanner
+ val opLetter = opStart
+ val reservedNames = []
+ val reservedOpNames= []
+ val caseSensitive = true
+
+ end
+
+ structure RTP = TokenParser (CNFModelDef)
+ open RTP
+
+ val SMLCharImplode = String.implode;
+ val SMLCharExplode = String.explode;
+
+
+ val num = (lexeme ((char #"-" || digit) && (repeat digit)) when
+ (fn (x,xs) => Int.fromString (SMLCharImplode (x::xs)))) ?? "num expression"
+
+ fun model_reserved wrd = (reserved wrd)
+
+ val model_line = (*(model_reserved "v" ?? "v, parsing model_line") <<*)
+ (repeat num ?? "literal, parsing model_line")
+
+ val model = (repeat num ?? "literal, parsing model_line")
+
+end
+
+
+val args = CommandLine.arguments()
+
+fun parse_problem sas_file =
+ (CharParser.parseString LexSASProb.problem (readFile sas_file))
+
+val parsed_problem = parse_problem (List.nth (args,0))
+
+val _ = case parsed_problem of Sum.INR _ =>
+ (case (Sum.outR parsed_problem) of (prob: SAS_PROB)
+ => print "Problem parsed\n")
+ | Sum.INL err => print ("ERR: " ^ err)
+
+fun parse_model model_file =
+ (CharParser.parseString LexCNFModel.model (readFile model_file))
+
+val parsed_model = parse_model (List.nth (args,1))
+
+val _ = case parsed_model of Sum.INR _ =>
+ (case (Sum.outR parsed_model) of (model)
+ => print "Model Parsed\n")
+ | Sum.INL err => print ("ERR: " ^ err)
+
+fun modelToString model = (String.concatWith " " (map IntInf.toString (map IntInf.fromInt model)))
+
+fun modelToIsabelleModel model = (map (exported.int_of_integer o IntInf.fromInt) model)
+
+val IsabelleStringImplode = exported.implode;
+val IsabelleStringExplode = exported.explode;
+
+fun planToIsabellePlan plan = map IsabelleStringExplode plan
+
+fun variableToIsabelleVariable
+ (variable_name: string,
+ (axiom_layer: int,
+ atom_names: string list)) =
+ (IsabelleStringExplode variable_name,
+ (exported.nat_opt_of_integer(IntInf.fromInt axiom_layer),
+ map IsabelleStringExplode atom_names))
+
+fun sasAssToIsabelleSasAss (varID, ass) =
+ (exported.nat_of_integer (IntInf.fromInt varID),
+ exported.nat_of_integer (IntInf.fromInt ass))
+
+fun effectToIsabelleEffect
+ (effect_preconds: SAS_ASS list,
+ (var_ID: int,
+ (old_ass: int,
+ (new_ass)))) =
+ (map sasAssToIsabelleSasAss effect_preconds,
+ (exported.nat_of_integer (IntInf.fromInt var_ID),
+ (exported.nat_opt_of_integer (IntInf.fromInt old_ass),
+ exported.nat_of_integer (IntInf.fromInt new_ass))))
+
+fun operatorToIsabelleOperator
+ (operator_name: string,
+ (preconds: SAS_ASS list,
+ (effects: EFFECT list,
+ (cost: int)))) =
+ (IsabelleStringExplode operator_name,
+ (map sasAssToIsabelleSasAss preconds,
+ (map effectToIsabelleEffect effects,
+ exported.nat_of_integer (IntInf.fromInt cost))))
+
+fun problemToIsabelleProblem
+ (version_res:int,
+ (metric_res:int,
+ (variables: SAS_VAR list,
+ (mutex_groups: MUTEX_GRP list,
+ (init_state: int list,
+ (goal: SAS_ASS list,
+ (operators: OPRTR list,
+ num_axioms: int))))))) =
+(map variableToIsabelleVariable variables,
+ (map (exported.nat_of_integer o IntInf.fromInt) init_state,
+ (map sasAssToIsabelleSasAss goal,
+ (map operatorToIsabelleOperator operators))))
+
+open LexSASProb
+
+val isabelle_plan =
+ (case parsed_problem of
+ Sum.INR _ =>
+ (case (Sum.outR parsed_problem) of (prob: SAS_PROB)
+ =>
+ (case parsed_model of
+ Sum.INR _ =>
+ (case (Sum.outR parsed_model) of (model: int list)
+ => (
+ exported.decode
+ (modelToIsabelleModel model)
+ ((case (IntInf.fromString (List.nth (args,2))) of Option.SOME n => exported.nat_of_integer n))
+ (problemToIsabelleProblem prob)
+ )))))
+
+val _ = case isabelle_plan
+ of exported.Inl plan
+ => print ("Plan:\n" ^ (String.concatWith "\n" (map exported.implode plan)) ^ "\n")
+ | exported.Inr err
+ => print (err ^ "\n")
+
+val _ = OS.Process.exit(OS.Process.success)
diff --git a/thys/Verified_SAT_Based_AI_Planning/code/encode_problem.mlb b/thys/Verified_SAT_Based_AI_Planning/code/encode_problem.mlb
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/code/encode_problem.mlb
@@ -0,0 +1,44 @@
+(* Combinator parsing examples *)
+
+$(MLTON_ROOT)/basis/basis.mlb
+
+sml-parse-comb-master/.smackage/lib/cmlib/v2.3.0/cmlib.mlb
+
+(* Parcom proper *)
+local
+
+ sml-parse-comb-master/src/parse.sig
+ sml-parse-comb-master/src/parse.sml
+
+ sml-parse-comb-master/src/charparse.sig
+ sml-parse-comb-master/src/charparse.sml
+
+ sml-parse-comb-master/src/tokparse.sig
+ sml-parse-comb-master/src/tokparse.sml
+ sml-parse-comb-master/src/langparse.sml
+
+in
+
+ signature PARSER_COMBINATORS
+ signature CHAR_PARSER
+ signature MINI_LANGUAGE_DEF
+ signature LANGUAGE_DEF
+ signature TOKEN_PARSER
+
+ structure ParserCombinators
+ structure CharParser
+ structure BasicParser
+
+
+ functor TokenParser
+ functor SimpleStyle
+ functor JavaStyle
+ functor MLStyle
+
+end
+
+
+(*strips.sml*)
+generated/SASP_to_DIMACS.sml
+sas_plus.sml
+encode_problem.sml
diff --git a/thys/Verified_SAT_Based_AI_Planning/code/encode_problem.sml b/thys/Verified_SAT_Based_AI_Planning/code/encode_problem.sml
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/code/encode_problem.sml
@@ -0,0 +1,178 @@
+(* This is a demo example of a simple grammar for receipts.
+
+ Consider the following EBNF:
+ sas_prob ::= version 0
+*)
+
+type SAS_VAR = (string * (int * string list))
+
+fun varToString (variable_name: string,
+ (axiom_layer:int,
+ atom_names :string list)) =
+ " Variable name = " ^ variable_name ^
+ "\n Axiom layer = " ^ Int.toString(axiom_layer) ^
+ "\n Atoms:\n " ^ ((String.concatWith "\n ") atom_names);
+
+fun sasAssToString (varID: int, ass: int) =
+ " VariableID = " ^ Int.toString(varID) ^
+ " Ass = " ^ Int.toString(ass);
+
+fun mutexGroupToString (mutex_group: (int * int) list) =
+ "\n Mutex group asses:\n" ^ ((String.concatWith "\n") (map sasAssToString mutex_group));
+
+type SAS_ASS = int * int
+
+fun effectToString (effect_preconds: SAS_ASS list,
+ (var_ID: int,
+ (old_ass: int,
+ (new_ass)))) =
+ "\n Effect:" ^ ((String.concatWith "\n ") (map sasAssToString effect_preconds)) ^
+ "\n Var ID = " ^ Int.toString(var_ID) ^
+ " Old ass = " ^ Int.toString(new_ass) ^
+ " New ass = " ^ Int.toString(old_ass);
+
+type EFFECT = ((SAS_ASS list) * (int * (int * int)))
+
+fun operatorToString
+ (operator_name: string,
+ (preconds: SAS_ASS list,
+ (effects: EFFECT list,
+ (cost: int)))) =
+ " Operator name = " ^ operator_name ^
+ "\n Preconds:\n" ^ ((String.concatWith "\n ") (map sasAssToString preconds)) ^
+ "\n Effects:\n " ^ ((String.concatWith "\n ") (map effectToString effects)) ^
+ "\n Cost = " ^ Int.toString(cost);
+
+type MUTEX_GRP = ((SAS_ASS list))
+
+type OPRTR = string *
+ ((SAS_ASS list)*
+ ((EFFECT list) * int))
+
+type SAS_PROB = int*
+ (int*
+ ((SAS_VAR list) *
+ ((MUTEX_GRP list) *
+ ((int list)*
+ ((SAS_ASS list)*
+ ((OPRTR list) * int))))))
+
+fun probToString
+ (version_res:int,
+ (metric_res:int,
+ (variables: SAS_VAR list,
+ (mutex_groups: MUTEX_GRP list,
+ (init_state: int list,
+ (goal: SAS_ASS list,
+ (operators: OPRTR list,
+ num_axioms: int))))))) =
+ ("Version = " ^ (Int.toString version_res) ^ "\n") ^
+ ("Metric = " ^ (Int.toString metric_res) ^ "\n") ^
+ ("SAS+ vars:\n" ^ ((String.concatWith "\n") (map varToString variables)) ^ "\n") ^
+ ("Mutex Groups:\n" ^ ((String.concatWith "\n") (map mutexGroupToString mutex_groups)) ^ "\n") ^
+ ("Initial state:\n " ^ ((String.concatWith "\n ") (map Int.toString init_state)) ^ "\n") ^
+ ("Goals:\n " ^ ((String.concatWith "\n ") (map sasAssToString goal)) ^ "\n") ^
+ ("Operators:\n " ^ ((String.concatWith "\n ") (map operatorToString operators)) ^ "\n")
+
+type PLAN = string list
+
+val args = CommandLine.arguments()
+
+(**********************************)
+
+(* open SASP_to_DIMACS *)
+(* open SASP_Checker_Exported *)
+
+val IsabelleStringImplode = exported.implode;
+val IsabelleStringExplode = exported.explode;
+
+(* val _ = (IntInf.fromInt (IntSplayDict (0))) *)
+
+fun planToIsabellePlan plan = map IsabelleStringExplode plan
+
+fun variableToIsabelleVariable
+ (variable_name: string,
+ (axiom_layer: int,
+ atom_names: string list)) =
+ (IsabelleStringExplode variable_name,
+ (exported.nat_opt_of_integer(IntInf.fromInt axiom_layer),
+ map IsabelleStringExplode atom_names))
+
+fun sasAssToIsabelleSasAss (varID, ass) =
+ (exported.nat_of_integer (IntInf.fromInt varID),
+ exported.nat_of_integer (IntInf.fromInt ass))
+
+fun effectToIsabelleEffect
+ (effect_preconds: SAS_ASS list,
+ (var_ID: int,
+ (old_ass: int,
+ (new_ass)))) =
+ (map sasAssToIsabelleSasAss effect_preconds,
+ (exported.nat_of_integer (IntInf.fromInt var_ID),
+ (exported.nat_opt_of_integer (IntInf.fromInt old_ass),
+ exported.nat_of_integer (IntInf.fromInt new_ass))))
+
+fun operatorToIsabelleOperator
+ (operator_name: string,
+ (preconds: SAS_ASS list,
+ (effects: EFFECT list,
+ (cost: int)))) =
+ (IsabelleStringExplode operator_name,
+ (map sasAssToIsabelleSasAss preconds,
+ (map effectToIsabelleEffect effects,
+ exported.nat_of_integer (IntInf.fromInt cost))))
+
+fun problemToIsabelleProblem
+ (version_res:int,
+ (metric_res:int,
+ (variables: SAS_VAR list,
+ (mutex_groups: MUTEX_GRP list,
+ (init_state: int list,
+ (goal: SAS_ASS list,
+ (operators: OPRTR list,
+ num_axioms: int))))))) =
+(map variableToIsabelleVariable variables,
+ (map (exported.nat_of_integer o IntInf.fromInt) init_state,
+ (map sasAssToIsabelleSasAss goal,
+ (map operatorToIsabelleOperator operators))))
+
+val readstdIn =
+let
+ fun next_String input = (TextIO.inputAll input)
+ val stream = TextIO.stdIn
+in
+ next_String stream
+end
+
+val parse_problem = (CharParser.parseString LexSASProb.problem readstdIn)
+
+val CNF_formula =
+ (case parse_problem of
+ Sum.INR _ =>
+ (case (Sum.outR parse_problem) of (prob: SAS_PROB)
+ => (exported.encode
+ (case (IntInf.fromString (List.nth (args,0))) of Option.SOME n => exported.nat_of_integer n)
+ (problemToIsabelleProblem prob))))
+
+fun clause_to_string ls = (concat (map ((fn x => x ^ " ") o
+ IntInf.toString o
+ exported.integer_of_int) ls)) ^
+ " 0\n"
+
+fun max xs = foldl (fn (x : int, y : int) => if (abs x) >= (abs y) then abs x else abs y) 0 xs
+
+fun cnfToString cnf =
+ (case cnf of exported.Inl formula
+ =>(let val n_vars = exported.integer_of_int ((exported.max_var (map exported.max_var formula)))
+ val n_clauses = length formula
+ in
+ ("p cnf " ^
+ (IntInf.toString n_vars) ^ " " ^
+ (Int.toString n_clauses) ^ "\n" ^
+ (concat (map clause_to_string formula)))
+ end)
+ | exported.Inr err => err)
+
+val _ = print (cnfToString CNF_formula)
+
+val _ = OS.Process.exit(OS.Process.success)
diff --git a/thys/Verified_SAT_Based_AI_Planning/code/generated/SASP_to_DIMACS.sml b/thys/Verified_SAT_Based_AI_Planning/code/generated/SASP_to_DIMACS.sml
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/code/generated/SASP_to_DIMACS.sml
@@ -0,0 +1,1034 @@
+structure exported : sig
+ type num
+ type int
+ type nat
+ val integer_of_nat : nat -> IntInf.int
+ type char
+ datatype ('a, 'b) sum = Inl of 'a | Inr of 'b
+ val integer_of_int : int -> IntInf.int
+ val nat : int -> nat
+ val concat : ('a list) list -> 'a list
+ val implode : char list -> string
+ val size_list : 'a list -> nat
+ val int_of_integer : IntInf.int -> int
+ val encode :
+ nat ->
+ (char list * (nat option * (char list) list)) list *
+ (nat list *
+ ((nat * nat) list *
+ (char list *
+ ((nat * nat) list *
+ (((nat * nat) list * (nat * (nat option * nat))) list *
+ nat))) list)) ->
+ (((int list) list), string) sum
+ val max_var : int list -> int
+ val explode : string -> char list
+ val nat_of_integer : IntInf.int -> nat
+ val char_of_nat : nat -> char
+ val nat_opt_of_integer : IntInf.int -> nat option
+end = struct
+
+datatype num = One | Bit0 of num | Bit1 of num;
+
+datatype int = Zero_int | Pos of num | Neg of num;
+
+val one_inta : int = Pos One;
+
+type 'a one = {one : 'a};
+val one = #one : 'a one -> 'a;
+
+val one_int = {one = one_inta} : int one;
+
+type 'a zero = {zero : 'a};
+val zero = #zero : 'a zero -> 'a;
+
+val zero_int = {zero = Zero_int} : int zero;
+
+type 'a zero_neq_one = {one_zero_neq_one : 'a one, zero_zero_neq_one : 'a zero};
+val one_zero_neq_one = #one_zero_neq_one : 'a zero_neq_one -> 'a one;
+val zero_zero_neq_one = #zero_zero_neq_one : 'a zero_neq_one -> 'a zero;
+
+val zero_neq_one_int =
+ {one_zero_neq_one = one_int, zero_zero_neq_one = zero_int} : int zero_neq_one;
+
+datatype nat = Nat of IntInf.int;
+
+fun integer_of_nat (Nat x) = x;
+
+fun equal_nata m n = (((integer_of_nat m) : IntInf.int) = (integer_of_nat n));
+
+type 'a equal = {equal : 'a -> 'a -> bool};
+val equal = #equal : 'a equal -> 'a -> 'a -> bool;
+
+val equal_nat = {equal = equal_nata} : nat equal;
+
+fun eq A_ a b = equal A_ a b;
+
+fun equal_lista A_ [] (x21 :: x22) = false
+ | equal_lista A_ (x21 :: x22) [] = false
+ | equal_lista A_ (x21 :: x22) (y21 :: y22) =
+ eq A_ x21 y21 andalso equal_lista A_ x22 y22
+ | equal_lista A_ [] [] = true;
+
+fun equal_list A_ = {equal = equal_lista A_} : ('a list) equal;
+
+fun equal_bool p true = p
+ | equal_bool p false = not p
+ | equal_bool true p = p
+ | equal_bool false p = not p;
+
+datatype char = Chara of bool * bool * bool * bool * bool * bool * bool * bool;
+
+fun equal_chara (Chara (x1, x2, x3, x4, x5, x6, x7, x8))
+ (Chara (y1, y2, y3, y4, y5, y6, y7, y8)) =
+ equal_bool x1 y1 andalso
+ (equal_bool x2 y2 andalso
+ (equal_bool x3 y3 andalso
+ (equal_bool x4 y4 andalso
+ (equal_bool x5 y5 andalso
+ (equal_bool x6 y6 andalso
+ (equal_bool x7 y7 andalso equal_bool x8 y8))))));
+
+val equal_char = {equal = equal_chara} : char equal;
+
+fun equal_proda A_ B_ (x1, x2) (y1, y2) = eq A_ x1 y1 andalso eq B_ x2 y2;
+
+fun equal_prod A_ B_ = {equal = equal_proda A_ B_} : ('a * 'b) equal;
+
+fun equal_unita u v = true;
+
+val equal_unit = {equal = equal_unita} : unit equal;
+
+val one_integera : IntInf.int = (1 : IntInf.int);
+
+val one_integer = {one = one_integera} : IntInf.int one;
+
+val zero_integer = {zero = (0 : IntInf.int)} : IntInf.int zero;
+
+type 'a ord = {less_eq : 'a -> 'a -> bool, less : 'a -> 'a -> bool};
+val less_eq = #less_eq : 'a ord -> 'a -> 'a -> bool;
+val less = #less : 'a ord -> 'a -> 'a -> bool;
+
+val ord_integer =
+ {less_eq = (fn a => fn b => IntInf.<= (a, b)),
+ less = (fn a => fn b => IntInf.< (a, b))}
+ : IntInf.int ord;
+
+val zero_neq_one_integer =
+ {one_zero_neq_one = one_integer, zero_zero_neq_one = zero_integer} :
+ IntInf.int zero_neq_one;
+
+datatype ('a, 'b) strips_operator_ext =
+ Strips_operator_ext of 'a list * 'a list * 'a list * 'b;
+
+fun equal_strips_operator_exta A_ B_
+ (Strips_operator_ext
+ (precondition_ofa, add_effects_ofa, delete_effects_ofa, morea))
+ (Strips_operator_ext
+ (precondition_of, add_effects_of, delete_effects_of, more))
+ = equal_lista A_ precondition_ofa precondition_of andalso
+ (equal_lista A_ add_effects_ofa add_effects_of andalso
+ (equal_lista A_ delete_effects_ofa delete_effects_of andalso
+ eq B_ morea more));
+
+fun equal_strips_operator_ext A_ B_ = {equal = equal_strips_operator_exta A_ B_}
+ : ('a, 'b) strips_operator_ext equal;
+
+datatype ('a, 'b) sum = Inl of 'a | Inr of 'b;
+
+datatype 'a formula = Atom of 'a | Bot | Not of 'a formula |
+ And of 'a formula * 'a formula | Or of 'a formula * 'a formula |
+ Imp of 'a formula * 'a formula;
+
+datatype sat_plan_variable = State of nat * nat | Operator of nat * nat;
+
+datatype ('a, 'b) strips_problem_ext =
+ Strips_problem_ext of
+ 'a list * ('a, unit) strips_operator_ext list * ('a -> bool option) *
+ ('a -> bool option) * 'b;
+
+datatype ('a, 'b, 'c) sas_plus_operator_ext =
+ Sas_plus_operator_ext of ('a * 'b) list * ('a * 'b) list * 'c;
+
+datatype ('a, 'b, 'c) sas_plus_problem_ext =
+ Sas_plus_problem_ext of
+ 'a list * ('a, 'b, unit) sas_plus_operator_ext list * ('a -> 'b option) *
+ ('a -> 'b option) * ('a -> ('b list) option) * 'c;
+
+fun id x = (fn xa => xa) x;
+
+fun dup (Neg n) = Neg (Bit0 n)
+ | dup (Pos n) = Pos (Bit0 n)
+ | dup Zero_int = Zero_int;
+
+fun plus_num (Bit1 m) (Bit1 n) = Bit0 (plus_num (plus_num m n) One)
+ | plus_num (Bit1 m) (Bit0 n) = Bit1 (plus_num m n)
+ | plus_num (Bit1 m) One = Bit0 (plus_num m One)
+ | plus_num (Bit0 m) (Bit1 n) = Bit1 (plus_num m n)
+ | plus_num (Bit0 m) (Bit0 n) = Bit0 (plus_num m n)
+ | plus_num (Bit0 m) One = Bit1 m
+ | plus_num One (Bit1 n) = Bit0 (plus_num n One)
+ | plus_num One (Bit0 n) = Bit1 n
+ | plus_num One One = Bit0 One;
+
+fun times_num (Bit1 m) (Bit1 n) =
+ Bit1 (plus_num (plus_num m n) (Bit0 (times_num m n)))
+ | times_num (Bit1 m) (Bit0 n) = Bit0 (times_num (Bit1 m) n)
+ | times_num (Bit0 m) (Bit1 n) = Bit0 (times_num m (Bit1 n))
+ | times_num (Bit0 m) (Bit0 n) = Bit0 (Bit0 (times_num m n))
+ | times_num One n = n
+ | times_num m One = m;
+
+fun times_int (Neg m) (Neg n) = Pos (times_num m n)
+ | times_int (Neg m) (Pos n) = Neg (times_num m n)
+ | times_int (Pos m) (Neg n) = Neg (times_num m n)
+ | times_int (Pos m) (Pos n) = Pos (times_num m n)
+ | times_int Zero_int l = Zero_int
+ | times_int k Zero_int = Zero_int;
+
+fun less_eq_num (Bit1 m) (Bit0 n) = less_num m n
+ | less_eq_num (Bit1 m) (Bit1 n) = less_eq_num m n
+ | less_eq_num (Bit0 m) (Bit1 n) = less_eq_num m n
+ | less_eq_num (Bit0 m) (Bit0 n) = less_eq_num m n
+ | less_eq_num (Bit1 m) One = false
+ | less_eq_num (Bit0 m) One = false
+ | less_eq_num One n = true
+and less_num (Bit1 m) (Bit0 n) = less_num m n
+ | less_num (Bit1 m) (Bit1 n) = less_num m n
+ | less_num (Bit0 m) (Bit1 n) = less_eq_num m n
+ | less_num (Bit0 m) (Bit0 n) = less_num m n
+ | less_num One (Bit1 n) = true
+ | less_num One (Bit0 n) = true
+ | less_num m One = false;
+
+fun less_eq_int (Neg k) (Neg l) = less_eq_num l k
+ | less_eq_int (Neg k) (Pos l) = true
+ | less_eq_int (Neg k) Zero_int = true
+ | less_eq_int (Pos k) (Neg l) = false
+ | less_eq_int (Pos k) (Pos l) = less_eq_num k l
+ | less_eq_int (Pos k) Zero_int = false
+ | less_eq_int Zero_int (Neg l) = false
+ | less_eq_int Zero_int (Pos l) = true
+ | less_eq_int Zero_int Zero_int = true;
+
+fun uminus_int (Neg m) = Pos m
+ | uminus_int (Pos m) = Neg m
+ | uminus_int Zero_int = Zero_int;
+
+fun bitM One = One
+ | bitM (Bit0 n) = Bit1 (bitM n)
+ | bitM (Bit1 n) = Bit1 (Bit0 n);
+
+fun minus_int (Neg m) (Neg n) = sub n m
+ | minus_int (Neg m) (Pos n) = Neg (plus_num m n)
+ | minus_int (Pos m) (Neg n) = Pos (plus_num m n)
+ | minus_int (Pos m) (Pos n) = sub m n
+ | minus_int Zero_int l = uminus_int l
+ | minus_int k Zero_int = k
+and sub (Bit0 m) (Bit1 n) = minus_int (dup (sub m n)) one_inta
+ | sub (Bit1 m) (Bit0 n) = plus_int (dup (sub m n)) one_inta
+ | sub (Bit1 m) (Bit1 n) = dup (sub m n)
+ | sub (Bit0 m) (Bit0 n) = dup (sub m n)
+ | sub One (Bit1 n) = Neg (Bit0 n)
+ | sub One (Bit0 n) = Neg (bitM n)
+ | sub (Bit1 m) One = Pos (Bit0 m)
+ | sub (Bit0 m) One = Pos (bitM m)
+ | sub One One = Zero_int
+and plus_int (Neg m) (Neg n) = Neg (plus_num m n)
+ | plus_int (Neg m) (Pos n) = sub n m
+ | plus_int (Pos m) (Neg n) = sub m n
+ | plus_int (Pos m) (Pos n) = Pos (plus_num m n)
+ | plus_int Zero_int l = l
+ | plus_int k Zero_int = k;
+
+fun divmod_step_int l (q, r) =
+ (if less_eq_int (Pos l) r
+ then (plus_int (times_int (Pos (Bit0 One)) q) one_inta, minus_int r (Pos l))
+ else (times_int (Pos (Bit0 One)) q, r));
+
+fun divmod_int (Bit1 m) (Bit1 n) =
+ (if less_num m n then (Zero_int, Pos (Bit1 m))
+ else divmod_step_int (Bit1 n) (divmod_int (Bit1 m) (Bit0 (Bit1 n))))
+ | divmod_int (Bit0 m) (Bit1 n) =
+ (if less_eq_num m n then (Zero_int, Pos (Bit0 m))
+ else divmod_step_int (Bit1 n) (divmod_int (Bit0 m) (Bit0 (Bit1 n))))
+ | divmod_int (Bit1 m) (Bit0 n) =
+ let
+ val (q, r) = divmod_int m n;
+ in
+ (q, plus_int (times_int (Pos (Bit0 One)) r) one_inta)
+ end
+ | divmod_int (Bit0 m) (Bit0 n) = let
+ val (q, r) = divmod_int m n;
+ in
+ (q, times_int (Pos (Bit0 One)) r)
+ end
+ | divmod_int One (Bit1 n) = (Zero_int, Pos One)
+ | divmod_int One (Bit0 n) = (Zero_int, Pos One)
+ | divmod_int (Bit1 m) One = (Pos (Bit1 m), Zero_int)
+ | divmod_int (Bit0 m) One = (Pos (Bit0 m), Zero_int)
+ | divmod_int One One = (Pos One, Zero_int);
+
+fun snd (x1, x2) = x2;
+
+fun equal_num (Bit0 x2) (Bit1 x3) = false
+ | equal_num (Bit1 x3) (Bit0 x2) = false
+ | equal_num One (Bit1 x3) = false
+ | equal_num (Bit1 x3) One = false
+ | equal_num One (Bit0 x2) = false
+ | equal_num (Bit0 x2) One = false
+ | equal_num (Bit1 x3) (Bit1 y3) = equal_num x3 y3
+ | equal_num (Bit0 x2) (Bit0 y2) = equal_num x2 y2
+ | equal_num One One = true;
+
+fun equal_int (Neg k) (Neg l) = equal_num k l
+ | equal_int (Neg k) (Pos l) = false
+ | equal_int (Neg k) Zero_int = false
+ | equal_int (Pos k) (Neg l) = false
+ | equal_int (Pos k) (Pos l) = equal_num k l
+ | equal_int (Pos k) Zero_int = false
+ | equal_int Zero_int (Neg l) = false
+ | equal_int Zero_int (Pos l) = false
+ | equal_int Zero_int Zero_int = true;
+
+fun adjust_mod l r = (if equal_int r Zero_int then Zero_int else minus_int l r);
+
+fun modulo_int (Neg m) (Neg n) = uminus_int (snd (divmod_int m n))
+ | modulo_int (Pos m) (Neg n) =
+ uminus_int (adjust_mod (Pos n) (snd (divmod_int m n)))
+ | modulo_int (Neg m) (Pos n) = adjust_mod (Pos n) (snd (divmod_int m n))
+ | modulo_int (Pos m) (Pos n) = snd (divmod_int m n)
+ | modulo_int k (Neg One) = Zero_int
+ | modulo_int k (Pos One) = Zero_int
+ | modulo_int Zero_int k = Zero_int
+ | modulo_int k Zero_int = k;
+
+fun fst (x1, x2) = x1;
+
+fun of_bool A_ true = one (one_zero_neq_one A_)
+ | of_bool A_ false = zero (zero_zero_neq_one A_);
+
+fun adjust_div (q, r) =
+ plus_int q (of_bool zero_neq_one_int (not (equal_int r Zero_int)));
+
+fun divide_int (Neg m) (Neg n) = fst (divmod_int m n)
+ | divide_int (Pos m) (Neg n) = uminus_int (adjust_div (divmod_int m n))
+ | divide_int (Neg m) (Pos n) = uminus_int (adjust_div (divmod_int m n))
+ | divide_int (Pos m) (Pos n) = fst (divmod_int m n)
+ | divide_int k (Neg One) = uminus_int k
+ | divide_int k (Pos One) = k
+ | divide_int Zero_int k = Zero_int
+ | divide_int k Zero_int = Zero_int;
+
+fun less_int (Neg k) (Neg l) = less_num l k
+ | less_int (Neg k) (Pos l) = true
+ | less_int (Neg k) Zero_int = true
+ | less_int (Pos k) (Neg l) = false
+ | less_int (Pos k) (Pos l) = less_num k l
+ | less_int (Pos k) Zero_int = false
+ | less_int Zero_int (Neg l) = false
+ | less_int Zero_int (Pos l) = true
+ | less_int Zero_int Zero_int = false;
+
+fun integer_of_int k =
+ (if less_int k Zero_int then IntInf.~ (integer_of_int (uminus_int k))
+ else (if equal_int k Zero_int then (0 : IntInf.int)
+ else let
+ val l =
+ IntInf.* ((2 : IntInf.int), integer_of_int
+ (divide_int k (Pos (Bit0 One))));
+ val j = modulo_int k (Pos (Bit0 One));
+ in
+ (if equal_int j Zero_int then l
+ else IntInf.+ (l, (1 : IntInf.int)))
+ end));
+
+fun max A_ a b = (if less_eq A_ a b then b else a);
+
+fun nat k = Nat (max ord_integer (0 : IntInf.int) (integer_of_int k));
+
+fun plus_nat m n = Nat (IntInf.+ (integer_of_nat m, integer_of_nat n));
+
+val one_nat : nat = Nat (1 : IntInf.int);
+
+fun suc n = plus_nat n one_nat;
+
+fun minus_nat m n =
+ Nat (max ord_integer (0 : IntInf.int)
+ (IntInf.- (integer_of_nat m, integer_of_nat n)));
+
+val zero_nat : nat = Nat (0 : IntInf.int);
+
+fun nth (x :: xs) n =
+ (if equal_nata n zero_nat then x else nth xs (minus_nat n one_nat));
+
+fun less_nat m n = IntInf.< (integer_of_nat m, integer_of_nat n);
+
+fun upt i j = (if less_nat i j then i :: upt (suc i) j else []);
+
+fun zip (x :: xs) (y :: ys) = (x, y) :: zip xs ys
+ | zip xs [] = []
+ | zip [] ys = [];
+
+fun fold f (x :: xs) s = fold f xs (f x s)
+ | fold f [] s = s;
+
+fun maps f [] = []
+ | maps f (x :: xs) = f x @ maps f xs;
+
+fun null [] = true
+ | null (x :: xs) = false;
+
+fun foldr f [] = id
+ | foldr f (x :: xs) = f x o foldr f xs;
+
+fun map_of A_ ((l, v) :: ps) k = (if eq A_ l k then SOME v else map_of A_ ps k)
+ | map_of A_ [] k = NONE;
+
+fun concat xss = foldr (fn a => fn b => a @ b) xss [];
+
+fun filter p [] = []
+ | filter p (x :: xs) = (if p x then x :: filter p xs else filter p xs);
+
+fun member A_ [] y = false
+ | member A_ (x :: xs) y = eq A_ x y orelse member A_ xs y;
+
+fun listMem A_ xa (x :: xs) = eq A_ xa x orelse listMem A_ xa xs
+ | listMem A_ x [] = false;
+
+fun list_ex p [] = false
+ | list_ex p (x :: xs) = p x orelse list_ex p xs;
+
+fun map f [] = []
+ | map f (x21 :: x22) = f x21 :: map f x22;
+
+fun product [] uu = []
+ | product (x :: xs) ys = map (fn a => (x, a)) ys @ product xs ys;
+
+fun distinct A_ [] = true
+ | distinct A_ (x :: xs) = not (member A_ xs x) andalso distinct A_ xs;
+
+fun bigOr [] = Bot
+ | bigOr (f :: fs) = Or (f, bigOr fs);
+
+fun is_none (SOME x) = false
+ | is_none NONE = true;
+
+fun integer_of_char (Chara (b0, b1, b2, b3, b4, b5, b6, b7)) =
+ IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (of_bool
+ zero_neq_one_integer
+ b7, (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b6), (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b5), (2 : IntInf.int)), of_bool
+ zero_neq_one_integer
+ b4), (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b3), (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b2), (2 : IntInf.int)), of_bool
+ zero_neq_one_integer
+ b1), (2 : IntInf.int)), of_bool zero_neq_one_integer b0);
+
+fun implode cs =
+ (String.implode
+ o List.map (fn k => if 0 <= k andalso k < 128 then (Char.chr o IntInf.toInt) k else raise Fail "Non-ASCII character in literal"))
+ (map integer_of_char cs);
+
+fun bigAnd [] = Not Bot
+ | bigAnd (f :: fs) = And (f, bigAnd fs);
+
+fun gen_length n (x :: xs) = gen_length (suc n) xs
+ | gen_length n [] = n;
+
+fun map_filter f [] = []
+ | map_filter f (x :: xs) =
+ (case f x of NONE => map_filter f xs | SOME y => y :: map_filter f xs);
+
+fun find_index uu [] = zero_nat
+ | find_index p (x :: xs) =
+ (if p x then zero_nat else plus_nat (find_index p xs) one_nat);
+
+fun index A_ xs = (fn a => find_index (fn x => eq A_ x a) xs);
+
+fun the (SOME x2) = x2;
+
+fun is_standard_effect x = (fn (pre, (_, (_, _))) => null pre) x;
+
+fun list_all p [] = true
+ | list_all p (x :: xs) = p x andalso list_all p xs;
+
+fun is_standard_operator x =
+ (fn (_, (_, (effects, _))) => list_all is_standard_effect effects) x;
+
+fun consistent_map_lists A_ xs1 xs2 =
+ list_all
+ (fn (x1, _) =>
+ list_all (fn (y1, y2) => (if eq A_ x1 y1 then eq A_ x1 y2 else true)) xs2)
+ xs1;
+
+fun implicit_pres effs =
+ map_filter
+ (fn x =>
+ (if let
+ val (_, (_, (vpre, _))) = x;
+ in
+ not (is_none vpre)
+ end
+ then SOME let
+ val (_, (v, (vpre, _))) = x;
+ in
+ (v, the vpre)
+ end
+ else NONE))
+ effs;
+
+fun consistent_pres_op opa =
+ let
+ val (_, (pres, (effs, _))) = opa;
+ in
+ distinct equal_nat (map fst (pres @ implicit_pres effs)) andalso
+ consistent_map_lists equal_nat pres (implicit_pres effs)
+ end;
+
+fun astDom problem = let
+ val (d, (_, (_, _))) = problem;
+ in
+ d
+ end;
+
+fun size_list x = gen_length zero_nat x;
+
+fun numVars problem = size_list (astDom problem);
+
+fun numVals problem x = size_list (snd (snd (nth (astDom problem) x)));
+
+fun wf_partial_state problem ps =
+ distinct equal_nat (map fst ps) andalso
+ list_all
+ (fn (x, v) =>
+ less_nat x (numVars problem) andalso less_nat v (numVals problem x))
+ ps;
+
+fun wf_operator problem =
+ (fn (_, (pres, (effs, _))) =>
+ wf_partial_state problem pres andalso
+ (distinct equal_nat (map (fn (_, (v, (_, _))) => v) effs) andalso
+ list_all
+ (fn (epres, (x, (vp, v))) =>
+ wf_partial_state problem epres andalso
+ (less_nat x (numVars problem) andalso
+ (less_nat v (numVals problem x) andalso
+ (case vp of NONE => true
+ | SOME va => less_nat va (numVals problem x)))))
+ effs));
+
+fun ast_delta problem = let
+ val (_, (_, (_, delta))) = problem;
+ in
+ delta
+ end;
+
+fun astI problem = let
+ val (_, (i, (_, _))) = problem;
+ in
+ i
+ end;
+
+fun astG problem = let
+ val (_, (_, (g, _))) = problem;
+ in
+ g
+ end;
+
+fun less_eq_nat m n = IntInf.<= (integer_of_nat m, integer_of_nat n);
+
+fun all_interval_nat p i j =
+ less_eq_nat j i orelse p i andalso all_interval_nat p (suc i) j;
+
+fun well_formed problem =
+ equal_nata (size_list (astI problem)) (numVars problem) andalso
+ (all_interval_nat
+ (fn x => less_nat (nth (astI problem) x) (numVals problem x)) zero_nat
+ (numVars problem) andalso
+ (wf_partial_state problem (astG problem) andalso
+ (distinct (equal_list equal_char) (map fst (ast_delta problem)) andalso
+ list_all (wf_operator problem) (ast_delta problem))));
+
+fun rem_effect_implicit_pres (preconds, (v, (implicit_pre, eff))) =
+ (preconds, (v, (NONE, eff)));
+
+fun rem_implicit_pres (name, (preconds, (effects, cost))) =
+ (name,
+ (implicit_pres effects @ preconds,
+ (map rem_effect_implicit_pres effects, cost)));
+
+fun rem_implicit_pres_ops (vars, (init, (goal, ops))) =
+ (vars, (init, (goal, map rem_implicit_pres ops)));
+
+fun operators_of
+ (Strips_problem_ext (variables_of, operators_of, initial_of, goal_of, more)) =
+ operators_of;
+
+fun encode_interfering_operator_pair_exclusion A_ pi k op_1 op_2 =
+ let
+ val ops = operators_of pi;
+ in
+ Or (Not (Atom (Operator
+ (k, index (equal_strips_operator_ext A_ equal_unit) ops
+ op_1))),
+ Not (Atom (Operator
+ (k, index (equal_strips_operator_ext A_ equal_unit) ops
+ op_2))))
+ end;
+
+fun delete_effects_of
+ (Strips_operator_ext
+ (precondition_of, add_effects_of, delete_effects_of, more))
+ = delete_effects_of;
+
+fun precondition_of
+ (Strips_operator_ext
+ (precondition_of, add_effects_of, delete_effects_of, more))
+ = precondition_of;
+
+fun are_operators_interfering A_ op_1 op_2 =
+ list_ex (fn v => list_ex (eq A_ v) (delete_effects_of op_1))
+ (precondition_of op_2) orelse
+ list_ex (fn v => list_ex (eq A_ v) (precondition_of op_1))
+ (delete_effects_of op_2);
+
+fun encode_interfering_operator_exclusion A_ pi t =
+ let
+ val ops = operators_of pi;
+ val interfering =
+ filter
+ (fn (op_1, op_2) =>
+ not (equal_nata
+ (index (equal_strips_operator_ext A_ equal_unit) ops op_1)
+ (index (equal_strips_operator_ext A_ equal_unit) ops
+ op_2)) andalso
+ are_operators_interfering A_ op_1 op_2)
+ (product ops ops);
+ in
+ foldr (fn a => fn b => And (a, b))
+ (maps (fn (op_1, op_2) =>
+ map (fn k =>
+ encode_interfering_operator_pair_exclusion A_ pi k op_1
+ op_2)
+ (upt zero_nat t))
+ interfering)
+ (Not Bot)
+ end;
+
+fun add_effects_of
+ (Strips_operator_ext
+ (precondition_of, add_effects_of, delete_effects_of, more))
+ = add_effects_of;
+
+fun variables_of
+ (Strips_problem_ext (variables_of, operators_of, initial_of, goal_of, more)) =
+ variables_of;
+
+fun encode_positive_transition_frame_axiom A_ pi t v =
+ let
+ val vs = variables_of pi;
+ val ops = operators_of pi;
+ val adding_operators =
+ filter (fn opa => listMem A_ v (add_effects_of opa)) ops;
+ in
+ Or (Atom (State (t, index A_ vs v)),
+ Or (Not (Atom (State (suc t, index A_ vs v))),
+ bigOr (map (fn opa =>
+ Atom (Operator
+ (t, index
+(equal_strips_operator_ext A_ equal_unit) ops opa)))
+ adding_operators)))
+ end;
+
+fun encode_negative_transition_frame_axiom A_ pi t v =
+ let
+ val vs = variables_of pi;
+ val ops = operators_of pi;
+ val deleting_operators =
+ filter (fn opa => listMem A_ v (delete_effects_of opa)) ops;
+ in
+ Or (Not (Atom (State (t, index A_ vs v))),
+ Or (Atom (State (suc t, index A_ vs v)),
+ bigOr (map (fn opa =>
+ Atom (Operator
+ (t, index
+(equal_strips_operator_ext A_ equal_unit) ops opa)))
+ deleting_operators)))
+ end;
+
+fun encode_all_frame_axioms A_ pi t =
+ let
+ val l = product (upt zero_nat t) (variables_of pi);
+ in
+ bigAnd
+ (map (fn (a, b) => encode_negative_transition_frame_axiom A_ pi a b) l @
+ map (fn (a, b) => encode_positive_transition_frame_axiom A_ pi a b) l)
+ end;
+
+fun initial_of
+ (Strips_problem_ext (variables_of, operators_of, initial_of, goal_of, more)) =
+ initial_of;
+
+fun encode_state_variable t k v =
+ (case v of SOME true => Atom (State (t, k))
+ | SOME false => Not (Atom (State (t, k))));
+
+fun encode_initial_state A_ pi =
+ let
+ val i = initial_of pi;
+ val vs = variables_of pi;
+ in
+ bigAnd
+ (map_filter
+ (fn x =>
+ (if not (is_none (i x))
+ then SOME (Or (encode_state_variable zero_nat (index A_ vs x) (i x),
+ Bot))
+ else NONE))
+ vs)
+ end;
+
+fun goal_of
+ (Strips_problem_ext (variables_of, operators_of, initial_of, goal_of, more)) =
+ goal_of;
+
+fun encode_goal_state A_ pi t =
+ let
+ val vs = variables_of pi;
+ val g = goal_of pi;
+ in
+ bigAnd
+ (map_filter
+ (fn x =>
+ (if not (is_none (g x))
+ then SOME (Or (encode_state_variable t (index A_ vs x) (g x), Bot))
+ else NONE))
+ vs)
+ end;
+
+fun encode_operator_precondition A_ pi t opa =
+ let
+ val vs = variables_of pi;
+ val ops = operators_of pi;
+ in
+ bigAnd
+ (map (fn v =>
+ Or (Not (Atom (Operator
+ (t, index (equal_strips_operator_ext A_ equal_unit)
+ ops opa))),
+ Atom (State (t, index A_ vs v))))
+ (precondition_of opa))
+ end;
+
+fun encode_all_operator_preconditions A_ pi ops t =
+ let
+ val l = product (upt zero_nat t) ops;
+ in
+ foldr ((fn a => fn b => And (a, b)) o
+ (fn (a, b) => encode_operator_precondition A_ pi a b))
+ l (Not Bot)
+ end;
+
+fun encode_operator_effect A_ pi t opa =
+ let
+ val vs = variables_of pi;
+ val ops = operators_of pi;
+ in
+ bigAnd
+ (map (fn v =>
+ Or (Not (Atom (Operator
+ (t, index (equal_strips_operator_ext A_ equal_unit)
+ ops opa))),
+ Atom (State (suc t, index A_ vs v))))
+ (add_effects_of opa) @
+ map (fn v =>
+ Or (Not (Atom (Operator
+ (t, index (equal_strips_operator_ext A_
+ equal_unit)
+ ops opa))),
+ Not (Atom (State (suc t, index A_ vs v)))))
+ (delete_effects_of opa))
+ end;
+
+fun encode_all_operator_effects A_ pi ops t =
+ let
+ val l = product (upt zero_nat t) ops;
+ in
+ foldr ((fn a => fn b => And (a, b)) o
+ (fn (a, b) => encode_operator_effect A_ pi a b))
+ l (Not Bot)
+ end;
+
+fun encode_operators A_ pi t =
+ let
+ val ops = operators_of pi;
+ in
+ And (encode_all_operator_preconditions A_ pi ops t,
+ encode_all_operator_effects A_ pi ops t)
+ end;
+
+fun encode_problem_with_operator_interference_exclusion A_ pi t =
+ And (encode_initial_state A_ pi,
+ And (encode_operators A_ pi t,
+ And (encode_all_frame_axioms A_ pi t,
+ And (encode_interfering_operator_exclusion A_ pi t,
+ encode_goal_state A_ pi t))));
+
+fun variables_ofa
+ (Sas_plus_problem_ext
+ (variables_of, operators_of, initial_of, goal_of, range_of, more))
+ = variables_of;
+
+fun operators_ofa
+ (Sas_plus_problem_ext
+ (variables_of, operators_of, initial_of, goal_of, range_of, more))
+ = operators_of;
+
+fun initial_ofa
+ (Sas_plus_problem_ext
+ (variables_of, operators_of, initial_of, goal_of, range_of, more))
+ = initial_of;
+
+fun goal_ofa
+ (Sas_plus_problem_ext
+ (variables_of, operators_of, initial_of, goal_of, range_of, more))
+ = goal_of;
+
+fun range_of
+ (Sas_plus_problem_ext
+ (variables_of, operators_of, initial_of, goal_of, range_of, more))
+ = range_of;
+
+fun possible_assignments_for psi v =
+ map (fn a => (v, a)) (the (range_of psi v));
+
+fun state_to_strips_state A_ B_ psi s =
+ let
+ val defined = filter (fn v => not (is_none (s v))) (variables_ofa psi);
+ in
+ map_of (equal_prod A_ B_)
+ (map (fn (v, a) => ((v, a), eq B_ (the (s v)) a))
+ (maps (possible_assignments_for psi) defined))
+ end;
+
+fun precondition_ofa (Sas_plus_operator_ext (precondition_of, effect_of, more))
+ = precondition_of;
+
+fun effect_of (Sas_plus_operator_ext (precondition_of, effect_of, more)) =
+ effect_of;
+
+fun sasp_op_to_strips B_ psi opa =
+ let
+ val pre = precondition_ofa opa;
+ val add = effect_of opa;
+ val delete =
+ maps (fn (v, a) =>
+ map_filter
+ (fn x => (if not (eq B_ a x) then SOME (v, x) else NONE))
+ (the (range_of psi v)))
+ (effect_of opa);
+ in
+ Strips_operator_ext (pre, add, delete, ())
+ end;
+
+fun sas_plus_problem_to_strips_problem A_ B_ psi =
+ let
+ val vs =
+ maps (fn v => map (fn asa => asa) (possible_assignments_for psi v))
+ (variables_ofa psi);
+ val ops = map (sasp_op_to_strips B_ psi) (operators_ofa psi);
+ val i = state_to_strips_state A_ B_ psi (initial_ofa psi);
+ val g = state_to_strips_state A_ B_ psi (goal_ofa psi);
+ in
+ Strips_problem_ext (vs, ops, i, g, ())
+ end;
+
+fun abs_ast_variable_section problem =
+ upt zero_nat (size_list (astDom problem));
+
+fun abs_ast_operator x =
+ (fn (_, (preconditions, (effects, _))) =>
+ Sas_plus_operator_ext
+ (preconditions, map (fn (_, a) => let
+ val (v, aa) = a;
+ val (_, ab) = aa;
+in
+ (v, ab)
+end)
+ effects,
+ ()))
+ x;
+
+fun abs_ast_operator_section problem = map abs_ast_operator (ast_delta problem);
+
+fun abs_ast_initial_state problem =
+ map_of equal_nat
+ (zip (upt zero_nat (size_list (astI problem))) (astI problem));
+
+fun abs_range_map problem =
+ map_of equal_nat
+ (zip (abs_ast_variable_section problem)
+ (map ((fn vals => upt zero_nat (size_list vals)) o snd o snd)
+ (astDom problem)));
+
+fun abs_ast_goal problem = map_of equal_nat (astG problem);
+
+fun abs_prob problem =
+ Sas_plus_problem_ext
+ (abs_ast_variable_section problem, abs_ast_operator_section problem,
+ abs_ast_initial_state problem, abs_ast_goal problem,
+ abs_range_map problem, ());
+
+fun times_nat m n = Nat (IntInf.* (integer_of_nat m, integer_of_nat n));
+
+fun var_to_dimacs h n_ops (State (t, k)) =
+ plus_nat (plus_nat (plus_nat one_nat (times_nat n_ops h)) t) (times_nat k h)
+ | var_to_dimacs h n_ops (Operator (t, k)) =
+ plus_nat (plus_nat one_nat t) (times_nat k h);
+
+val empty_sasp_action : ('a, 'b, unit) sas_plus_operator_ext =
+ Sas_plus_operator_ext ([], [], ());
+
+fun prob_with_noop pi =
+ Sas_plus_problem_ext
+ (variables_ofa pi, empty_sasp_action :: operators_ofa pi, initial_ofa pi,
+ goal_ofa pi, range_of pi, ());
+
+fun map_formula f (Atom x1) = Atom (f x1)
+ | map_formula f Bot = Bot
+ | map_formula f (Not x3) = Not (map_formula f x3)
+ | map_formula f (And (x41, x42)) = And (map_formula f x41, map_formula f x42)
+ | map_formula f (Or (x51, x52)) = Or (map_formula f x51, map_formula f x52)
+ | map_formula f (Imp (x61, x62)) = Imp (map_formula f x61, map_formula f x62);
+
+fun apsnd f (x, y) = (x, f y);
+
+fun divmod_integer k l =
+ (if ((k : IntInf.int) = (0 : IntInf.int))
+ then ((0 : IntInf.int), (0 : IntInf.int))
+ else (if IntInf.< ((0 : IntInf.int), l)
+ then (if IntInf.< ((0 : IntInf.int), k)
+ then IntInf.divMod (IntInf.abs k, IntInf.abs l)
+ else let
+ val (r, s) =
+ IntInf.divMod (IntInf.abs k, IntInf.abs l);
+ in
+ (if ((s : IntInf.int) = (0 : IntInf.int))
+ then (IntInf.~ r, (0 : IntInf.int))
+ else (IntInf.- (IntInf.~ r, (1 : IntInf.int)),
+ IntInf.- (l, s)))
+ end)
+ else (if ((l : IntInf.int) = (0 : IntInf.int))
+ then ((0 : IntInf.int), k)
+ else apsnd IntInf.~
+ (if IntInf.< (k, (0 : IntInf.int))
+ then IntInf.divMod (IntInf.abs k, IntInf.abs l)
+ else let
+ val (r, s) =
+ IntInf.divMod (IntInf.abs k, IntInf.abs l);
+ in
+ (if ((s : IntInf.int) = (0 : IntInf.int))
+ then (IntInf.~ r, (0 : IntInf.int))
+ else (IntInf.- (IntInf.~
+ r, (1 : IntInf.int)),
+ IntInf.- (IntInf.~ l, s)))
+ end))));
+
+fun int_of_integer k =
+ (if IntInf.< (k, (0 : IntInf.int))
+ then uminus_int (int_of_integer (IntInf.~ k))
+ else (if ((k : IntInf.int) = (0 : IntInf.int)) then Zero_int
+ else let
+ val (l, j) = divmod_integer k (2 : IntInf.int);
+ val la = times_int (Pos (Bit0 One)) (int_of_integer l);
+ in
+ (if ((j : IntInf.int) = (0 : IntInf.int)) then la
+ else plus_int la one_inta)
+ end));
+
+fun int_of_nat n = int_of_integer (integer_of_nat n);
+
+fun disj_to_dimacs (Or (phi_1, phi_2)) =
+ disj_to_dimacs phi_1 @ disj_to_dimacs phi_2
+ | disj_to_dimacs Bot = []
+ | disj_to_dimacs (Not Bot) = [uminus_int one_inta, one_inta]
+ | disj_to_dimacs (Atom v) = [int_of_nat v]
+ | disj_to_dimacs (Not (Atom v)) = [uminus_int (int_of_nat v)];
+
+fun cnf_to_dimacs (And (phi_1, phi_2)) =
+ cnf_to_dimacs phi_1 @ cnf_to_dimacs phi_2
+ | cnf_to_dimacs (Atom v) = [disj_to_dimacs (Atom v)]
+ | cnf_to_dimacs Bot = [disj_to_dimacs Bot]
+ | cnf_to_dimacs (Not v) = [disj_to_dimacs (Not v)]
+ | cnf_to_dimacs (Or (v, va)) = [disj_to_dimacs (Or (v, va))]
+ | cnf_to_dimacs (Imp (v, va)) = [disj_to_dimacs (Imp (v, va))];
+
+fun sASP_to_DIMACS h prob =
+ cnf_to_dimacs
+ (map_formula (var_to_dimacs (suc h) (suc (size_list (ast_delta prob))))
+ (encode_problem_with_operator_interference_exclusion
+ (equal_prod equal_nat equal_nat)
+ (sas_plus_problem_to_strips_problem equal_nat equal_nat
+ (prob_with_noop (abs_prob prob)))
+ h));
+
+fun sASP_to_DIMACSa h prob = sASP_to_DIMACS h (rem_implicit_pres_ops prob);
+
+fun encode h prob =
+ (if well_formed prob
+ then (if list_all consistent_pres_op (ast_delta prob)
+ then (if list_all is_standard_operator (ast_delta prob)
+ then Inl (sASP_to_DIMACSa h prob)
+ else Inr "Error: Conditional effects!")
+ else Inr "Error: Preconditions inconsistent")
+ else Inr "Error: Problem malformed!");
+
+fun abs_int i = (if less_int i Zero_int then uminus_int i else i);
+
+fun max_var xs =
+ fold (fn x => fn y =>
+ (if less_eq_int (abs_int y) (abs_int x) then abs_int x else y))
+ xs Zero_int;
+
+fun bit_cut_integer k =
+ (if ((k : IntInf.int) = (0 : IntInf.int)) then ((0 : IntInf.int), false)
+ else let
+ val (r, s) =
+ IntInf.divMod (IntInf.abs k, IntInf.abs (2 : IntInf.int));
+ in
+ ((if IntInf.< ((0 : IntInf.int), k) then r
+ else IntInf.- (IntInf.~ r, s)),
+ ((s : IntInf.int) = (1 : IntInf.int)))
+ end);
+
+fun char_of_integer k = let
+ val (q0, b0) = bit_cut_integer k;
+ val (q1, b1) = bit_cut_integer q0;
+ val (q2, b2) = bit_cut_integer q1;
+ val (q3, b3) = bit_cut_integer q2;
+ val (q4, b4) = bit_cut_integer q3;
+ val (q5, b5) = bit_cut_integer q4;
+ val (q6, b6) = bit_cut_integer q5;
+ val a = bit_cut_integer q6;
+ val (_, aa) = a;
+ in
+ Chara (b0, b1, b2, b3, b4, b5, b6, aa)
+ end;
+
+fun explode s =
+ map char_of_integer
+ ((List.map (fn c => let val k = Char.ord c in if k < 128 then IntInf.fromInt k else raise Fail "Non-ASCII character in literal" end)
+ o String.explode)
+ s);
+
+fun nat_of_integer k = Nat (max ord_integer (0 : IntInf.int) k);
+
+fun char_of_nat x = (char_of_integer o integer_of_nat) x;
+
+fun nat_opt_of_integer i =
+ (if IntInf.<= ((0 : IntInf.int), i) then SOME (nat_of_integer i) else NONE);
+
+end; (*struct exported*)
diff --git a/thys/Verified_SAT_Based_AI_Planning/code/generated/decode_DIMACS_model.sml b/thys/Verified_SAT_Based_AI_Planning/code/generated/decode_DIMACS_model.sml
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/code/generated/decode_DIMACS_model.sml
@@ -0,0 +1,1377 @@
+structure exported : sig
+ type num
+ type int
+ type nat
+ val integer_of_nat : nat -> IntInf.int
+ type char
+ datatype ('a, 'b) sum = Inl of 'a | Inr of 'b
+ val integer_of_int : int -> IntInf.int
+ val nat : int -> nat
+ val concat : ('a list) list -> 'a list
+ val implode : char list -> string
+ val size_list : 'a list -> nat
+ val int_of_integer : IntInf.int -> int
+ val decode :
+ int list ->
+ nat ->
+ (char list * (nat option * (char list) list)) list *
+ (nat list *
+ ((nat * nat) list *
+ (char list *
+ ((nat * nat) list *
+ (((nat * nat) list * (nat * (nat option * nat))) list *
+ nat))) list)) ->
+ (((char list) list), string) sum
+ val max_var : int list -> int
+ val explode : string -> char list
+ val nat_of_integer : IntInf.int -> nat
+ val char_of_nat : nat -> char
+ val nat_opt_of_integer : IntInf.int -> nat option
+end = struct
+
+datatype num = One | Bit0 of num | Bit1 of num;
+
+fun equal_num (Bit0 x2) (Bit1 x3) = false
+ | equal_num (Bit1 x3) (Bit0 x2) = false
+ | equal_num One (Bit1 x3) = false
+ | equal_num (Bit1 x3) One = false
+ | equal_num One (Bit0 x2) = false
+ | equal_num (Bit0 x2) One = false
+ | equal_num (Bit1 x3) (Bit1 y3) = equal_num x3 y3
+ | equal_num (Bit0 x2) (Bit0 y2) = equal_num x2 y2
+ | equal_num One One = true;
+
+datatype int = Zero_int | Pos of num | Neg of num;
+
+fun equal_inta (Neg k) (Neg l) = equal_num k l
+ | equal_inta (Neg k) (Pos l) = false
+ | equal_inta (Neg k) Zero_int = false
+ | equal_inta (Pos k) (Neg l) = false
+ | equal_inta (Pos k) (Pos l) = equal_num k l
+ | equal_inta (Pos k) Zero_int = false
+ | equal_inta Zero_int (Neg l) = false
+ | equal_inta Zero_int (Pos l) = false
+ | equal_inta Zero_int Zero_int = true;
+
+type 'a equal = {equal : 'a -> 'a -> bool};
+val equal = #equal : 'a equal -> 'a -> 'a -> bool;
+
+val equal_int = {equal = equal_inta} : int equal;
+
+val one_inta : int = Pos One;
+
+type 'a one = {one : 'a};
+val one = #one : 'a one -> 'a;
+
+val one_int = {one = one_inta} : int one;
+
+type 'a zero = {zero : 'a};
+val zero = #zero : 'a zero -> 'a;
+
+val zero_int = {zero = Zero_int} : int zero;
+
+fun less_eq_num (Bit1 m) (Bit0 n) = less_num m n
+ | less_eq_num (Bit1 m) (Bit1 n) = less_eq_num m n
+ | less_eq_num (Bit0 m) (Bit1 n) = less_eq_num m n
+ | less_eq_num (Bit0 m) (Bit0 n) = less_eq_num m n
+ | less_eq_num (Bit1 m) One = false
+ | less_eq_num (Bit0 m) One = false
+ | less_eq_num One n = true
+and less_num (Bit1 m) (Bit0 n) = less_num m n
+ | less_num (Bit1 m) (Bit1 n) = less_num m n
+ | less_num (Bit0 m) (Bit1 n) = less_eq_num m n
+ | less_num (Bit0 m) (Bit0 n) = less_num m n
+ | less_num One (Bit1 n) = true
+ | less_num One (Bit0 n) = true
+ | less_num m One = false;
+
+fun less_eq_int (Neg k) (Neg l) = less_eq_num l k
+ | less_eq_int (Neg k) (Pos l) = true
+ | less_eq_int (Neg k) Zero_int = true
+ | less_eq_int (Pos k) (Neg l) = false
+ | less_eq_int (Pos k) (Pos l) = less_eq_num k l
+ | less_eq_int (Pos k) Zero_int = false
+ | less_eq_int Zero_int (Neg l) = false
+ | less_eq_int Zero_int (Pos l) = true
+ | less_eq_int Zero_int Zero_int = true;
+
+type 'a ord = {less_eq : 'a -> 'a -> bool, less : 'a -> 'a -> bool};
+val less_eq = #less_eq : 'a ord -> 'a -> 'a -> bool;
+val less = #less : 'a ord -> 'a -> 'a -> bool;
+
+fun less_int (Neg k) (Neg l) = less_num l k
+ | less_int (Neg k) (Pos l) = true
+ | less_int (Neg k) Zero_int = true
+ | less_int (Pos k) (Neg l) = false
+ | less_int (Pos k) (Pos l) = less_num k l
+ | less_int (Pos k) Zero_int = false
+ | less_int Zero_int (Neg l) = false
+ | less_int Zero_int (Pos l) = true
+ | less_int Zero_int Zero_int = false;
+
+val ord_int = {less_eq = less_eq_int, less = less_int} : int ord;
+
+type 'a preorder = {ord_preorder : 'a ord};
+val ord_preorder = #ord_preorder : 'a preorder -> 'a ord;
+
+type 'a order = {preorder_order : 'a preorder};
+val preorder_order = #preorder_order : 'a order -> 'a preorder;
+
+val preorder_int = {ord_preorder = ord_int} : int preorder;
+
+val order_int = {preorder_order = preorder_int} : int order;
+
+type 'a linorder = {order_linorder : 'a order};
+val order_linorder = #order_linorder : 'a linorder -> 'a order;
+
+val linorder_int = {order_linorder = order_int} : int linorder;
+
+type 'a zero_neq_one = {one_zero_neq_one : 'a one, zero_zero_neq_one : 'a zero};
+val one_zero_neq_one = #one_zero_neq_one : 'a zero_neq_one -> 'a one;
+val zero_zero_neq_one = #zero_zero_neq_one : 'a zero_neq_one -> 'a zero;
+
+val zero_neq_one_int =
+ {one_zero_neq_one = one_int, zero_zero_neq_one = zero_int} : int zero_neq_one;
+
+datatype nat = Nat of IntInf.int;
+
+fun integer_of_nat (Nat x) = x;
+
+fun equal_nata m n = (((integer_of_nat m) : IntInf.int) = (integer_of_nat n));
+
+val equal_nat = {equal = equal_nata} : nat equal;
+
+fun less_eq_nat m n = IntInf.<= (integer_of_nat m, integer_of_nat n);
+
+fun less_nat m n = IntInf.< (integer_of_nat m, integer_of_nat n);
+
+val ord_nat = {less_eq = less_eq_nat, less = less_nat} : nat ord;
+
+val preorder_nat = {ord_preorder = ord_nat} : nat preorder;
+
+val order_nat = {preorder_order = preorder_nat} : nat order;
+
+val linorder_nat = {order_linorder = order_nat} : nat linorder;
+
+fun eq A_ a b = equal A_ a b;
+
+fun equal_lista A_ [] (x21 :: x22) = false
+ | equal_lista A_ (x21 :: x22) [] = false
+ | equal_lista A_ (x21 :: x22) (y21 :: y22) =
+ eq A_ x21 y21 andalso equal_lista A_ x22 y22
+ | equal_lista A_ [] [] = true;
+
+fun equal_list A_ = {equal = equal_lista A_} : ('a list) equal;
+
+datatype color = Red | Black;
+
+fun equal_colora Red Black = false
+ | equal_colora Black Red = false
+ | equal_colora Black Black = true
+ | equal_colora Red Red = true;
+
+val equal_color = {equal = equal_colora} : color equal;
+
+fun equal_bool p true = p
+ | equal_bool p false = not p
+ | equal_bool true p = p
+ | equal_bool false p = not p;
+
+datatype char = Chara of bool * bool * bool * bool * bool * bool * bool * bool;
+
+fun equal_chara (Chara (x1, x2, x3, x4, x5, x6, x7, x8))
+ (Chara (y1, y2, y3, y4, y5, y6, y7, y8)) =
+ equal_bool x1 y1 andalso
+ (equal_bool x2 y2 andalso
+ (equal_bool x3 y3 andalso
+ (equal_bool x4 y4 andalso
+ (equal_bool x5 y5 andalso
+ (equal_bool x6 y6 andalso
+ (equal_bool x7 y7 andalso equal_bool x8 y8))))));
+
+val equal_char = {equal = equal_chara} : char equal;
+
+fun equal_optiona A_ NONE (SOME x2) = false
+ | equal_optiona A_ (SOME x2) NONE = false
+ | equal_optiona A_ (SOME x2) (SOME y2) = eq A_ x2 y2
+ | equal_optiona A_ NONE NONE = true;
+
+fun equal_option A_ = {equal = equal_optiona A_} : ('a option) equal;
+
+fun equal_proda A_ B_ (x1, x2) (y1, y2) = eq A_ x1 y1 andalso eq B_ x2 y2;
+
+fun equal_prod A_ B_ = {equal = equal_proda A_ B_} : ('a * 'b) equal;
+
+fun equal_unita u v = true;
+
+val equal_unit = {equal = equal_unita} : unit equal;
+
+val one_integera : IntInf.int = (1 : IntInf.int);
+
+val one_integer = {one = one_integera} : IntInf.int one;
+
+val zero_integer = {zero = (0 : IntInf.int)} : IntInf.int zero;
+
+val ord_integer =
+ {less_eq = (fn a => fn b => IntInf.<= (a, b)),
+ less = (fn a => fn b => IntInf.< (a, b))}
+ : IntInf.int ord;
+
+val zero_neq_one_integer =
+ {one_zero_neq_one = one_integer, zero_zero_neq_one = zero_integer} :
+ IntInf.int zero_neq_one;
+
+datatype ('a, 'b) strips_operator_ext =
+ Strips_operator_ext of 'a list * 'a list * 'a list * 'b;
+
+fun equal_strips_operator_exta A_ B_
+ (Strips_operator_ext
+ (precondition_ofa, add_effects_ofa, delete_effects_ofa, morea))
+ (Strips_operator_ext
+ (precondition_of, add_effects_of, delete_effects_of, more))
+ = equal_lista A_ precondition_ofa precondition_of andalso
+ (equal_lista A_ add_effects_ofa add_effects_of andalso
+ (equal_lista A_ delete_effects_ofa delete_effects_of andalso
+ eq B_ morea more));
+
+fun equal_strips_operator_ext A_ B_ = {equal = equal_strips_operator_exta A_ B_}
+ : ('a, 'b) strips_operator_ext equal;
+
+datatype 'a tree = Leaf | Node of 'a tree * 'a * 'a tree;
+
+datatype cmp_val = LT | EQ | GT;
+
+datatype ('a, 'b) sum = Inl of 'a | Inr of 'b;
+
+datatype 'a formula = Atom of 'a | Bot | Not of 'a formula |
+ And of 'a formula * 'a formula | Or of 'a formula * 'a formula |
+ Imp of 'a formula * 'a formula;
+
+datatype sat_plan_variable = State of nat * nat | Operator of nat * nat;
+
+datatype ('a, 'b) strips_problem_ext =
+ Strips_problem_ext of
+ 'a list * ('a, unit) strips_operator_ext list * ('a -> bool option) *
+ ('a -> bool option) * 'b;
+
+datatype ('a, 'b, 'c) sas_plus_operator_ext =
+ Sas_plus_operator_ext of ('a * 'b) list * ('a * 'b) list * 'c;
+
+datatype ('a, 'b, 'c) sas_plus_problem_ext =
+ Sas_plus_problem_ext of
+ 'a list * ('a, 'b, unit) sas_plus_operator_ext list * ('a -> 'b option) *
+ ('a -> 'b option) * ('a -> ('b list) option) * 'c;
+
+fun id x = (fn xa => xa) x;
+
+fun cmp (A1_, A2_) x y =
+ (if less ((ord_preorder o preorder_order o order_linorder) A2_) x y then LT
+ else (if eq A1_ x y then EQ else GT));
+
+fun dup (Neg n) = Neg (Bit0 n)
+ | dup (Pos n) = Pos (Bit0 n)
+ | dup Zero_int = Zero_int;
+
+fun plus_num (Bit1 m) (Bit1 n) = Bit0 (plus_num (plus_num m n) One)
+ | plus_num (Bit1 m) (Bit0 n) = Bit1 (plus_num m n)
+ | plus_num (Bit1 m) One = Bit0 (plus_num m One)
+ | plus_num (Bit0 m) (Bit1 n) = Bit1 (plus_num m n)
+ | plus_num (Bit0 m) (Bit0 n) = Bit0 (plus_num m n)
+ | plus_num (Bit0 m) One = Bit1 m
+ | plus_num One (Bit1 n) = Bit0 (plus_num n One)
+ | plus_num One (Bit0 n) = Bit1 n
+ | plus_num One One = Bit0 One;
+
+fun times_num (Bit1 m) (Bit1 n) =
+ Bit1 (plus_num (plus_num m n) (Bit0 (times_num m n)))
+ | times_num (Bit1 m) (Bit0 n) = Bit0 (times_num (Bit1 m) n)
+ | times_num (Bit0 m) (Bit1 n) = Bit0 (times_num m (Bit1 n))
+ | times_num (Bit0 m) (Bit0 n) = Bit0 (Bit0 (times_num m n))
+ | times_num One n = n
+ | times_num m One = m;
+
+fun times_int (Neg m) (Neg n) = Pos (times_num m n)
+ | times_int (Neg m) (Pos n) = Neg (times_num m n)
+ | times_int (Pos m) (Neg n) = Neg (times_num m n)
+ | times_int (Pos m) (Pos n) = Pos (times_num m n)
+ | times_int Zero_int l = Zero_int
+ | times_int k Zero_int = Zero_int;
+
+fun uminus_int (Neg m) = Pos m
+ | uminus_int (Pos m) = Neg m
+ | uminus_int Zero_int = Zero_int;
+
+fun bitM One = One
+ | bitM (Bit0 n) = Bit1 (bitM n)
+ | bitM (Bit1 n) = Bit1 (Bit0 n);
+
+fun minus_int (Neg m) (Neg n) = sub n m
+ | minus_int (Neg m) (Pos n) = Neg (plus_num m n)
+ | minus_int (Pos m) (Neg n) = Pos (plus_num m n)
+ | minus_int (Pos m) (Pos n) = sub m n
+ | minus_int Zero_int l = uminus_int l
+ | minus_int k Zero_int = k
+and sub (Bit0 m) (Bit1 n) = minus_int (dup (sub m n)) one_inta
+ | sub (Bit1 m) (Bit0 n) = plus_int (dup (sub m n)) one_inta
+ | sub (Bit1 m) (Bit1 n) = dup (sub m n)
+ | sub (Bit0 m) (Bit0 n) = dup (sub m n)
+ | sub One (Bit1 n) = Neg (Bit0 n)
+ | sub One (Bit0 n) = Neg (bitM n)
+ | sub (Bit1 m) One = Pos (Bit0 m)
+ | sub (Bit0 m) One = Pos (bitM m)
+ | sub One One = Zero_int
+and plus_int (Neg m) (Neg n) = Neg (plus_num m n)
+ | plus_int (Neg m) (Pos n) = sub n m
+ | plus_int (Pos m) (Neg n) = sub m n
+ | plus_int (Pos m) (Pos n) = Pos (plus_num m n)
+ | plus_int Zero_int l = l
+ | plus_int k Zero_int = k;
+
+fun divmod_step_int l (q, r) =
+ (if less_eq_int (Pos l) r
+ then (plus_int (times_int (Pos (Bit0 One)) q) one_inta, minus_int r (Pos l))
+ else (times_int (Pos (Bit0 One)) q, r));
+
+fun divmod_int (Bit1 m) (Bit1 n) =
+ (if less_num m n then (Zero_int, Pos (Bit1 m))
+ else divmod_step_int (Bit1 n) (divmod_int (Bit1 m) (Bit0 (Bit1 n))))
+ | divmod_int (Bit0 m) (Bit1 n) =
+ (if less_eq_num m n then (Zero_int, Pos (Bit0 m))
+ else divmod_step_int (Bit1 n) (divmod_int (Bit0 m) (Bit0 (Bit1 n))))
+ | divmod_int (Bit1 m) (Bit0 n) =
+ let
+ val (q, r) = divmod_int m n;
+ in
+ (q, plus_int (times_int (Pos (Bit0 One)) r) one_inta)
+ end
+ | divmod_int (Bit0 m) (Bit0 n) = let
+ val (q, r) = divmod_int m n;
+ in
+ (q, times_int (Pos (Bit0 One)) r)
+ end
+ | divmod_int One (Bit1 n) = (Zero_int, Pos One)
+ | divmod_int One (Bit0 n) = (Zero_int, Pos One)
+ | divmod_int (Bit1 m) One = (Pos (Bit1 m), Zero_int)
+ | divmod_int (Bit0 m) One = (Pos (Bit0 m), Zero_int)
+ | divmod_int One One = (Pos One, Zero_int);
+
+fun snd (x1, x2) = x2;
+
+fun adjust_mod l r =
+ (if equal_inta r Zero_int then Zero_int else minus_int l r);
+
+fun modulo_int (Neg m) (Neg n) = uminus_int (snd (divmod_int m n))
+ | modulo_int (Pos m) (Neg n) =
+ uminus_int (adjust_mod (Pos n) (snd (divmod_int m n)))
+ | modulo_int (Neg m) (Pos n) = adjust_mod (Pos n) (snd (divmod_int m n))
+ | modulo_int (Pos m) (Pos n) = snd (divmod_int m n)
+ | modulo_int k (Neg One) = Zero_int
+ | modulo_int k (Pos One) = Zero_int
+ | modulo_int Zero_int k = Zero_int
+ | modulo_int k Zero_int = k;
+
+fun fst (x1, x2) = x1;
+
+fun of_bool A_ true = one (one_zero_neq_one A_)
+ | of_bool A_ false = zero (zero_zero_neq_one A_);
+
+fun adjust_div (q, r) =
+ plus_int q (of_bool zero_neq_one_int (not (equal_inta r Zero_int)));
+
+fun divide_int (Neg m) (Neg n) = fst (divmod_int m n)
+ | divide_int (Pos m) (Neg n) = uminus_int (adjust_div (divmod_int m n))
+ | divide_int (Neg m) (Pos n) = uminus_int (adjust_div (divmod_int m n))
+ | divide_int (Pos m) (Pos n) = fst (divmod_int m n)
+ | divide_int k (Neg One) = uminus_int k
+ | divide_int k (Pos One) = k
+ | divide_int Zero_int k = Zero_int
+ | divide_int k Zero_int = Zero_int;
+
+fun integer_of_int k =
+ (if less_int k Zero_int then IntInf.~ (integer_of_int (uminus_int k))
+ else (if equal_inta k Zero_int then (0 : IntInf.int)
+ else let
+ val l =
+ IntInf.* ((2 : IntInf.int), integer_of_int
+ (divide_int k (Pos (Bit0 One))));
+ val j = modulo_int k (Pos (Bit0 One));
+ in
+ (if equal_inta j Zero_int then l
+ else IntInf.+ (l, (1 : IntInf.int)))
+ end));
+
+fun max A_ a b = (if less_eq A_ a b then b else a);
+
+fun nat k = Nat (max ord_integer (0 : IntInf.int) (integer_of_int k));
+
+fun plus_nat m n = Nat (IntInf.+ (integer_of_nat m, integer_of_nat n));
+
+val one_nat : nat = Nat (1 : IntInf.int);
+
+fun suc n = plus_nat n one_nat;
+
+fun minus_nat m n =
+ Nat (max ord_integer (0 : IntInf.int)
+ (IntInf.- (integer_of_nat m, integer_of_nat n)));
+
+val zero_nat : nat = Nat (0 : IntInf.int);
+
+fun nth (x :: xs) n =
+ (if equal_nata n zero_nat then x else nth xs (minus_nat n one_nat));
+
+fun upt i j = (if less_nat i j then i :: upt (suc i) j else []);
+
+fun zip (x :: xs) (y :: ys) = (x, y) :: zip xs ys
+ | zip xs [] = []
+ | zip [] ys = [];
+
+fun find uu [] = NONE
+ | find p (x :: xs) = (if p x then SOME x else find p xs);
+
+fun fold f (x :: xs) s = fold f xs (f x s)
+ | fold f [] s = s;
+
+fun maps f [] = []
+ | maps f (x :: xs) = f x @ maps f xs;
+
+fun null [] = true
+ | null (x :: xs) = false;
+
+fun baliL (Node (Node (t1, (a, Red), t2), (b, Red), t3)) c t4 =
+ Node (Node (t1, (a, Black), t2), (b, Red), Node (t3, (c, Black), t4))
+ | baliL (Node (Leaf, (a, Red), Node (t2, (b, Red), t3))) c t4 =
+ Node (Node (Leaf, (a, Black), t2), (b, Red), Node (t3, (c, Black), t4))
+ | baliL (Node (Node (v, (vc, Black), vb), (a, Red), Node (t2, (b, Red), t3)))
+ c t4 =
+ Node (Node (Node (v, (vc, Black), vb), (a, Black), t2), (b, Red),
+ Node (t3, (c, Black), t4))
+ | baliL Leaf a t2 = Node (Leaf, (a, Black), t2)
+ | baliL (Node (Leaf, (v, Black), vb)) a t2 =
+ Node (Node (Leaf, (v, Black), vb), (a, Black), t2)
+ | baliL (Node (Leaf, va, Leaf)) a t2 =
+ Node (Node (Leaf, va, Leaf), (a, Black), t2)
+ | baliL (Node (Leaf, va, Node (v, (ve, Black), vd))) a t2 =
+ Node (Node (Leaf, va, Node (v, (ve, Black), vd)), (a, Black), t2)
+ | baliL (Node (Node (vc, (vf, Black), ve), (v, Black), vb)) a t2 =
+ Node (Node (Node (vc, (vf, Black), ve), (v, Black), vb), (a, Black), t2)
+ | baliL (Node (Node (vc, (vf, Black), ve), va, Leaf)) a t2 =
+ Node (Node (Node (vc, (vf, Black), ve), va, Leaf), (a, Black), t2)
+ | baliL (Node (Node (vc, (vf, Black), ve), va, Node (v, (vh, Black), vg))) a
+ t2 =
+ Node (Node (Node (vc, (vf, Black), ve), va, Node (v, (vh, Black), vg)),
+ (a, Black), t2)
+ | baliL (Node (v, (vc, Black), vb)) a t2 =
+ Node (Node (v, (vc, Black), vb), (a, Black), t2);
+
+fun baliR t1 a (Node (t2, (b, Red), Node (t3, (c, Red), t4))) =
+ Node (Node (t1, (a, Black), t2), (b, Red), Node (t3, (c, Black), t4))
+ | baliR t1 a (Node (Node (t2, (b, Red), t3), (c, Red), Leaf)) =
+ Node (Node (t1, (a, Black), t2), (b, Red), Node (t3, (c, Black), Leaf))
+ | baliR t1 a
+ (Node (Node (t2, (b, Red), t3), (c, Red), Node (v, (vc, Black), vb))) =
+ Node (Node (t1, (a, Black), t2), (b, Red),
+ Node (t3, (c, Black), Node (v, (vc, Black), vb)))
+ | baliR t1 a Leaf = Node (t1, (a, Black), Leaf)
+ | baliR t1 a (Node (v, (vc, Black), vb)) =
+ Node (t1, (a, Black), Node (v, (vc, Black), vb))
+ | baliR t1 a (Node (Leaf, va, Leaf)) =
+ Node (t1, (a, Black), Node (Leaf, va, Leaf))
+ | baliR t1 a (Node (Node (vb, (ve, Black), vd), va, Leaf)) =
+ Node (t1, (a, Black), Node (Node (vb, (ve, Black), vd), va, Leaf))
+ | baliR t1 a (Node (Leaf, va, Node (vc, (vf, Black), ve))) =
+ Node (t1, (a, Black), Node (Leaf, va, Node (vc, (vf, Black), ve)))
+ | baliR t1 a
+ (Node (Node (vb, (vh, Black), vg), va, Node (vc, (vf, Black), ve))) =
+ Node (t1, (a, Black),
+ Node (Node (vb, (vh, Black), vg), va, Node (vc, (vf, Black), ve)));
+
+fun paint c Leaf = Leaf
+ | paint c (Node (l, (a, uu), r)) = Node (l, (a, c), r);
+
+fun foldr f [] = id
+ | foldr f (x :: xs) = f x o foldr f xs;
+
+fun map_of A_ ((l, v) :: ps) k = (if eq A_ l k then SOME v else map_of A_ ps k)
+ | map_of A_ [] k = NONE;
+
+fun fun_upd A_ f a b = (fn x => (if eq A_ x a then b else f x));
+
+fun concat xss = foldr (fn a => fn b => a @ b) xss [];
+
+fun filter p [] = []
+ | filter p (x :: xs) = (if p x then x :: filter p xs else filter p xs);
+
+fun member A_ [] y = false
+ | member A_ (x :: xs) y = eq A_ x y orelse member A_ xs y;
+
+fun map_add m1 m2 = (fn x => (case m2 x of NONE => m1 x | SOME a => SOME a));
+
+fun upd (A1_, A2_) x y Leaf = Node (Leaf, ((x, y), Red), Leaf)
+ | upd (A1_, A2_) x y (Node (l, ((a, b), Black), r)) =
+ (case cmp (A1_, A2_) x a of LT => baliL (upd (A1_, A2_) x y l) (a, b) r
+ | EQ => Node (l, ((x, y), Black), r)
+ | GT => baliR l (a, b) (upd (A1_, A2_) x y r))
+ | upd (A1_, A2_) x y (Node (l, ((a, b), Red), r)) =
+ (case cmp (A1_, A2_) x a
+ of LT => Node (upd (A1_, A2_) x y l, ((a, b), Red), r)
+ | EQ => Node (l, ((x, y), Red), r)
+ | GT => Node (l, ((a, b), Red), upd (A1_, A2_) x y r));
+
+fun listMem A_ xa (x :: xs) = eq A_ xa x orelse listMem A_ xa xs
+ | listMem A_ x [] = false;
+
+fun list_ex p [] = false
+ | list_ex p (x :: xs) = p x orelse list_ex p xs;
+
+fun map f [] = []
+ | map f (x21 :: x22) = f x21 :: map f x22;
+
+fun product [] uu = []
+ | product (x :: xs) ys = map (fn a => (x, a)) ys @ product xs ys;
+
+fun remdups A_ [] = []
+ | remdups A_ (x :: xs) =
+ (if member A_ xs x then remdups A_ xs else x :: remdups A_ xs);
+
+fun distinct A_ [] = true
+ | distinct A_ (x :: xs) = not (member A_ xs x) andalso distinct A_ xs;
+
+val empty : ('a * color) tree = Leaf;
+
+fun inorder Leaf = []
+ | inorder (Node (l, (a, uu), r)) = inorder l @ a :: inorder r;
+
+fun bigOr [] = Bot
+ | bigOr (f :: fs) = Or (f, bigOr fs);
+
+fun is_none (SOME x) = false
+ | is_none NONE = true;
+
+fun update (A1_, A2_) x y t = paint Black (upd (A1_, A2_) x y t);
+
+fun integer_of_char (Chara (b0, b1, b2, b3, b4, b5, b6, b7)) =
+ IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (IntInf.+ (IntInf.* (of_bool
+ zero_neq_one_integer
+ b7, (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b6), (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b5), (2 : IntInf.int)), of_bool
+ zero_neq_one_integer
+ b4), (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b3), (2 : IntInf.int)), of_bool zero_neq_one_integer
+ b2), (2 : IntInf.int)), of_bool
+ zero_neq_one_integer
+ b1), (2 : IntInf.int)), of_bool zero_neq_one_integer b0);
+
+fun implode cs =
+ (String.implode
+ o List.map (fn k => if 0 <= k andalso k < 128 then (Char.chr o IntInf.toInt) k else raise Fail "Non-ASCII character in literal"))
+ (map integer_of_char cs);
+
+fun bigAnd [] = Not Bot
+ | bigAnd (f :: fs) = And (f, bigAnd fs);
+
+fun gen_length n (x :: xs) = gen_length (suc n) xs
+ | gen_length n [] = n;
+
+fun map_filter f [] = []
+ | map_filter f (x :: xs) =
+ (case f x of NONE => map_filter f xs | SOME y => y :: map_filter f xs);
+
+fun bheight Leaf = zero_nat
+ | bheight (Node (l, (x, c), r)) =
+ (if equal_colora c Black then plus_nat (bheight l) one_nat else bheight l);
+
+fun find_index uu [] = zero_nat
+ | find_index p (x :: xs) =
+ (if p x then zero_nat else plus_nat (find_index p xs) one_nat);
+
+fun index A_ xs = (fn a => find_index (fn x => eq A_ x a) xs);
+
+fun the (SOME x2) = x2;
+
+fun is_standard_effect x = (fn (pre, (_, (_, _))) => null pre) x;
+
+fun list_all p [] = true
+ | list_all p (x :: xs) = p x andalso list_all p xs;
+
+fun is_standard_operator x =
+ (fn (_, (_, (effects, _))) => list_all is_standard_effect effects) x;
+
+fun consistent_map_lists A_ xs1 xs2 =
+ list_all
+ (fn (x1, _) =>
+ list_all (fn (y1, y2) => (if eq A_ x1 y1 then eq A_ x1 y2 else true)) xs2)
+ xs1;
+
+fun implicit_pres effs =
+ map_filter
+ (fn x =>
+ (if let
+ val (_, (_, (vpre, _))) = x;
+ in
+ not (is_none vpre)
+ end
+ then SOME let
+ val (_, (v, (vpre, _))) = x;
+ in
+ (v, the vpre)
+ end
+ else NONE))
+ effs;
+
+fun consistent_pres_op opa =
+ let
+ val (_, (pres, (effs, _))) = opa;
+ in
+ distinct equal_nat (map fst (pres @ implicit_pres effs)) andalso
+ consistent_map_lists equal_nat pres (implicit_pres effs)
+ end;
+
+fun astDom problem = let
+ val (d, (_, (_, _))) = problem;
+ in
+ d
+ end;
+
+fun size_list x = gen_length zero_nat x;
+
+fun numVars problem = size_list (astDom problem);
+
+fun numVals problem x = size_list (snd (snd (nth (astDom problem) x)));
+
+fun wf_partial_state problem ps =
+ distinct equal_nat (map fst ps) andalso
+ list_all
+ (fn (x, v) =>
+ less_nat x (numVars problem) andalso less_nat v (numVals problem x))
+ ps;
+
+fun wf_operator problem =
+ (fn (_, (pres, (effs, _))) =>
+ wf_partial_state problem pres andalso
+ (distinct equal_nat (map (fn (_, (v, (_, _))) => v) effs) andalso
+ list_all
+ (fn (epres, (x, (vp, v))) =>
+ wf_partial_state problem epres andalso
+ (less_nat x (numVars problem) andalso
+ (less_nat v (numVals problem x) andalso
+ (case vp of NONE => true
+ | SOME va => less_nat va (numVals problem x)))))
+ effs));
+
+fun ast_delta problem = let
+ val (_, (_, (_, delta))) = problem;
+ in
+ delta
+ end;
+
+fun astI problem = let
+ val (_, (i, (_, _))) = problem;
+ in
+ i
+ end;
+
+fun astG problem = let
+ val (_, (_, (g, _))) = problem;
+ in
+ g
+ end;
+
+fun all_interval_nat p i j =
+ less_eq_nat j i orelse p i andalso all_interval_nat p (suc i) j;
+
+fun well_formed problem =
+ equal_nata (size_list (astI problem)) (numVars problem) andalso
+ (all_interval_nat
+ (fn x => less_nat (nth (astI problem) x) (numVals problem x)) zero_nat
+ (numVars problem) andalso
+ (wf_partial_state problem (astG problem) andalso
+ (distinct (equal_list equal_char) (map fst (ast_delta problem)) andalso
+ list_all (wf_operator problem) (ast_delta problem))));
+
+fun rem_effect_implicit_pres (preconds, (v, (implicit_pre, eff))) =
+ (preconds, (v, (NONE, eff)));
+
+fun rem_implicit_pres (name, (preconds, (effects, cost))) =
+ (name,
+ (implicit_pres effects @ preconds,
+ (map rem_effect_implicit_pres effects, cost)));
+
+fun rem_implicit_pres_ops (vars, (init, (goal, ops))) =
+ (vars, (init, (goal, map rem_implicit_pres ops)));
+
+fun precondition_ofa (Sas_plus_operator_ext (precondition_of, effect_of, more))
+ = precondition_of;
+
+fun effect_of (Sas_plus_operator_ext (precondition_of, effect_of, more)) =
+ effect_of;
+
+fun lookup_action problem opa =
+ find (fn (_, (pres, (effs, _))) =>
+ equal_lista (equal_prod equal_nat equal_nat) (precondition_ofa opa)
+ pres andalso
+ equal_lista
+ (equal_prod (equal_list (equal_prod equal_nat equal_nat))
+ (equal_prod equal_nat
+ (equal_prod (equal_option equal_nat) equal_nat)))
+ (map (fn (v, a) => ([], (v, (NONE, a)))) (effect_of opa)) effs)
+ (ast_delta problem);
+
+fun tree_map_of updatea t [] = t
+ | tree_map_of updatea t ((v, a) :: m) = updatea v a (tree_map_of updatea t m);
+
+fun match_pre B_ = (fn (x, v) => fn s => equal_optiona B_ (s x) (SOME v));
+
+fun match_pres B_ pres s = list_all (fn pre => match_pre B_ pre s) pres;
+
+fun is_operator_applicable_in (A1_, A2_) B_ s opa =
+ match_pres B_
+ (inorder (tree_map_of (update (A1_, A2_)) empty (precondition_ofa opa))) s;
+
+fun execute_operator_sas_plus A_ s opa = map_add s (map_of A_ (effect_of opa));
+
+fun rem_condless_ops (A1_, A2_) B_ s [] = []
+ | rem_condless_ops (A1_, A2_) B_ s (opa :: ops) =
+ (if is_operator_applicable_in (A1_, A2_) B_ s opa
+ then opa ::
+ rem_condless_ops (A1_, A2_) B_
+ (execute_operator_sas_plus A1_ s opa) ops
+ else []);
+
+fun i problem v =
+ (if less_nat v (size_list (astI problem)) then SOME (nth (astI problem) v)
+ else NONE);
+
+fun decode_abs_plan problem =
+ map (fst o the o lookup_action problem) o
+ rem_condless_ops (equal_nat, linorder_nat) equal_nat (i problem);
+
+fun variables_ofa
+ (Sas_plus_problem_ext
+ (variables_of, operators_of, initial_of, goal_of, range_of, more))
+ = variables_of;
+
+fun operators_ofa
+ (Sas_plus_problem_ext
+ (variables_of, operators_of, initial_of, goal_of, range_of, more))
+ = operators_of;
+
+fun initial_ofa
+ (Sas_plus_problem_ext
+ (variables_of, operators_of, initial_of, goal_of, range_of, more))
+ = initial_of;
+
+fun goal_ofa
+ (Sas_plus_problem_ext
+ (variables_of, operators_of, initial_of, goal_of, range_of, more))
+ = goal_of;
+
+fun range_of
+ (Sas_plus_problem_ext
+ (variables_of, operators_of, initial_of, goal_of, range_of, more))
+ = range_of;
+
+fun possible_assignments_for psi v =
+ map (fn a => (v, a)) (the (range_of psi v));
+
+fun state_to_strips_state A_ B_ psi s =
+ let
+ val defined = filter (fn v => not (is_none (s v))) (variables_ofa psi);
+ in
+ map_of (equal_prod A_ B_)
+ (map (fn (v, a) => ((v, a), eq B_ (the (s v)) a))
+ (maps (possible_assignments_for psi) defined))
+ end;
+
+fun sasp_op_to_strips B_ psi opa =
+ let
+ val pre = precondition_ofa opa;
+ val add = effect_of opa;
+ val delete =
+ maps (fn (v, a) =>
+ map_filter
+ (fn x => (if not (eq B_ a x) then SOME (v, x) else NONE))
+ (the (range_of psi v)))
+ (effect_of opa);
+ in
+ Strips_operator_ext (pre, add, delete, ())
+ end;
+
+fun sas_plus_problem_to_strips_problem A_ B_ psi =
+ let
+ val vs =
+ maps (fn v => map (fn asa => asa) (possible_assignments_for psi v))
+ (variables_ofa psi);
+ val ops = map (sasp_op_to_strips B_ psi) (operators_ofa psi);
+ val i = state_to_strips_state A_ B_ psi (initial_ofa psi);
+ val g = state_to_strips_state A_ B_ psi (goal_ofa psi);
+ in
+ Strips_problem_ext (vs, ops, i, g, ())
+ end;
+
+fun abs_ast_variable_section problem =
+ upt zero_nat (size_list (astDom problem));
+
+fun abs_ast_operator x =
+ (fn (_, (preconditions, (effects, _))) =>
+ Sas_plus_operator_ext
+ (preconditions, map (fn (_, a) => let
+ val (v, aa) = a;
+ val (_, ab) = aa;
+in
+ (v, ab)
+end)
+ effects,
+ ()))
+ x;
+
+fun abs_ast_operator_section problem = map abs_ast_operator (ast_delta problem);
+
+fun abs_ast_initial_state problem =
+ map_of equal_nat
+ (zip (upt zero_nat (size_list (astI problem))) (astI problem));
+
+fun abs_range_map problem =
+ map_of equal_nat
+ (zip (abs_ast_variable_section problem)
+ (map ((fn vals => upt zero_nat (size_list vals)) o snd o snd)
+ (astDom problem)));
+
+fun abs_ast_goal problem = map_of equal_nat (astG problem);
+
+fun abs_prob problem =
+ Sas_plus_problem_ext
+ (abs_ast_variable_section problem, abs_ast_operator_section problem,
+ abs_ast_initial_state problem, abs_ast_goal problem,
+ abs_range_map problem, ());
+
+fun times_nat m n = Nat (IntInf.* (integer_of_nat m, integer_of_nat n));
+
+fun var_to_dimacs h n_ops (State (t, k)) =
+ plus_nat (plus_nat (plus_nat one_nat (times_nat n_ops h)) t) (times_nat k h)
+ | var_to_dimacs h n_ops (Operator (t, k)) =
+ plus_nat (plus_nat one_nat t) (times_nat k h);
+
+val empty_sasp_action : ('a, 'b, unit) sas_plus_operator_ext =
+ Sas_plus_operator_ext ([], [], ());
+
+fun prob_with_noop pi =
+ Sas_plus_problem_ext
+ (variables_ofa pi, empty_sasp_action :: operators_ofa pi, initial_ofa pi,
+ goal_ofa pi, range_of pi, ());
+
+fun precondition_of
+ (Strips_operator_ext
+ (precondition_of, add_effects_of, delete_effects_of, more))
+ = precondition_of;
+
+fun add_effects_of
+ (Strips_operator_ext
+ (precondition_of, add_effects_of, delete_effects_of, more))
+ = add_effects_of;
+
+fun strips_op_to_sasp psi opa =
+ let
+ val precondition = precondition_of opa;
+ val effect = add_effects_of opa;
+ in
+ Sas_plus_operator_ext (precondition, effect, ())
+ end;
+
+fun abs_int i = (if less_int i Zero_int then uminus_int i else i);
+
+fun dimacs_model_to_abs dimacs_M m =
+ fold (fn l => fn ma =>
+ (if less_int Zero_int l
+ then fun_upd equal_nat ma (nat (abs_int l)) true
+ else fun_upd equal_nat ma (nat (abs_int l)) false))
+ dimacs_M m;
+
+fun equal_sas_plus_operator_ext A_ B_ C_
+ (Sas_plus_operator_ext (precondition_ofa, effect_ofa, morea))
+ (Sas_plus_operator_ext (precondition_of, effect_of, more)) =
+ equal_lista (equal_prod A_ B_) precondition_ofa precondition_of andalso
+ (equal_lista (equal_prod A_ B_) effect_ofa effect_of andalso
+ eq C_ morea more);
+
+fun rem_noops A_ B_ =
+ filter
+ (fn opa =>
+ not (equal_sas_plus_operator_ext A_ B_ equal_unit opa empty_sasp_action));
+
+fun operators_of
+ (Strips_problem_ext (variables_of, operators_of, initial_of, goal_of, more)) =
+ operators_of;
+
+fun decode_plana A_ pi a i =
+ let
+ val ops = operators_of pi;
+ val b =
+ map (fn opa =>
+ Operator
+ (i, index (equal_strips_operator_ext A_ equal_unit) ops opa))
+ (remdups (equal_strips_operator_ext A_ equal_unit) ops);
+ in
+ map_filter
+ (fn x => (if a x then SOME let
+ val Operator (_, aa) = x;
+ in
+ nth ops aa
+ end
+ else NONE))
+ b
+ end;
+
+fun decode_plan A_ pi a t = map (decode_plana A_ pi a) (upt zero_nat t);
+
+fun decode_DIMACS_model dimacs_M h prob =
+ decode_abs_plan prob
+ (rem_noops equal_nat equal_nat
+ (map (strips_op_to_sasp (prob_with_noop (abs_prob prob)))
+ (concat
+ (decode_plan (equal_prod equal_nat equal_nat)
+ (sas_plus_problem_to_strips_problem equal_nat equal_nat
+ (prob_with_noop (abs_prob prob)))
+ (dimacs_model_to_abs dimacs_M (fn _ => false) o
+ var_to_dimacs (suc h) (suc (size_list (ast_delta prob))))
+ h))));
+
+fun decode_DIMACS_modela dimacs_M h prob =
+ decode_DIMACS_model dimacs_M h (rem_implicit_pres_ops prob);
+
+fun encode_interfering_operator_pair_exclusion A_ pi k op_1 op_2 =
+ let
+ val ops = operators_of pi;
+ in
+ Or (Not (Atom (Operator
+ (k, index (equal_strips_operator_ext A_ equal_unit) ops
+ op_1))),
+ Not (Atom (Operator
+ (k, index (equal_strips_operator_ext A_ equal_unit) ops
+ op_2))))
+ end;
+
+fun delete_effects_of
+ (Strips_operator_ext
+ (precondition_of, add_effects_of, delete_effects_of, more))
+ = delete_effects_of;
+
+fun are_operators_interfering A_ op_1 op_2 =
+ list_ex (fn v => list_ex (eq A_ v) (delete_effects_of op_1))
+ (precondition_of op_2) orelse
+ list_ex (fn v => list_ex (eq A_ v) (precondition_of op_1))
+ (delete_effects_of op_2);
+
+fun encode_interfering_operator_exclusion A_ pi t =
+ let
+ val ops = operators_of pi;
+ val interfering =
+ filter
+ (fn (op_1, op_2) =>
+ not (equal_nata
+ (index (equal_strips_operator_ext A_ equal_unit) ops op_1)
+ (index (equal_strips_operator_ext A_ equal_unit) ops
+ op_2)) andalso
+ are_operators_interfering A_ op_1 op_2)
+ (product ops ops);
+ in
+ foldr (fn a => fn b => And (a, b))
+ (maps (fn (op_1, op_2) =>
+ map (fn k =>
+ encode_interfering_operator_pair_exclusion A_ pi k op_1
+ op_2)
+ (upt zero_nat t))
+ interfering)
+ (Not Bot)
+ end;
+
+fun variables_of
+ (Strips_problem_ext (variables_of, operators_of, initial_of, goal_of, more)) =
+ variables_of;
+
+fun encode_positive_transition_frame_axiom A_ pi t v =
+ let
+ val vs = variables_of pi;
+ val ops = operators_of pi;
+ val adding_operators =
+ filter (fn opa => listMem A_ v (add_effects_of opa)) ops;
+ in
+ Or (Atom (State (t, index A_ vs v)),
+ Or (Not (Atom (State (suc t, index A_ vs v))),
+ bigOr (map (fn opa =>
+ Atom (Operator
+ (t, index
+(equal_strips_operator_ext A_ equal_unit) ops opa)))
+ adding_operators)))
+ end;
+
+fun encode_negative_transition_frame_axiom A_ pi t v =
+ let
+ val vs = variables_of pi;
+ val ops = operators_of pi;
+ val deleting_operators =
+ filter (fn opa => listMem A_ v (delete_effects_of opa)) ops;
+ in
+ Or (Not (Atom (State (t, index A_ vs v))),
+ Or (Atom (State (suc t, index A_ vs v)),
+ bigOr (map (fn opa =>
+ Atom (Operator
+ (t, index
+(equal_strips_operator_ext A_ equal_unit) ops opa)))
+ deleting_operators)))
+ end;
+
+fun encode_all_frame_axioms A_ pi t =
+ let
+ val l = product (upt zero_nat t) (variables_of pi);
+ in
+ bigAnd
+ (map (fn (a, b) => encode_negative_transition_frame_axiom A_ pi a b) l @
+ map (fn (a, b) => encode_positive_transition_frame_axiom A_ pi a b) l)
+ end;
+
+fun initial_of
+ (Strips_problem_ext (variables_of, operators_of, initial_of, goal_of, more)) =
+ initial_of;
+
+fun encode_state_variable t k v =
+ (case v of SOME true => Atom (State (t, k))
+ | SOME false => Not (Atom (State (t, k))));
+
+fun encode_initial_state A_ pi =
+ let
+ val i = initial_of pi;
+ val vs = variables_of pi;
+ in
+ bigAnd
+ (map_filter
+ (fn x =>
+ (if not (is_none (i x))
+ then SOME (Or (encode_state_variable zero_nat (index A_ vs x) (i x),
+ Bot))
+ else NONE))
+ vs)
+ end;
+
+fun goal_of
+ (Strips_problem_ext (variables_of, operators_of, initial_of, goal_of, more)) =
+ goal_of;
+
+fun encode_goal_state A_ pi t =
+ let
+ val vs = variables_of pi;
+ val g = goal_of pi;
+ in
+ bigAnd
+ (map_filter
+ (fn x =>
+ (if not (is_none (g x))
+ then SOME (Or (encode_state_variable t (index A_ vs x) (g x), Bot))
+ else NONE))
+ vs)
+ end;
+
+fun encode_operator_precondition A_ pi t opa =
+ let
+ val vs = variables_of pi;
+ val ops = operators_of pi;
+ in
+ bigAnd
+ (map (fn v =>
+ Or (Not (Atom (Operator
+ (t, index (equal_strips_operator_ext A_ equal_unit)
+ ops opa))),
+ Atom (State (t, index A_ vs v))))
+ (precondition_of opa))
+ end;
+
+fun encode_all_operator_preconditions A_ pi ops t =
+ let
+ val l = product (upt zero_nat t) ops;
+ in
+ foldr ((fn a => fn b => And (a, b)) o
+ (fn (a, b) => encode_operator_precondition A_ pi a b))
+ l (Not Bot)
+ end;
+
+fun encode_operator_effect A_ pi t opa =
+ let
+ val vs = variables_of pi;
+ val ops = operators_of pi;
+ in
+ bigAnd
+ (map (fn v =>
+ Or (Not (Atom (Operator
+ (t, index (equal_strips_operator_ext A_ equal_unit)
+ ops opa))),
+ Atom (State (suc t, index A_ vs v))))
+ (add_effects_of opa) @
+ map (fn v =>
+ Or (Not (Atom (Operator
+ (t, index (equal_strips_operator_ext A_
+ equal_unit)
+ ops opa))),
+ Not (Atom (State (suc t, index A_ vs v)))))
+ (delete_effects_of opa))
+ end;
+
+fun encode_all_operator_effects A_ pi ops t =
+ let
+ val l = product (upt zero_nat t) ops;
+ in
+ foldr ((fn a => fn b => And (a, b)) o
+ (fn (a, b) => encode_operator_effect A_ pi a b))
+ l (Not Bot)
+ end;
+
+fun encode_operators A_ pi t =
+ let
+ val ops = operators_of pi;
+ in
+ And (encode_all_operator_preconditions A_ pi ops t,
+ encode_all_operator_effects A_ pi ops t)
+ end;
+
+fun encode_problem_with_operator_interference_exclusion A_ pi t =
+ And (encode_initial_state A_ pi,
+ And (encode_operators A_ pi t,
+ And (encode_all_frame_axioms A_ pi t,
+ And (encode_interfering_operator_exclusion A_ pi t,
+ encode_goal_state A_ pi t))));
+
+fun map_formula f (Atom x1) = Atom (f x1)
+ | map_formula f Bot = Bot
+ | map_formula f (Not x3) = Not (map_formula f x3)
+ | map_formula f (And (x41, x42)) = And (map_formula f x41, map_formula f x42)
+ | map_formula f (Or (x51, x52)) = Or (map_formula f x51, map_formula f x52)
+ | map_formula f (Imp (x61, x62)) = Imp (map_formula f x61, map_formula f x62);
+
+fun apsnd f (x, y) = (x, f y);
+
+fun divmod_integer k l =
+ (if ((k : IntInf.int) = (0 : IntInf.int))
+ then ((0 : IntInf.int), (0 : IntInf.int))
+ else (if IntInf.< ((0 : IntInf.int), l)
+ then (if IntInf.< ((0 : IntInf.int), k)
+ then IntInf.divMod (IntInf.abs k, IntInf.abs l)
+ else let
+ val (r, s) =
+ IntInf.divMod (IntInf.abs k, IntInf.abs l);
+ in
+ (if ((s : IntInf.int) = (0 : IntInf.int))
+ then (IntInf.~ r, (0 : IntInf.int))
+ else (IntInf.- (IntInf.~ r, (1 : IntInf.int)),
+ IntInf.- (l, s)))
+ end)
+ else (if ((l : IntInf.int) = (0 : IntInf.int))
+ then ((0 : IntInf.int), k)
+ else apsnd IntInf.~
+ (if IntInf.< (k, (0 : IntInf.int))
+ then IntInf.divMod (IntInf.abs k, IntInf.abs l)
+ else let
+ val (r, s) =
+ IntInf.divMod (IntInf.abs k, IntInf.abs l);
+ in
+ (if ((s : IntInf.int) = (0 : IntInf.int))
+ then (IntInf.~ r, (0 : IntInf.int))
+ else (IntInf.- (IntInf.~
+ r, (1 : IntInf.int)),
+ IntInf.- (IntInf.~ l, s)))
+ end))));
+
+fun int_of_integer k =
+ (if IntInf.< (k, (0 : IntInf.int))
+ then uminus_int (int_of_integer (IntInf.~ k))
+ else (if ((k : IntInf.int) = (0 : IntInf.int)) then Zero_int
+ else let
+ val (l, j) = divmod_integer k (2 : IntInf.int);
+ val la = times_int (Pos (Bit0 One)) (int_of_integer l);
+ in
+ (if ((j : IntInf.int) = (0 : IntInf.int)) then la
+ else plus_int la one_inta)
+ end));
+
+fun int_of_nat n = int_of_integer (integer_of_nat n);
+
+fun disj_to_dimacs (Or (phi_1, phi_2)) =
+ disj_to_dimacs phi_1 @ disj_to_dimacs phi_2
+ | disj_to_dimacs Bot = []
+ | disj_to_dimacs (Not Bot) = [uminus_int one_inta, one_inta]
+ | disj_to_dimacs (Atom v) = [int_of_nat v]
+ | disj_to_dimacs (Not (Atom v)) = [uminus_int (int_of_nat v)];
+
+fun cnf_to_dimacs (And (phi_1, phi_2)) =
+ cnf_to_dimacs phi_1 @ cnf_to_dimacs phi_2
+ | cnf_to_dimacs (Atom v) = [disj_to_dimacs (Atom v)]
+ | cnf_to_dimacs Bot = [disj_to_dimacs Bot]
+ | cnf_to_dimacs (Not v) = [disj_to_dimacs (Not v)]
+ | cnf_to_dimacs (Or (v, va)) = [disj_to_dimacs (Or (v, va))]
+ | cnf_to_dimacs (Imp (v, va)) = [disj_to_dimacs (Imp (v, va))];
+
+fun sASP_to_DIMACS h prob =
+ cnf_to_dimacs
+ (map_formula (var_to_dimacs (suc h) (suc (size_list (ast_delta prob))))
+ (encode_problem_with_operator_interference_exclusion
+ (equal_prod equal_nat equal_nat)
+ (sas_plus_problem_to_strips_problem equal_nat equal_nat
+ (prob_with_noop (abs_prob prob)))
+ h));
+
+fun sASP_to_DIMACSa h prob = sASP_to_DIMACS h (rem_implicit_pres_ops prob);
+
+fun size_tree Leaf = zero_nat
+ | size_tree (Node (x21, x22, x23)) =
+ plus_nat (plus_nat (size_tree x21) (size_tree x23)) (suc zero_nat);
+
+fun dimacs_lit_to_var l = nat (abs_int l);
+
+fun equal_tree A_ Leaf (Node (x21, x22, x23)) = false
+ | equal_tree A_ (Node (x21, x22, x23)) Leaf = false
+ | equal_tree A_ (Node (x21, x22, x23)) (Node (y21, y22, y23)) =
+ equal_tree A_ x21 y21 andalso (eq A_ x22 y22 andalso equal_tree A_ x23 y23)
+ | equal_tree A_ Leaf Leaf = true;
+
+fun joinR l x r =
+ (if less_eq_nat (bheight l) (bheight r) then Node (l, (x, Red), r)
+ else (case l
+ of Node (la, (xa, Red), ra) => Node (la, (xa, Red), joinR ra x r)
+ | Node (la, (xa, Black), ra) => baliR la xa (joinR ra x r)));
+
+fun joinL l x r =
+ (if less_eq_nat (bheight r) (bheight l) then Node (l, (x, Red), r)
+ else (case r
+ of Node (la, (xa, Red), ra) => Node (joinL l x la, (xa, Red), ra)
+ | Node (la, (xa, Black), ra) => baliL (joinL l x la) xa ra));
+
+fun join l x r =
+ (if less_nat (bheight r) (bheight l) then paint Black (joinR l x r)
+ else (if less_nat (bheight l) (bheight r) then paint Black (joinL l x r)
+ else Node (l, (x, Black), r)));
+
+fun split_rbt (A1_, A2_) Leaf k = (Leaf, (false, Leaf))
+ | split_rbt (A1_, A2_) (Node (l, (a, uu), r)) x =
+ (case cmp (A1_, A2_) x a of LT => let
+val b = split_rbt (A1_, A2_) l x;
+val (l1, ba) = b;
+val (bb, l2) = ba;
+ in
+(l1, (bb, join l2 a r))
+ end
+ | EQ => (l, (true, r)) | GT => let
+ val b = split_rbt (A1_, A2_) r x;
+ val (r1, ba) = b;
+ val (bb, r2) = ba;
+ in
+ (join l a r1, (bb, r2))
+ end);
+
+fun split_min_rbt (A1_, A2_) (Node (l, (a, uu), r)) =
+ (if equal_tree (equal_prod A1_ equal_color) l Leaf then (a, r)
+ else let
+ val (m, la) = split_min_rbt (A1_, A2_) l;
+ in
+ (m, join la a r)
+ end);
+
+fun join2_rbt (A1_, A2_) l r =
+ (if equal_tree (equal_prod A1_ equal_color) r Leaf then l
+ else let
+ val a = split_min_rbt (A1_, A2_) r;
+ val (aa, b) = a;
+ in
+ join l aa b
+ end);
+
+fun inter_rbt (A1_, A2_) t1 t2 =
+ (if equal_tree (equal_prod A1_ equal_color) t1 Leaf then Leaf
+ else (if equal_tree (equal_prod A1_ equal_color) t2 Leaf then Leaf
+ else let
+ val Node (l1, (a, _), r1) = t1;
+ val (l2, (ain, r2)) = split_rbt (A1_, A2_) t2 a;
+ val l = inter_rbt (A1_, A2_) l1 l2;
+ val r = inter_rbt (A1_, A2_) r1 r2;
+ in
+ (if ain then join l a r else join2_rbt (A1_, A2_) l r)
+ end));
+
+fun insert_rbt (A1_, A2_) x t = let
+ val a = split_rbt (A1_, A2_) t x;
+ val (l, aa) = a;
+ val (_, ab) = aa;
+ in
+ join l x ab
+ end;
+
+fun list_to_rbt [] = Leaf
+ | list_to_rbt (x :: xs) =
+ insert_rbt (equal_int, linorder_int) x (list_to_rbt xs);
+
+fun dimacs_model ls cs =
+ let
+ val tls = list_to_rbt ls;
+ in
+ list_all
+ (fn c =>
+ not (equal_nata
+ (size_tree
+ (inter_rbt (equal_int, linorder_int) tls (list_to_rbt c)))
+ zero_nat))
+ cs andalso
+ distinct equal_nat (map dimacs_lit_to_var ls)
+ end;
+
+fun decode m h prob =
+ (if well_formed prob
+ then (if list_all consistent_pres_op (ast_delta prob)
+ then (if list_all is_standard_operator (ast_delta prob)
+ then (if dimacs_model m (sASP_to_DIMACSa h prob)
+ then Inl (decode_DIMACS_modela m h prob)
+ else Inr "Error: Model does not solve the problem!")
+ else Inr "Error: Conditional effects!")
+ else Inr "Error: Preconditions inconsistent")
+ else Inr "Error: Problem malformed!");
+
+fun max_var xs =
+ fold (fn x => fn y =>
+ (if less_eq_int (abs_int y) (abs_int x) then abs_int x else y))
+ xs Zero_int;
+
+fun bit_cut_integer k =
+ (if ((k : IntInf.int) = (0 : IntInf.int)) then ((0 : IntInf.int), false)
+ else let
+ val (r, s) =
+ IntInf.divMod (IntInf.abs k, IntInf.abs (2 : IntInf.int));
+ in
+ ((if IntInf.< ((0 : IntInf.int), k) then r
+ else IntInf.- (IntInf.~ r, s)),
+ ((s : IntInf.int) = (1 : IntInf.int)))
+ end);
+
+fun char_of_integer k = let
+ val (q0, b0) = bit_cut_integer k;
+ val (q1, b1) = bit_cut_integer q0;
+ val (q2, b2) = bit_cut_integer q1;
+ val (q3, b3) = bit_cut_integer q2;
+ val (q4, b4) = bit_cut_integer q3;
+ val (q5, b5) = bit_cut_integer q4;
+ val (q6, b6) = bit_cut_integer q5;
+ val a = bit_cut_integer q6;
+ val (_, aa) = a;
+ in
+ Chara (b0, b1, b2, b3, b4, b5, b6, aa)
+ end;
+
+fun explode s =
+ map char_of_integer
+ ((List.map (fn c => let val k = Char.ord c in if k < 128 then IntInf.fromInt k else raise Fail "Non-ASCII character in literal" end)
+ o String.explode)
+ s);
+
+fun nat_of_integer k = Nat (max ord_integer (0 : IntInf.int) k);
+
+fun char_of_nat x = (char_of_integer o integer_of_nat) x;
+
+fun nat_opt_of_integer i =
+ (if IntInf.<= ((0 : IntInf.int), i) then SOME (nat_of_integer i) else NONE);
+
+end; (*struct exported*)
diff --git a/thys/Verified_SAT_Based_AI_Planning/code/sas_plus.sml b/thys/Verified_SAT_Based_AI_Planning/code/sas_plus.sml
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/code/sas_plus.sml
@@ -0,0 +1,293 @@
+(*
+ This is a file that containts a grammar and a parser for
+ Fast-Downward's Multi-valued problem representation.
+*)
+
+structure LexSASProb =
+(* An implementation that uses token parser. *)
+struct
+
+ open ParserCombinators
+ open CharParser
+
+ infixr 4 << >>
+ infixr 3 &&
+ infix 2 -- ##
+ infix 2 wth suchthat return guard when
+ infixr 1 || <|> ??
+
+ structure SASProbDef :> LANGUAGE_DEF =
+ struct
+
+ type scanner = SubstringMonoStreamable.elem CharParser.charParser
+
+ val commentStart = NONE
+ val commentEnd = NONE
+ val commentLine = NONE
+ val nestedComments = false
+
+ val alphaNumUnderDashSpace = try (satisfy (fn c =>
+ (if (Char.isAlphaNum c)
+ then true
+ else if (c = #"_")
+ then true
+ else if (c = #"-")
+ then true
+ else if (c = #" ")
+ then true
+ else if (c = #"(")
+ then true
+ else if (c = #")")
+ then true
+ else if (c = #",")
+ then true
+ else if (c = #"<")
+ then true
+ else if (c = #">")
+ then true
+ else false)) ) ?? "alphanumeric character"
+
+ val identLetter = alphaNumUnderDashSpace (*Idents can only be separated with \n and can contain [Aa-Zz], [0-9], " ", "-", "_"*)
+ val identStart = identLetter
+ val opStart = fail "Operators not supported" : scanner
+ val opLetter = opStart
+ val reservedNames = ["begin_version", "end_version",
+ "begin_metric", "end_metric",
+ "begin_variable", "end_variable",
+ "begin_mutex_group", "end_mutex_group",
+ "begin_state", "end_state",
+ "begin_goal", "end_goal",
+ "begin_operator", "end_operator"]
+ val reservedOpNames= []
+ val caseSensitive = true
+
+ end
+
+ structure RTP = TokenParser (SASProbDef)
+ open RTP
+
+ val SMLCharImplode = String.implode;
+ val SMLCharExplode = String.explode;
+
+
+ val num = (lexeme ((char #"-" || digit) && (repeat digit)) when
+ (fn (x,xs) => Int.fromString (SMLCharImplode (x::xs)))) ?? "num expression"
+
+ val sas_ident = identifier
+
+ fun sas_reserved wrd = (reserved wrd)
+
+ val version = (sas_reserved "begin_version" ?? "begin_version")>>
+ (num ?? "version number") <<
+ (sas_reserved "end_version" ?? "begversion")
+
+ val metric = (sas_reserved "begin_metric" ?? "begin_metric")>>
+ (num ?? "Metric number") <<
+ (sas_reserved "end_metric" ?? "end_metric")
+
+ val variable = (sas_reserved "begin_variable" ?? "begin_variable")>>
+ (sas_ident ?? "Variable name") &&
+ (num ?? "Axiom layer") &&
+ ((num ?? "Number of asses") --
+ (fn n_asses => (repeatn n_asses sas_ident) ?? "Atom names")) <<
+ (sas_reserved "end_variable" ?? "end_variable")
+ ?? "SAS+ Variable"
+
+ val sas_ass = (num ?? "SAS+ Variable ID") &&
+ (num ?? "SAS+ ass")
+ ?? "sas+ ass"
+
+ val mutex_group = (sas_reserved "begin_mutex_group" ?? "begin_mutex_group")>>
+ ((num ?? "number of mutexes") --
+ (fn n_mutexes => (repeatn n_mutexes sas_ass) ?? "SAS+ asses")) <<
+ (sas_reserved "end_mutex_group" ?? "end_mutex_group")
+ ?? "mutex"
+
+ val init_state = (sas_reserved "begin_state" ?? "begin_state")>>
+ (repeat1 num ?? "Initial state assignments") <<
+ (sas_reserved "end_state" ?? "end_state")
+ ?? "Initial state"
+
+ val goal = (sas_reserved "begin_goal" ?? "begin_goal")>>
+ ((num ?? "Number of goal asses") --
+ (fn n_goals => (repeatn n_goals sas_ass) ?? "Goal asses")) <<
+ (sas_reserved "end_goal" ?? "end_goal")
+ ?? "Initial state"
+
+ val numPreconds = 0
+
+ val effect = ((num ?? "Number of effect preconds") --
+ (fn n_eff_pres => ((repeatn n_eff_pres sas_ass ) ?? "Effect preconds"))) &&
+ (num ?? "Variable ID") &&
+ (num ?? "Old ass") &&
+ (num ?? "New ass") ?? "Effect"
+
+ val operator = (sas_reserved "begin_operator" ?? "begin_operator")>>
+ (sas_ident ?? "Operator name") &&
+ ((num ?? "Number of preconds") --
+ (fn n_preconds => (repeatn n_preconds sas_ass) ?? "Prevail preconditions")) &&
+ ((num ?? "Number of effects") --
+ (fn n_eff => (repeatn n_eff effect) ?? "Action effects")) &&
+ (num ?? "Cost") <<
+ (sas_reserved "end_operator" ?? "end_operator")
+ ?? "Operator"
+
+ val problem = version && metric &&
+ ((num ?? "Number of SAS+ variables") --
+ (fn n_sas_vars => (repeatn n_sas_vars variable) ?? "SAS+ variables section")) &&
+ ((num ?? "Number of mutex groups") --
+ (fn n_mutx => repeatn n_mutx mutex_group ?? "Mutex groups section")) &&
+ (init_state) &&
+ (goal) &&
+ ((num ?? "Number of operators") --
+ (fn n_opr => (repeatn n_opr operator)?? "Operators")) &&
+ (num ?? "Number of axioms") <<
+ (eos ?? "end of stream") ?? "problem"
+
+ val plan = (repeat sas_ident) ?? "Plan"
+
+ val model_line = (sas_reserved "v" ?? "v, parsing model_line")>>
+ (repeat num ?? "literal, parsing model_line")
+
+ val model = (repeat model_line ?? "model_line, parsing model")
+
+end
+
+fun readFile file =
+let
+ fun next_String input = (TextIO.inputAll input)
+ val stream = TextIO.openIn file
+in
+ next_String stream
+end
+
+fun parse_plan plan_file =
+ (CharParser.parseString LexSASProb.plan (readFile plan_file))
+
+
+type SAS_VAR = (string * (int * string list))
+
+fun varToString (variable_name: string,
+ (axiom_layer:int,
+ atom_names :string list)) =
+ " Variable name = " ^ variable_name ^
+ "\n Axiom layer = " ^ Int.toString(axiom_layer) ^
+ "\n Atoms:\n " ^ ((String.concatWith "\n ") atom_names);
+
+fun sasAssToString (varID: int, ass: int) =
+ " VariableID = " ^ Int.toString(varID) ^
+ " Ass = " ^ Int.toString(ass);
+
+fun mutexGroupToString (mutex_group: (int * int) list) =
+ "\n Mutex group asses:\n" ^ ((String.concatWith "\n") (map sasAssToString mutex_group));
+
+type SAS_ASS = int * int
+
+fun effectToString (effect_preconds: SAS_ASS list,
+ (var_ID: int,
+ (old_ass: int,
+ (new_ass)))) =
+ "\n Effect:" ^ ((String.concatWith "\n ") (map sasAssToString effect_preconds)) ^
+ "\n Var ID = " ^ Int.toString(var_ID) ^
+ " Old ass = " ^ Int.toString(new_ass) ^
+ " New ass = " ^ Int.toString(old_ass);
+
+type EFFECT = ((SAS_ASS list) * (int * (int * int)))
+
+fun operatorToString
+ (operator_name: string,
+ (preconds: SAS_ASS list,
+ (effects: EFFECT list,
+ (cost: int)))) =
+ " Operator name = " ^ operator_name ^
+ "\n Preconds:\n" ^ ((String.concatWith "\n ") (map sasAssToString preconds)) ^
+ "\n Effects:\n " ^ ((String.concatWith "\n ") (map effectToString effects)) ^
+ "\n Cost = " ^ Int.toString(cost);
+
+type MUTEX_GRP = ((SAS_ASS list))
+
+type OPRTR = string *
+ ((SAS_ASS list)*
+ ((EFFECT list) * int))
+
+type SAS_PROB = int*
+ (int*
+ ((SAS_VAR list) *
+ ((MUTEX_GRP list) *
+ ((int list)*
+ ((SAS_ASS list)*
+ ((OPRTR list) * int))))))
+
+fun probToString
+ (version_res:int,
+ (metric_res:int,
+ (variables: SAS_VAR list,
+ (mutex_groups: MUTEX_GRP list,
+ (init_state: int list,
+ (goal: SAS_ASS list,
+ (operators: OPRTR list,
+ num_axioms: int))))))) =
+ ("Version = " ^ (Int.toString version_res) ^ "\n") ^
+ ("Metric = " ^ (Int.toString metric_res) ^ "\n") ^
+ ("SAS+ vars:\n" ^ ((String.concatWith "\n") (map varToString variables)) ^ "\n") ^
+ ("Mutex Groups:\n" ^ ((String.concatWith "\n") (map mutexGroupToString mutex_groups)) ^ "\n") ^
+ ("Initial state:\n " ^ ((String.concatWith "\n ") (map Int.toString init_state)) ^ "\n") ^
+ ("Goals:\n " ^ ((String.concatWith "\n ") (map sasAssToString goal)) ^ "\n") ^
+ ("Operators:\n " ^ ((String.concatWith "\n ") (map operatorToString operators)) ^ "\n")
+
+fun planToString (plan: string list) =
+ ("Plan:\n " ^ ((String.concatWith "\n ") plan) ^ "\n")
+
+type PLAN = string list
+
+
+val IsabelleStringImplode = exported.implode;
+val IsabelleStringExplode = exported.explode;
+
+fun planToIsabellePlan plan = map IsabelleStringExplode plan
+
+fun variableToIsabelleVariable
+ (variable_name: string,
+ (axiom_layer: int,
+ atom_names: string list)) =
+ (IsabelleStringExplode variable_name,
+ (exported.nat_opt_of_integer(IntInf.fromInt axiom_layer),
+ map IsabelleStringExplode atom_names))
+
+fun sasAssToIsabelleSasAss (varID, ass) =
+ (exported.nat_of_integer (IntInf.fromInt varID),
+ exported.nat_of_integer (IntInf.fromInt ass))
+
+fun effectToIsabelleEffect
+ (effect_preconds: SAS_ASS list,
+ (var_ID: int,
+ (old_ass: int,
+ (new_ass)))) =
+ (map sasAssToIsabelleSasAss effect_preconds,
+ (exported.nat_of_integer (IntInf.fromInt var_ID),
+ (exported.nat_opt_of_integer (IntInf.fromInt old_ass),
+ exported.nat_of_integer (IntInf.fromInt new_ass))))
+
+fun operatorToIsabelleOperator
+ (operator_name: string,
+ (preconds: SAS_ASS list,
+ (effects: EFFECT list,
+ (cost: int)))) =
+ (IsabelleStringExplode operator_name,
+ (map sasAssToIsabelleSasAss preconds,
+ (map effectToIsabelleEffect effects,
+ exported.nat_of_integer (IntInf.fromInt cost))))
+
+fun problemToIsabelleProblem
+ (version_res:int,
+ (metric_res:int,
+ (variables: SAS_VAR list,
+ (mutex_groups: MUTEX_GRP list,
+ (init_state: int list,
+ (goal: SAS_ASS list,
+ (operators: OPRTR list,
+ num_axioms: int))))))) =
+(map variableToIsabelleVariable variables,
+ (map (exported.nat_of_integer o IntInf.fromInt) init_state,
+ (map sasAssToIsabelleSasAss goal,
+ (map operatorToIsabelleOperator operators))))
diff --git a/thys/Verified_SAT_Based_AI_Planning/document/root.bib b/thys/Verified_SAT_Based_AI_Planning/document/root.bib
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/document/root.bib
@@ -0,0 +1,1835 @@
+%% This BibTeX bibliography file was created using BibDesk.
+%% http://bibdesk.sourceforge.net/
+
+
+%% Created for Larry Paulson at 2020-11-13 12:45:07 +0000
+
+
+%% Saved with string encoding Unicode (UTF-8)
+
+
+@string{lncs = {Lecture Notes in Computer Science}}
+
+
+@misc{verifiedSATPlan,
+ archiveprefix = {arXiv},
+ author = {Mohammad Abdulaziz and Friedrich Kurz},
+ date-added = {2020-11-13 12:45:04 +0000},
+ date-modified = {2020-11-13 12:45:04 +0000},
+ eprint = {2010.14648},
+ primaryclass = {cs.AI},
+ title = {Formally Verified SAT-Based AI Planning},
+ year = {2020}}
+
+@techreport{PDDLref,
+ author = {Mc{D}ermott, Drew and Ghallab, Malik and Howe, Adele and Knoblock, Craig and Ram, Ashwin and Veloso, Manuela and Weld, Daniel and Wilkins, David},
+ institution = {CVC TR-98-003/DCS TR-1165, Yale Center for Computational Vision and Control},
+ priority = {2},
+ title = {{PDDL: The Planning Domain Definition Language}},
+ year = {1998}}
+
+@inproceedings{BiereCCZ99,
+ author = {Armin Biere and Alessandro Cimatti and Edmund M. Clarke and Yunshan Zhu},
+ booktitle = {{TACAS}},
+ pages = {193--207},
+ title = {Symbolic Model Checking without {BDDs}},
+ year = {1999}}
+
+@inproceedings{KroeningS03,
+ author = {Daniel Kroening and Ofer Strichman},
+ booktitle = {{VMCAI}},
+ pages = {298--309},
+ title = {Efficient Computation of Recurrence Diameters},
+ year = {2003}}
+
+@inproceedings{Rintanen:Gretton:2013,
+ author = {Jussi Rintanen and Charles Orgill Gretton},
+ booktitle = {International Joint Conference on Artificial Intelligence},
+ title = {Computing Upper Bounds on Lengths of Transition Sequences},
+ year = {2013}}
+
+@inproceedings{sievers:etal:12,
+ author = {S. Sievers and M. Ortlieb and M. Helmert},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {Proc. 5th Annual Symposium on Combinatorial Search},
+ ee = {http://www.aaai.org/ocs/index.php/SOCS/SOCS12/paper/view/5375},
+ title = {Efficient Implementation of Pattern Database Heuristics for Classical Planning},
+ year = {2012}}
+
+@inproceedings{sang:etal:05,
+ author = {T. Sang and P. Beame and H. A. Kautz},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {Proc. 8th International Conference on Theory and Applications of Satisfiability Testing},
+ ee = {http://dx.doi.org/10.1007/11499107_17},
+ pages = {226--240},
+ publisher = {Springer-Verlag},
+ title = {Heuristics for Fast Exact Model Counting},
+ year = {2005}}
+
+@article{luna:etal:07,
+ author = {G. Luna and P. Bello L{\'o}pez and M. C. Gonz{\'a}lez},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://www.engineeringletters.com/issues_v15/issue_2/EL_15_2_11.pdf},
+ journal = {Engineering Letters},
+ number = {2},
+ pages = {250--258},
+ title = {New Polynomial Classes for \#2{SAT} Established Via Graph-Topological Structure},
+ volume = {15},
+ year = {2007}}
+
+@inproceedings{streeter:07,
+ author = {M. J. Streeter and S. F. Smith},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {Proc. 17th International Conference on Automated Planning and Scheduling},
+ ee = {http://www.aaai.org/Library/ICAPS/2007/icaps07-040.php},
+ pages = {312--319},
+ publisher = {AAAI Press},
+ title = {Using Decision Procedures Efficiently for Optimization},
+ year = {2007}}
+
+@article{gimenez:jonsson:12,
+ author = {O. Gim{\'e}nez and A. Jonsson},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://dx.doi.org/10.1016/j.artint.2011.12.002},
+ journal = {Artificial Intelligence},
+ pages = {25--45},
+ title = {The influence of k-dependence on the complexity of planning},
+ volume = {177-179},
+ year = {2012}}
+
+@article{JonssonB98,
+ author = {Peter Jonsson and Christer B{\"a}ckstr{\"o}m},
+ journal = {Artificial Intelligence},
+ number = {1-2},
+ pages = {125-176},
+ title = {State-Variable Planning Under Structural Restrictions: Algorithms and Complexity},
+ volume = {100},
+ year = {1998}}
+
+@article{brafman:domshlak:03,
+ author = {R. I. Brafman and C. Domshlak},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://dx.doi.org/10.1613/jair.1146},
+ journal = {Journal of Artificial Intelligence Research},
+ pages = {315--349},
+ title = {Structure and Complexity in Planning with Unary Operators},
+ volume = {18},
+ year = {2003}}
+
+@article{bylander:94,
+ author = {T. Bylander},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://dx.doi.org/10.1016/0004-3702(94)90081-7},
+ journal = {Artificial Intelligence},
+ number = {1-2},
+ pages = {165--204},
+ title = {The Computational Complexity of Propositional {STRIPS} Planning},
+ volume = {69},
+ year = {1994}}
+
+@inproceedings{williams:nayak:97,
+ author = {Brian C. Williams and P. Pandurang Nayak},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {International Joint Conference on Artificial Intelligence},
+ pages = {1178--1185},
+ publisher = {Morgan Kaufmann Publishers},
+ title = {A Reactive Planner for a Model-based Executive},
+ year = {1997}}
+
+@article{knoblock:94,
+ author = {C. A. Knoblock},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://dx.doi.org/10.1016/0004-3702(94)90069-8},
+ journal = {Artificial Intelligence},
+ number = {2},
+ pages = {243--302},
+ title = {Automatically Generating Abstractions for Planning},
+ volume = {68},
+ year = {1994}}
+
+@article{rintanen:12,
+ author = {Jussi Rintanen},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://dx.doi.org/10.1016/j.artint.2012.08.001},
+ journal = {Artificial Intelligence},
+ pages = {45--86},
+ title = {Planning as satisfiability: Heuristics},
+ volume = {193},
+ year = {2012}}
+
+@inproceedings{haslum:07,
+ author = {Patrik Haslum},
+ booktitle = {ICAPS workshop on the IPC: Past, Present and Future},
+ title = {Quality of Solutions to {IPC5} Benchmark Problems: Preliminary Results},
+ year = {2007}}
+
+@article{Helmert06,
+ author = {Malte Helmert},
+ journal = {Journal of Artificial Intelligence Research},
+ pages = {191-246},
+ title = {The {Fast} {Downward} Planning System},
+ volume = {26},
+ year = {2006}}
+
+@inproceedings{haslum:etal:07,
+ author = {P. Haslum and A. Botea and M. Helmert and B. Bonet and S. Koenig},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {Proc 22nd AAAI Conf. on Artificial Intelligence},
+ ee = {http://www.aaai.org/Library/AAAI/2007/aaai07-160.php},
+ pages = {1007--1012},
+ publisher = {AAAI Press},
+ title = {Domain-Independent Construction of Pattern Database Heuristics for Cost-Optimal Planning},
+ year = {2007}}
+
+@inproceedings{kautz:selman:96,
+ author = {H. A. Kautz and B. Selman},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {Proc. 13th National Conf. on Artificial Intelligence},
+ ee = {http://www.aaai.org/Library/AAAI/1996/aaai96-177.php},
+ pages = {1194--1201},
+ publisher = {AAAI Press},
+ title = {Pushing the Envelope: Planning, Propositional Logic and Stochastic Search},
+ year = {1996}}
+
+@inproceedings{kautz:selman:92,
+ author = {H. A. Kautz and B. Selman},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {ECAI},
+ pages = {359--363},
+ title = {Planning as Satisfiability},
+ year = {1992}}
+
+@book{abelson-et-al:scheme,
+ address = {Cambridge, Massachusetts},
+ author = {Harold Abelson and Gerald~Jay Sussman and Julie Sussman},
+ publisher = {MIT Press},
+ title = {Structure and Interpretation of Computer Programs},
+ year = {1985}}
+
+@inproceedings{HOLsystem,
+ author = {Konrad Slind and Michael Norrish},
+ booktitle = {TPHOLs},
+ title = {A Brief Overview of {HOL4}},
+ year = 2008}
+
+@inproceedings{HOLsystemL,
+ author = {Konrad Slind and Michael Norrish},
+ booktitle = {Theorem Proving in Higher Order Logics},
+ pages = {28--32},
+ publisher = {Springer},
+ series = {LNCS},
+ title = {A Brief Overview of {HOL4}},
+ volume = 5170,
+ year = 2008}
+
+@inproceedings{anonymous,
+ author = {Hidden},
+ booktitle = {Hidden},
+ title = {Title hidden to preserve anonymity.},
+ year = {2014}}
+
+@inproceedings{Selman94,
+ author = {Selman, Bart},
+ booktitle = {KR},
+ pages = {521--529},
+ title = {Near-optimal plans, tractability, and reactivity},
+ year = {1994}}
+
+@article{cooper:etal:11,
+ author = {M. C. Cooper and M. de Roquemaurel and P. R{\'e}gnier},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://dx.doi.org/10.3233/AIC-2010-0473},
+ journal = {AI Commun.},
+ number = {1},
+ pages = {1--9},
+ title = {A weighted {CSP} approach to cost-optimal planning},
+ volume = {24},
+ year = {2011}}
+
+@inproceedings{gerevini:schubert:98,
+ author = {A. Gerevini and L. K. Schubert},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {Proc. 15th National Conf. on Artificial Intelligence},
+ ee = {http://www.aaai.org/Library/AAAI/1998/aaai98-128.php},
+ pages = {905--912},
+ publisher = {AAAI Press},
+ title = {Inferring State Constraints for Domain-Independent Planning},
+ year = {1998}}
+
+@article{JonssonBackstrom98b,
+ author = {P. Jonsson and C. B{\"a}ckstr{\"o}m},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://dx.doi.org/10.1023/A:1018995620232},
+ journal = {Ann. Math. Artificial Intelligence},
+ number = {3-4},
+ pages = {281--296},
+ title = {Tractable Plan Existence Does Not Imply Tractable Plan Generation},
+ volume = {22},
+ year = {1998}}
+
+@article{hart:etal:68,
+ author = {P. E. Hart and N. J. Nilsson and B. Raphael},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://dx.doi.org/10.1109/TSSC.1968.300136},
+ journal = {IEEE Trans. Systems Science and Cybernetics},
+ number = {2},
+ pages = {100--107},
+ title = {A Formal Basis for the Heuristic Determination of Minimum Cost Paths},
+ volume = {4},
+ year = {1968}}
+
+@inproceedings{haslum:geffner:00,
+ author = {P. Haslum and H. Geffner},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {Proc. Int. Conf. on AI Planning Systems},
+ ee = {http://www.aaai.org/Library/AIPS/2000/aips00-015.php},
+ pages = {140--149},
+ title = {Admissible Heuristics for Optimal Planning},
+ year = {2000}}
+
+@article{drager:etal:09,
+ author = {K. Dr{\"a}ger and B. Finkbeiner and A. Podelski},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://dx.doi.org/10.1007/s10009-008-0092-z},
+ journal = {STTT},
+ number = {1},
+ pages = {27--37},
+ title = {Directed model checking with distance-preserving abstractions},
+ volume = {11},
+ year = {2009}}
+
+@article{bonet:geffner:01,
+ author = {Blai Bonet and Hector Geffner},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://dx.doi.org/10.1016/S0004-3702(01)00108-4},
+ journal = {Artificial Intelligence},
+ number = {1-2},
+ pages = {5--33},
+ title = {Planning as heuristic search},
+ volume = {129},
+ year = {2001}}
+
+@inproceedings{korf:97,
+ author = {R. E. Korf},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {Proc. 14th National Conf. on Artificial Intelligence},
+ ee = {http://www.aaai.org/Library/AAAI/1997/aaai97-109.php},
+ pages = {700--705},
+ publisher = {AAAI Press},
+ title = {Finding Optimal Solutions to {R}ubik's Cube Using Pattern Databases},
+ year = {1997}}
+
+@inproceedings{culberson:schaeffer:96,
+ author = {J. C. Culberson and J. Schaeffer},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {Canadian Conf. on AI},
+ ee = {http://dx.doi.org/10.1007/3-540-61291-2_68},
+ pages = {402--416},
+ publisher = {Springer-Verlag},
+ title = {Searching with Pattern Databases},
+ year = {1996}}
+
+@article{tarjan:72,
+ author = {R. E. Tarjan},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ ee = {http://dx.doi.org/10.1137/0201010},
+ journal = {SIAM J. Comput.},
+ number = {2},
+ pages = {146--160},
+ title = {Depth-First Search and Linear Graph Algorithms},
+ volume = {1},
+ year = {1972}}
+
+@inproceedings{rintanen:08,
+ author = {Rintanen, Jussi},
+ booktitle = {Proc. 18th European Conf. on AI},
+ pages = {568--571},
+ publisher = {IOS Press},
+ title = {Regression for classical and nondeterministic planning},
+ year = 2008}
+
+@inproceedings{rintanen:04,
+ author = {Jussi Rintanen},
+ bibsource = {DBLP, http://dblp.uni-trier.de},
+ booktitle = {Proc. 16th European Conf. on Artificial Intelligence},
+ pages = {682--687},
+ publisher = {IOS Press},
+ title = {Evaluation Strategies for Planning as Satisfiability},
+ year = {2004}}
+
+@inproceedings{robinson09,
+ author = {Nathan Robinson and Charles Gretton and Duc Nghia Pham and Abdul Sattar},
+ booktitle = {ICAPS},
+ title = {{SAT}-Based Parallel Planning Using a Split Representation of Actions},
+ year = {2009}}
+
+@inproceedings{bgf:Lixto,
+ address = {Rome, Italy},
+ author = {Robert Baumgartner and Georg Gottlob and Sergio Flesca},
+ booktitle = {Proceedings of the 27th Intnl. Conf. on Very Large Databases},
+ month = {September},
+ pages = {119-128},
+ publisher = {Morgan Kaufmann},
+ title = {Visual Information Extraction with {Lixto}},
+ year = {2001}}
+
+@article{brachman-schmolze:kl-one,
+ author = {Ronald~J. Brachman and James~G. Schmolze},
+ journal = {Cognitive Science},
+ month = {April--June},
+ number = {2},
+ pages = {171--216},
+ title = {An overview of the {KL-ONE} knowledge representation system},
+ volume = {9},
+ year = {1985}}
+
+@article{gottlob:nonmon,
+ author = {Georg Gottlob},
+ journal = {Journal of Logic and Computation},
+ month = {June},
+ number = {3},
+ pages = {397--425},
+ title = {Complexity results for nonmonotonic logics},
+ volume = {2},
+ year = {1992}}
+
+@article{gls:hypertrees,
+ author = {Georg Gottlob and Nicola Leone and Francesco Scarcello},
+ journal = {Journal of Computer and System Sciences},
+ month = {May},
+ number = {3},
+ pages = {579--627},
+ title = {Hypertree Decompositions and Tractable Queries},
+ volume = {64},
+ year = {2002}}
+
+@article{levesque:functional-foundations,
+ author = {Hector~J. Levesque},
+ journal = {Artificial Intelligence},
+ month = {July},
+ number = {2},
+ pages = {155--212},
+ title = {Foundations of a functional approach to knowledge representation},
+ volume = {23},
+ year = {1984}}
+
+@inproceedings{levesque:belief,
+ address = {Austin, Texas},
+ author = {Hector~J. Levesque},
+ booktitle = {Proceedings of the Fourth National Conf. on Artificial Intelligence},
+ month = {August},
+ pages = {198--202},
+ publisher = {American Association for Artificial Intelligence},
+ title = {A logic of implicit and explicit belief},
+ year = {1984}}
+
+@article{nebel:jair-2000,
+ author = {Bernhard Nebel},
+ journal = {Journal of Artificial Intelligence Research},
+ pages = {271--315},
+ title = {On the compilability and expressive power of propositional planning formalisms},
+ volume = {12},
+ year = {2000}}
+
+@book{hodges1993model,
+ author = {Hodges, Wilfrid},
+ publisher = {Cambridge University Press Cambridge},
+ title = {Model theory},
+ volume = {42},
+ year = {1993}}
+
+@book{jackson2006:alloy-book,
+ author = {Daniel Jackson},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/books/daglib/0024034},
+ isbn = {978-0-262-10114-1},
+ publisher = {{MIT} Press},
+ timestamp = {Fri, 20 Oct 4446299 22:18:08 +},
+ title = {Software Abstractions: Logic, Language, and Analysis},
+ year = {2006}}
+
+@inproceedings{Nipkow-ICTAC06,
+ author = {Tobias Nipkow},
+ booktitle = {Theoretical Aspects of Computing (ICTAC 2006)},
+ editor = {K. Barkaoui and A. Cavalcanti and A. Cerone},
+ note = {Invited paper.},
+ publisher = {Springer},
+ series = LNCS,
+ title = {Verifying a Hotel Key Card System},
+ volume = 4281,
+ year = 2006}
+
+@inproceedings{baumgartner2002property,
+ author = {Baumgartner, Jason and Kuehlmann, Andreas and Abraham, Jacob},
+ booktitle = {Computer Aided Verification},
+ organization = {Springer},
+ pages = {151--165},
+ title = {Property Checking Via Structural Analysis},
+ year = {2002}}
+
+@inproceedings{BlanchetteN10,
+ author = {Jasmin Christian Blanchette and Tobias Nipkow},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ booktitle = {Interactive Theorem Proving, First International Conference, {ITP} 2010},
+ doi = {10.1007/978-3-642-14052-5_11},
+ pages = {131--146},
+ title = {Nitpick: {A} Counterexample Generator for Higher-Order Logic Based on a Relational Model Finder},
+ year = {2010},
+ Bdsk-Url-1 = {https://doi.org/10.1007/978-3-642-14052-5_11}}
+
+@inproceedings{DBLP:conf/date/BaumgartnerK04,
+ author = {Jason Baumgartner and Andreas Kuehlmann},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/date/BaumgartnerK04},
+ booktitle = {{DATE} 2004, 16-20 February 2004, Paris, France},
+ doi = {10.1109/DATE.2004.1268824},
+ pages = {36--41},
+ timestamp = {Wed, 26 Oct 2011 12:00:27 +0200},
+ title = {Enhanced Diameter Bounding via Structural Analysis},
+ year = {2004},
+ Bdsk-Url-1 = {https://doi.org/10.1109/DATE.2004.1268824}}
+
+@article{DBLP:journals/ac/BiereCCSZ03,
+ author = {Armin Biere and Alessandro Cimatti and Edmund M. Clarke and Ofer Strichman and Yunshan Zhu},
+ journal = {Advances in Computers},
+ pages = {117--148},
+ title = {Bounded model checking},
+ volume = {58},
+ year = {2003}}
+
+@inproceedings{DBLP:conf/fmcad/SheeranSS00,
+ author = {Mary Sheeran and Satnam Singh and Gunnar St{\aa}lmarck},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/fmcad/SheeranSS00},
+ booktitle = {Formal Methods in Computer-Aided Design, Third International Conference, {FMCAD} 2000, Austin, Texas, USA, November 1-3, 2000, Proceedings},
+ doi = {10.1007/3-540-40922-X_8},
+ pages = {108--125},
+ timestamp = {Tue, 21 Jun 2011 16:40:02 +0200},
+ title = {Checking Safety Properties Using Induction and a {SAT}-Solver},
+ year = {2000},
+ Bdsk-Url-1 = {https://doi.org/10.1007/3-540-40922-X_8}}
+
+@inproceedings{DBLP:conf/nca/SastryW14,
+ author = {Srikanth Sastry and Josef Widder},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/nca/SastryW14},
+ booktitle = {2014 {IEEE} 13th International Symposium on Network Computing and Applications, {NCA} 2014, Cambridge, MA, USA, 21-23 August, 2014},
+ doi = {10.1109/NCA.2014.46},
+ pages = {269--276},
+ timestamp = {Tue, 25 Nov 2014 17:05:18 +0100},
+ title = {Solvability-Based Comparison of Failure Detectors},
+ year = {2014},
+ Bdsk-Url-1 = {https://doi.org/10.1109/NCA.2014.46}}
+
+@inproceedings{DBLP:conf/date/GanaiG08,
+ author = {Malay K. Ganai and Aarti Gupta},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/date/GanaiG08},
+ booktitle = {Design, Automation and Test in Europe, {DATE} 2008, Munich, Germany, March 10-14, 2008},
+ doi = {10.1109/DATE.2008.4484777},
+ pages = {831--836},
+ timestamp = {Mon, 21 Sep 2009 09:13:26 +0200},
+ title = {Completeness in {SMT}-based {BMC} for Software Programs},
+ year = {2008},
+ Bdsk-Url-1 = {https://doi.org/10.1109/DATE.2008.4484777}}
+
+@inproceedings{DBLP:conf/fmcad/CaseMBK09,
+ author = {Michael L. Case and Hari Mony and Jason Baumgartner and Robert Kanzelman},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/fmcad/CaseMBK09},
+ booktitle = {{FMCAD} 2009, 15-18 November 2009, Austin, Texas, {USA}},
+ pages = {17--24},
+ timestamp = {Wed, 27 Jan 2010 15:12:16 +0100},
+ title = {Enhanced verification by temporal decomposition},
+ year = {2009}}
+
+@article{soares1992maximum,
+ author = {Soares, Jos{\'e}},
+ journal = {Journal of Graph Theory},
+ number = {5},
+ pages = {437--450},
+ publisher = {Wiley Online Library},
+ title = {Maximum diameter of regular digraphs},
+ volume = {16},
+ year = {1992}}
+
+@article{erdHos1989radius,
+ author = {Erd{\H{o}}s, Paul and Pach, Janos and Pollack, Richard and Tuza, Zsolt},
+ journal = {Journal of Combinatorial Theory, Series B},
+ number = {1},
+ pages = {73--79},
+ publisher = {Elsevier},
+ title = {Radius, diameter, and minimum degree},
+ volume = {47},
+ year = {1989}}
+
+@article{moon1965diameter,
+ author = {Moon, John W and others},
+ journal = {The Michigan Mathematical Journal},
+ number = {3},
+ pages = {349--351},
+ publisher = {The University of Michigan},
+ title = {On the diameter of a graph.},
+ volume = {12},
+ year = {1965}}
+
+@article{knyazev1987diameters,
+ author = {Knyazev, AV},
+ journal = {Mathematical Notes},
+ number = {6},
+ pages = {473--482},
+ publisher = {Springer},
+ title = {Diameters of pseudosymmetric graphs},
+ volume = {41},
+ year = {1987}}
+
+@article{dankelmann2005diameter,
+ author = {Dankelmann, Peter},
+ journal = {Journal of Combinatorial Theory, Series B},
+ number = {1},
+ pages = {183--186},
+ publisher = {Elsevier},
+ title = {The diameter of directed graphs},
+ volume = {94},
+ year = {2005}}
+
+@article{dankelmann2010diameter,
+ author = {Dankelmann, Peter and Volkmann, Lutz},
+ journal = {the electronic journal of combinatorics},
+ number = {1},
+ pages = {R157},
+ title = {The diameter of almost Eulerian digraphs},
+ volume = {17},
+ year = {2010}}
+
+@article{dankelmann2016diameter,
+ author = {Dankelmann, Peter and Dorfling, Michael},
+ journal = {Discrete Mathematics},
+ number = {4},
+ pages = {1355--1361},
+ publisher = {North-Holland},
+ title = {Diameter and maximum degree in Eulerian digraphs},
+ volume = {339},
+ year = {2016}}
+
+@inproceedings{clarke2001progress,
+ author = {Clarke, Edmund and Grumberg, Orna and Jha, Somesh and Lu, Yuan and Veith, Helmut},
+ booktitle = {Informatics},
+ organization = {Springer},
+ pages = {176--194},
+ title = {Progress on the state explosion problem in model checking},
+ year = {2001}}
+
+@inproceedings{kroening2011linear,
+ author = {Kroening, Daniel and Ouaknine, Jo{\"e}l and Strichman, Ofer and Wahl, Thomas and Worrell, James},
+ booktitle = {Computer Aided Verification},
+ organization = {Springer},
+ pages = {557--572},
+ title = {Linear completeness thresholds for bounded model checking},
+ year = {2011}}
+
+@inproceedings{bundala2012magnitude,
+ author = {Bundala, Daniel and Ouaknine, Jo{\"e}l and Worrell, James},
+ booktitle = {Proceedings of the 2012 27th Annual IEEE/ACM Symposium on Logic in Computer Science},
+ organization = {IEEE Computer Society},
+ pages = {155--164},
+ title = {On the magnitude of completeness thresholds in bounded model checking},
+ year = {2012}}
+
+@article{fikes1971strips,
+ author = {Fikes, Richard E and Nilsson, Nils J},
+ journal = {Artificial intelligence},
+ number = {3-4},
+ pages = {189--208},
+ publisher = {Elsevier},
+ title = {STRIPS: A new approach to the application of theorem proving to problem solving},
+ volume = {2},
+ year = {1971}}
+
+@incollection{mcmillan1993symbolic,
+ author = {McMillan, Kenneth L},
+ booktitle = {Symbolic Model Checking},
+ pages = {25--60},
+ publisher = {Springer},
+ title = {Symbolic model checking},
+ year = {1993}}
+
+@article{kroening2006computing,
+ author = {Kroening, Daniel},
+ journal = {Electronic Notes in Theoretical Computer Science},
+ number = {1},
+ pages = {79--92},
+ publisher = {Elsevier},
+ title = {Computing over-approximations with bounded model checking},
+ volume = {144},
+ year = {2006}}
+
+@article{yuster2010computing,
+ author = {Yuster, Raphael},
+ journal = {arXiv preprint arXiv:1011.6181},
+ title = {{Computing the diameter polynomially faster than APSP}},
+ year = {2010}}
+
+@article{asgharian2016approximation,
+ author = {Asgharian Sardroud, Asghar and Bagheri, Alireza},
+ journal = {Optimization Methods and Software},
+ number = {3},
+ pages = {479--493},
+ publisher = {Taylor \& Francis},
+ title = {An approximation algorithm for the longest path problem in solid grid graphs},
+ volume = {31},
+ year = {2016}}
+
+@article{bjorklund2003finding,
+ author = {Bj{\"o}rklund, Andreas and Husfeldt, Thore},
+ journal = {SIAM Journal on Computing},
+ number = {6},
+ pages = {1395--1402},
+ publisher = {SIAM},
+ title = {Finding a path of superlogarithmic length},
+ volume = {32},
+ year = {2003}}
+
+@inproceedings{bjorklund2004approximating,
+ author = {Bj{\"o}rklund, Andreas and Husfeldt, Thore and Khanna, Sanjeev},
+ booktitle = {International Colloquium on Automata, Languages, and Programming},
+ organization = {Springer},
+ pages = {222--233},
+ title = {Approximating longest directed paths and cycles},
+ year = {2004}}
+
+@article{aingworth1999fast,
+ author = {Aingworth, Donald and Chekuri, Chandra and Indyk, Piotr and Motwani, Rajeev},
+ journal = {SIAM Journal on Computing},
+ number = {4},
+ pages = {1167--1181},
+ publisher = {SIAM},
+ title = {Fast estimation of diameter and shortest paths (without matrix multiplication)},
+ volume = {28},
+ year = {1999}}
+
+@incollection{berezin1998compositional,
+ author = {Berezin, Sergey and Campos, S{\'e}rgio and Clarke, Edmund M},
+ booktitle = {Compositionality: The Significant Difference},
+ pages = {81--102},
+ publisher = {Springer},
+ title = {Compositional reasoning in model checking},
+ year = {1998}}
+
+@article{alon1997exponent,
+ author = {Alon, Noga and Galil, Zvi and Margalit, Oded},
+ journal = {Journal of Computer and System Sciences},
+ number = {2},
+ pages = {255--262},
+ publisher = {Elsevier},
+ title = {On the exponent of the all pairs shortest path problem},
+ volume = {54},
+ year = {1997}}
+
+@article{chan2010more,
+ author = {Chan, Timothy M},
+ journal = {SIAM Journal on Computing},
+ number = {5},
+ pages = {2075--2089},
+ publisher = {SIAM},
+ title = {More algorithms for all-pairs shortest paths in weighted graphs},
+ volume = {39},
+ year = {2010}}
+
+@article{fredman1976new,
+ author = {Fredman, Michael L},
+ journal = {SIAM Journal on Computing},
+ number = {1},
+ pages = {83--89},
+ publisher = {SIAM},
+ title = {New bounds on the complexity of the shortest path problem},
+ volume = {5},
+ year = {1976}}
+
+@inproceedings{chechik2014better,
+ author = {Chechik, Shiri and Larkin, Daniel H and Roditty, Liam and Schoenebeck, Grant and Tarjan, Robert E and Williams, Virginia Vassilevska},
+ booktitle = {Proceedings of the Twenty-Fifth Annual ACM-SIAM Symposium on Discrete Algorithms},
+ organization = {Society for Industrial and Applied Mathematics},
+ pages = {1041--1052},
+ title = {Better approximation algorithms for the graph diameter},
+ year = {2014}}
+
+@inproceedings{roditty2013fast,
+ author = {Roditty, Liam and Vassilevska Williams, Virginia},
+ booktitle = {Proceedings of the forty-fifth annual ACM symposium on Theory of computing},
+ organization = {ACM},
+ pages = {515--524},
+ title = {Fast approximation algorithms for the diameter and radius of sparse graphs},
+ year = {2013}}
+
+@inproceedings{abboud2016approximation,
+ author = {Abboud, Amir and Williams, Virginia Vassilevska and Wang, Joshua},
+ booktitle = {Proceedings of the twenty-seventh annual ACM-SIAM symposium on Discrete Algorithms},
+ organization = {SIAM},
+ pages = {377--391},
+ title = {Approximation and fixed parameter subquadratic algorithms for radius and diameter in sparse graphs},
+ year = {2016}}
+
+@article{alon1995color,
+ author = {Alon, Noga and Yuster, Raphael and Zwick, Uri},
+ journal = {Journal of the ACM (JACM)},
+ number = {4},
+ pages = {844--856},
+ publisher = {ACM},
+ title = {Color-coding},
+ volume = {42},
+ year = {1995}}
+
+@article{bulterman2002computing,
+ author = {Bulterman, RW and van der Sommen, FW and Zwaan, Gerard and Verhoeff, Tom and van Gasteren, AJM and Feijen, WHJ},
+ journal = {Information Processing Letters},
+ number = {2},
+ pages = {93--96},
+ publisher = {Elsevier North-Holland, Inc.},
+ title = {On computing a longest path in a tree},
+ volume = {81},
+ year = {2002}}
+
+@article{gutin1993finding,
+ author = {Gutin, Gregory},
+ journal = {SIAM Journal on Discrete Mathematics},
+ number = {2},
+ pages = {270--273},
+ publisher = {SIAM},
+ title = {Finding a longest path in a complete multipartite digraph},
+ volume = {6},
+ year = {1993}}
+
+@article{clarke2009turing,
+ author = {Clarke, Edmund M and Emerson, E Allen and Sifakis, Joseph},
+ journal = {Communications of the ACM},
+ number = {11},
+ pages = {74--84},
+ title = {Turing lecture: model checking--algorithmic verification and debugging},
+ volume = {52},
+ year = {2009}}
+
+@inproceedings{knoblock1991characterizing,
+ author = {Knoblock, Craig A and Tenenberg, Josh D and Yang, Qiang},
+ booktitle = {AAAI},
+ pages = {692--697},
+ title = {Characterizing Abstraction Hierarchies for Planning.},
+ year = {1991}}
+
+@inproceedings{clarke2000counterexample,
+ author = {Clarke, Edmund and Grumberg, Orna and Jha, Somesh and Lu, Yuan and Veith, Helmut},
+ booktitle = {International Conference on Computer Aided Verification},
+ organization = {Springer},
+ pages = {154--169},
+ title = {Counterexample-guided abstraction refinement},
+ year = {2000}}
+
+@article{sacerdoti1974planning,
+ author = {Sacerdoti, Earl D},
+ journal = {Artificial intelligence},
+ number = {2},
+ pages = {115--135},
+ publisher = {Elsevier},
+ title = {Planning in a hierarchy of abstraction spaces},
+ volume = {5},
+ year = {1974}}
+
+@article{seippfast,
+ author = {Seipp, Jendrik and Pommerening, Florian and Sievers, Silvan and Wehrle, Martin and Fawcett, Chris and Alkhazraji, Yusra},
+ title = {{Fast Downward Aidos}}}
+
+@inproceedings{clarke2004completeness,
+ author = {Clarke, Edmund and Kroening, Daniel and Ouaknine, Jo{\"e}l and Strichman, Ofer},
+ booktitle = {International Workshop on Verification, Model Checking, and Abstract Interpretation},
+ organization = {Springer},
+ pages = {85--96},
+ title = {Completeness and complexity of bounded model checking},
+ year = {2004}}
+
+@inproceedings{uehara2004efficient,
+ author = {Uehara, Ryuhei and Uno, Yushi},
+ booktitle = {International Symposium on Algorithms and Computation},
+ organization = {Springer},
+ pages = {871--883},
+ title = {Efficient algorithms for the longest path problem},
+ year = {2004}}
+
+@inproceedings{porco2013automatic,
+ author = {Porco, Aldo and Machado, Alejandro and Bonet, Blai},
+ booktitle = {ICAPS},
+ title = {Automatic Reductions from {PH} into {STRIPS} or How to Generate Short Problems with Very Long Solutions.},
+ year = {2013}}
+
+@article{BrownFP96,
+ author = {Cynthia A. Brown and Larry Finkelstein and Paul Walton Purdom Jr.},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/journals/njc/BrownFP96},
+ journal = {Nord. J. Comput.},
+ number = {3},
+ pages = {203--219},
+ timestamp = {Mon, 24 Jul 2006 10:22:32 +0200},
+ title = {Backtrack Searching in the Presence of Symmetry},
+ volume = {3},
+ year = {1996}}
+
+@inproceedings{DeMoura:2008:ZES:1792734.1792766,
+ author = {De Moura, Leonardo and Bj{\o}rner, Nikolaj},
+ booktitle = {Proc. TACAS'08/ETAPS'08},
+ location = {Budapest, Hungary},
+ pages = {337--340},
+ title = {Z3: An Efficient SMT Solver},
+ year = {2008}}
+
+@article{McKay201494,
+ author = {Brendan D. McKay and Adolfo Piperno},
+ doi = {http://dx.doi.org/10.1016/j.jsc.2013.09.003},
+ issn = {0747-7171},
+ journal = {Journal of Symbolic Computation},
+ number = {0},
+ pages = {94 - 112},
+ title = {Practical graph isomorphism, \{II\}},
+ url = {http://www.sciencedirect.com/science/article/pii/S0747717113001193},
+ volume = {60},
+ year = {2014},
+ Bdsk-Url-1 = {http://www.sciencedirect.com/science/article/pii/S0747717113001193},
+ Bdsk-Url-2 = {http://dx.doi.org/10.1016/j.jsc.2013.09.003}}
+
+@article{richter2010lama,
+ author = {Richter, Silvia and Westphal, Matthias},
+ journal = {Journal of Artificial Intelligence Research},
+ number = {1},
+ pages = {127--177},
+ title = {The {LAMA} Planner: Guiding Cost-based Anytime Planning with Landmarks},
+ volume = {39},
+ year = {2010}}
+
+@inproceedings{shleyfman2015heuristics,
+ author = {Shleyfman, Alexander and Katz, Michael and Helmert, Malte and Sievers, Silvan and Wehrle, Martin},
+ booktitle = {AAAI},
+ title = {Heuristics and Symmetries in Classical Planning},
+ year = {2015}}
+
+@inproceedings{DomshlakKS13,
+ author = {Carmel Domshlak and Michael Katz and Alexander Shleyfman},
+ booktitle = {ICAPS},
+ title = {Symmetry Breaking: Satisficing Planning and Landmark Heuristics},
+ year = {2013}}
+
+@article{helmert2014merge,
+ author = {Helmert, Malte and Haslum, Patrik and Hoffmann, J{\"o}rg and Nissim, Raz},
+ journal = {Journal of the ACM (JACM)},
+ number = {3},
+ pages = {16},
+ publisher = {ACM},
+ title = {Merge-and-shrink abstraction: A method for generating lower bounds in factored state spaces},
+ volume = {61},
+ year = {2014}}
+
+@inproceedings{amir2003factored,
+ author = {Amir, Eyal and Engelhardt, Barbara},
+ booktitle = {IJCAI},
+ organization = {Citeseer},
+ pages = {929--935},
+ title = {Factored planning},
+ volume = {3},
+ year = {2003}}
+
+@inproceedings{brafman2006factored,
+ author = {Brafman, Ronen I and Domshlak, Carmel},
+ booktitle = {AAAI},
+ pages = {809--814},
+ title = {Factored planning: How, when, and when not},
+ volume = {6},
+ year = {2006}}
+
+@inproceedings{kelareva2007factored,
+ author = {Kelareva, Elena and Buffet, Olivier and Huang, Jinbo and Thi{\'e}baux, Sylvie},
+ booktitle = {IJCAI},
+ pages = {1942--1947},
+ title = {Factored Planning Using Decomposition Trees.},
+ year = {2007}}
+
+@inproceedings{sievers:2015,
+ author = {Silvan Sievers and Martin Wehrle and Malte Helmert and Alexander Shleyfman and Michael Katz},
+ booktitle = {Proc. 29th National Conf. on Artificial Intelligence},
+ publisher = {AAAI Press},
+ title = {Factored Symmetries for Merge-and-Shrink Abstractions},
+ year = {2015}}
+
+@article{crawford1996symmetry,
+ author = {Crawford, James and Ginsberg, Matthew and Luks, Eugene and Roy, Amitabha},
+ journal = {KR},
+ pages = {148--159},
+ title = {Symmetry-breaking predicates for search problems},
+ volume = {96},
+ year = {1996}}
+
+@inproceedings{GuereA01,
+ author = {Emmanuel Guere and Rachid Alami},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/ijcai/GuereA01},
+ booktitle = {Proceedings of the Seventeenth International Joint Conference on Artificial Intelligence, {IJCAI} 2001, Seattle, Washington, USA, August 4-10, 2001},
+ pages = {439--444},
+ timestamp = {Mon, 20 Apr 2009 09:38:06 +0200},
+ title = {One action is enough to plan},
+ year = {2001}}
+
+@inproceedings{JoslinR97,
+ author = {David Joslin and Amitabha Roy},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/aaai/JoslinR97},
+ booktitle = {Proceedings of the Fourteenth National Conference on Artificial Intelligence and Ninth Innovative Applications of Artificial Intelligence Conference, {AAAI} 97, {IAAI} 97, July 27-31, 1997, Providence, Rhode Island.},
+ pages = {197--202},
+ timestamp = {Tue, 11 Dec 2012 12:57:22 +0100},
+ title = {Exploiting Symmetry in Lifted {CSPs}},
+ year = {1997}}
+
+@inproceedings{rintanen2003symmetry,
+ author = {Rintanen, Jussi},
+ booktitle = {ICAPS},
+ pages = {32--41},
+ title = {Symmetry Reduction for {SAT} Representations of Transition Systems.},
+ year = {2003}}
+
+@inproceedings{domshlak2012enhanced,
+ author = {Domshlak, Carmel and Katz, Michael and Shleyfman, Alexander},
+ booktitle = {ICAPS},
+ title = {Enhanced Symmetry Breaking in Cost-Optimal Planning as Forward Search.},
+ year = {2012}}
+
+@inproceedings{pochter2011exploiting,
+ author = {Pochter, Nir and Zohar, Aviv and Rosenschein, Jeffrey S},
+ booktitle = {AAAI},
+ title = {Exploiting Problem Symmetries in State-Based Planners.},
+ year = {2011}}
+
+@article{WahlD10,
+ author = {Thomas Wahl and Alastair F. Donaldson},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/journals/symmetry/WahlD10},
+ doi = {10.3390/sym2020799},
+ journal = {Symmetry},
+ number = {2},
+ pages = {799--847},
+ timestamp = {Mon, 21 Feb 2011 21:51:20 +0100},
+ title = {Replication and Abstraction: Symmetry in Automated Formal Verification},
+ url = {http://dx.doi.org/10.3390/sym2020799},
+ volume = {2},
+ year = {2010},
+ Bdsk-Url-1 = {http://dx.doi.org/10.3390/sym2020799}}
+
+@inproceedings{FoxL99,
+ author = {Maria Fox and Derek Long},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/ijcai/FoxL99},
+ booktitle = {Proceedings of the Sixteenth International Joint Conference on Artificial Intelligence, {IJCAI} 99, Stockholm, Sweden, July 31 - August 6, 1999. 2 Volumes, 1450 pages},
+ pages = {956--961},
+ title = {The Detection and Exploitation of Symmetry in Planning Problems},
+ year = {1999}}
+
+@inproceedings{FoxL02,
+ author = {Maria Fox and Derek Long},
+ booktitle = {Proceedings of the Sixth International Conference on Artificial Intelligence Planning Systems, April 23-27, 2002, Toulouse, France},
+ pages = {83--91},
+ title = {Extending the Exploitation of Symmetries in Planning},
+ year = {2002}}
+
+@article{helmert2006fast,
+ author = {Helmert, Malte},
+ journal = {J. Artif. Intell. Res.(JAIR)},
+ pages = {191--246},
+ title = {The Fast Downward Planning System.},
+ volume = {26},
+ year = {2006}}
+
+@inproceedings{miguel2001symmetry,
+ author = {Miguel, Ian},
+ booktitle = {{Proceedings of the CP'01 Workshop on Symmetry in Constraints}},
+ pages = {17--24},
+ title = {Symmetry-breaking in planning: Schematic constraints},
+ year = {2001}}
+
+@incollection{Walsh:07,
+ author = {Walsh, Toby},
+ booktitle = {Principles and Practice of Constraint Programming -- CP 2007},
+ doi = {10.1007/978-3-540-74970-7_67},
+ editor = {Bessi{\`e}re, Christian},
+ isbn = {978-3-540-74969-1},
+ language = {English},
+ pages = {880-887},
+ publisher = {Springer Berlin Heidelberg},
+ series = {Lecture Notes in Computer Science},
+ title = {Breaking Value Symmetry},
+ url = {http://dx.doi.org/10.1007/978-3-540-74970-7_67},
+ volume = {4741},
+ year = {2007},
+ Bdsk-Url-1 = {http://dx.doi.org/10.1007/978-3-540-74970-7_67}}
+
+@inproceedings{eugene1993permutation,
+ author = {Eugene, M},
+ booktitle = {Groups and Computation: Workshop on Groups and Computation, October 7-10, 1991},
+ organization = {American Mathematical Soc.},
+ pages = {139},
+ title = {Permutation groups and polynomial-time computation},
+ volume = {11},
+ year = {1993}}
+
+@inproceedings{Babai:1983:CLG:800061.808746,
+ acmid = {808746},
+ address = {New York, NY, USA},
+ author = {Babai, L\'{a}szl\'{o} and Luks, Eugene M.},
+ booktitle = {Proceedings of the Fifteenth Annual ACM Symposium on Theory of Computing},
+ doi = {10.1145/800061.808746},
+ isbn = {0-89791-099-0},
+ numpages = {13},
+ pages = {171--183},
+ publisher = {ACM},
+ series = {STOC '83},
+ title = {Canonical Labeling of Graphs},
+ url = {http://doi.acm.org/10.1145/800061.808746},
+ year = {1983},
+ Bdsk-Url-1 = {http://doi.acm.org/10.1145/800061.808746},
+ Bdsk-Url-2 = {https://doi.org/10.1145/800061.808746}}
+
+@inproceedings{clarke1998symmetry,
+ author = {Clarke, Edmund M and Emerson, E Allen and Jha, Somesh and Sistla, A Prasad},
+ booktitle = {Computer Aided Verification},
+ organization = {Springer},
+ pages = {147--158},
+ title = {Symmetry reductions in model checking},
+ year = {1998}}
+
+@article{bellman1958routing,
+ author = {Bellman, Richard},
+ journal = {Quarterly of applied mathematics},
+ pages = {87--90},
+ publisher = {JSTOR},
+ title = {On a routing problem},
+ year = {1958}}
+
+@article{dijkstra1959note,
+ author = {Dijkstra, Edsger W},
+ journal = {Numerische mathematik},
+ number = {1},
+ pages = {269--271},
+ publisher = {Springer},
+ title = {A note on two problems in connexion with graphs},
+ volume = {1},
+ year = {1959}}
+
+@article{fredman1987fibonacci,
+ author = {Fredman, Michael L and Tarjan, Robert Endre},
+ journal = {Journal of the ACM (JACM)},
+ number = {3},
+ pages = {596--615},
+ publisher = {ACM},
+ title = {Fibonacci heaps and their uses in improved network optimization algorithms},
+ volume = {34},
+ year = {1987}}
+
+@inproceedings{thorup2003integer,
+ author = {Thorup, Mikkel},
+ booktitle = {Proceedings of the thirty-fifth annual ACM symposium on Theory of computing},
+ organization = {ACM},
+ pages = {149--158},
+ title = {Integer priority queues with decrease key in constant time and the single source shortest paths problem},
+ year = {2003}}
+
+@article{dufourd2009intuitionistic,
+ author = {Dufourd, Jean-Fran{\c{c}}ois},
+ journal = {Journal of Automated Reasoning},
+ number = {1},
+ pages = {19--51},
+ publisher = {Springer},
+ title = {{An intuitionistic proof of a discrete form of the Jordan Curve Theorem formalized in Coq with combinatorial hypermaps}},
+ volume = {43},
+ year = {2009}}
+
+@article{bezem2008mechanization,
+ author = {Bezem, Marc and Hendriks, Dimitri},
+ journal = {Journal of Automated Reasoning},
+ number = {1},
+ pages = {61--85},
+ publisher = {Springer},
+ title = {{On the mechanization of the proof of Hessenberg's theorem in coherent logic}},
+ volume = {40},
+ year = {2008}}
+
+@article{mckinna1999some,
+ author = {McKinna, James and Pollack, Robert},
+ journal = {Journal of Automated Reasoning},
+ number = {3},
+ pages = {373--409},
+ publisher = {Springer},
+ title = {Some lambda calculus and type theory formalized},
+ volume = {23},
+ year = {1999}}
+
+@inproceedings{taylor1991fixed,
+ author = {Taylor, Paul},
+ booktitle = {Logic in Computer Science, 1991. LICS'91., Proceedings of Sixth Annual IEEE Symposium on},
+ organization = {IEEE},
+ pages = {152--160},
+ title = {The fixed point property in synthetic domain theory},
+ year = {1991}}
+
+@article{jaume1999full,
+ author = {Jaume, Mathieu},
+ journal = {Journal of Automated Reasoning},
+ number = {3},
+ pages = {347--371},
+ publisher = {Springer},
+ title = {A full formalization of SLD-resolution in the Calculus of Inductive Constructions},
+ volume = {23},
+ year = {1999}}
+
+@article{kamareddine2003formalizing,
+ author = {Kamareddine, Fairouz and Qiao, Haiyan},
+ journal = {Journal of Automated Reasoning},
+ number = {1},
+ pages = {59--98},
+ publisher = {Springer},
+ title = {Formalizing strong normalization proofs of explicit substitution calculi in ALF},
+ volume = {30},
+ year = {2003}}
+
+@article{manolios2005ordinal,
+ author = {Manolios, Panagiotis and Vroon, Daron},
+ journal = {Journal of Automated Reasoning},
+ number = {4},
+ pages = {387--423},
+ publisher = {Springer},
+ title = {Ordinal arithmetic: Algorithms and mechanization},
+ volume = {34},
+ year = {2005}}
+
+@article{maric2009formalization,
+ author = {Mari{\'c}, Filip},
+ journal = {Journal of Automated Reasoning},
+ number = {1},
+ publisher = {Springer},
+ title = {{Formalization and implementation of modern SAT solvers}},
+ volume = {43},
+ year = {2009}}
+
+@inproceedings{klein2009sel4L,
+ author = {Klein, Gerwin and Elphinstone, Kevin and Heiser, Gernot and Andronick, June and Cock, David and Derrin, Philip and Elkaduwe, Dhammika and Engelhardt, Kai and Kolanski, Rafal and Norrish, Michael and others},
+ booktitle = {Proceedings of the ACM SIGOPS 22nd symposium on Operating systems principles},
+ organization = {ACM},
+ pages = {207--220},
+ title = {{seL4: Formal verification of an OS kernel}},
+ year = {2009}}
+
+@inproceedings{klein2009sel4,
+ author = {Klein, Gerwin and others},
+ booktitle = {SOSP},
+ organization = {ACM},
+ pages = {207--220},
+ title = {{seL4: Formal verification of an OS kernel}},
+ year = {2009}}
+
+@book{gordon1993introduction,
+ author = {Gordon, Michael JC and Melham, Tom F},
+ publisher = {Cambridge University Press},
+ title = {Introduction to HOL: a theorem proving environment for higher order logic},
+ year = {1993}}
+
+@incollection{bauer2013tableaux,
+ author = {Bauer, Andreas and Baumgartner, Peter and Diller, Martin and Norrish, Michael},
+ booktitle = {Automated Reasoning with Analytic Tableaux and Related Methods},
+ pages = {28--43},
+ publisher = {Springer},
+ title = {Tableaux for verification of data-centric processes},
+ year = {2013}}
+
+@book{paulson1994isabelle,
+ author = {Paulson, Lawrence C},
+ publisher = {Springer},
+ title = {Isabelle: A generic theorem prover},
+ volume = {828},
+ year = {1994}}
+
+@book{bertot2004interactive,
+ author = {Bertot, Yves and Cast{\'e}ran, Pierre},
+ publisher = {springer},
+ title = {Interactive theorem proving and program development: Coq'Art: the calculus of inductive constructions},
+ year = {2004}}
+
+@article{gonthier2008formal,
+ author = {Gonthier, Georges},
+ journal = {Notices of the AMS},
+ number = {11},
+ pages = {1382--1393},
+ title = {Formal proof--the four-color theorem},
+ volume = {55},
+ year = {2008}}
+
+@incollection{hales2011revision,
+ author = {Hales, Thomas C and Harrison, John and McLaughlin, Sean and Nipkow, Tobias and Obua, Steven and Zumkeller, Roland},
+ booktitle = {The Kepler Conjecture},
+ pages = {341--376},
+ publisher = {Springer},
+ title = {{A revision of the proof of the Kepler conjecture}},
+ year = {2011}}
+
+@article{gamboa2009formalization,
+ author = {Gamboa, Ruben A},
+ journal = {Journal of Automated Reasoning},
+ number = {2},
+ pages = {139--172},
+ publisher = {Springer},
+ title = {A Formalization of Powerlist Algebra in ACL2},
+ volume = {43},
+ year = {2009}}
+
+@article{harrison2007formalizing,
+ author = {Harrison, John},
+ journal = {From Insight to Proof: Festschrift in Honour of Andrzej Trybulec. Studies in Logic, Grammar and Rhetoric},
+ number = {23},
+ pages = {151--165},
+ title = {Formalizing basic complex analysis},
+ volume = {10},
+ year = {2007}}
+
+@inproceedings{esparza2013fully,
+ author = {Esparza, Javier and Lammich, Peter and Neumann, Ren{\'e} and Nipkow, Tobias and Schimpf, Alexander and Smaus, Jan-Georg},
+ booktitle = {International Conference on Computer Aided Verification},
+ organization = {Springer},
+ pages = {463--478},
+ title = {{A fully verified executable LTL model checker}},
+ year = {2013}}
+
+@inproceedings{paulson2015formalisation,
+ author = {Paulson, Lawrence C},
+ booktitle = {International Conference on Automated Deduction},
+ organization = {Springer},
+ pages = {231--245},
+ title = {A formalisation of finite automata using hereditarily finite sets},
+ year = {2015}}
+
+@inproceedings{constable2000constructively,
+ author = {Constable, Robert L and Jackson, Paul B and Naumov, Pavel and Uribe, Juan C},
+ booktitle = {Proof, language, and interaction},
+ pages = {213--238},
+ title = {Constructively formalizing automata theory.},
+ year = {2000}}
+
+@inproceedings{doczkal2013constructive,
+ author = {Doczkal, Christian and Kaiser, Jan-Oliver and Smolka, Gert},
+ booktitle = {International Conference on Certified Programs and Proofs},
+ organization = {Springer},
+ pages = {82--97},
+ title = {A constructive theory of regular languages in Coq},
+ year = {2013}}
+
+@inproceedings{wu2011formalisation,
+ author = {Wu, Chunhan and Zhang, Xingyuan and Urban, Christian},
+ booktitle = {International Conference on Interactive Theorem Proving},
+ organization = {Springer},
+ pages = {341--356},
+ title = {{A formalisation of the Myhill-Nerode theorem based on regular expressions (proof pearl)}},
+ year = {2011}}
+
+@inproceedings{schimpf2009construction,
+ author = {Schimpf, Alexander and Merz, Stephan and Smaus, Jan-Georg},
+ booktitle = {International Conference on Theorem Proving in Higher Order Logics},
+ organization = {Springer},
+ pages = {424--439},
+ title = {{Construction of B{\"u}chi automata for LTL model checking verified in Isabelle/HOL}},
+ year = {2009}}
+
+@inproceedings{sprenger1998verified,
+ author = {Sprenger, Christoph},
+ booktitle = {International Conference on Tools and Algorithms for the Construction and Analysis of Systems},
+ organization = {Springer},
+ pages = {167--183},
+ title = {A verified model checker for the modal $\mu$-calculus in Coq},
+ year = {1998}}
+
+@inproceedings{nipkow2005proof,
+ author = {Nipkow, Tobias and Paulson, Lawrence C},
+ booktitle = {International Conference on Theorem Proving in Higher Order Logics},
+ organization = {Springer},
+ pages = {385--396},
+ title = {Proof pearl: Defining functions over finite sets},
+ year = {2005}}
+
+@article{sistla1985complexity,
+ author = {Sistla, A Prasad and Clarke, Edmund M},
+ journal = {Journal of the ACM (JACM)},
+ number = {3},
+ pages = {733--749},
+ publisher = {ACM},
+ title = {The complexity of propositional linear temporal logics},
+ volume = {32},
+ year = {1985}}
+
+@article{clarke1994model,
+ author = {Clarke, Edmund M and Grumberg, Orna and Long, David E},
+ journal = {ACM transactions on Programming Languages and Systems (TOPLAS)},
+ number = {5},
+ pages = {1512--1542},
+ publisher = {ACM},
+ title = {Model checking and abstraction},
+ volume = {16},
+ year = {1994}}
+
+@article{filiot2011antichains,
+ author = {Filiot, Emmanuel and Jin, Naiyong and Raskin, Jean-Fran{\c{c}}ois},
+ journal = {Formal Methods in System Design},
+ number = {3},
+ pages = {261--296},
+ publisher = {Springer},
+ title = {{Antichains and compositional algorithms for LTL synthesis}},
+ volume = {39},
+ year = {2011}}
+
+@inproceedings{abdulaziz2014mechanising,
+ author = {Abdulaziz, Mohammad and Gretton, Charles and Norrish, Michael},
+ booktitle = {{Workshop on Knowledge Engineering for Planning and Scheduling}},
+ title = {{Mechanising Theoretical Upper Bounds in Planning}},
+ year = {2014}}
+
+@inproceedings{abdulaziz2015exploiting,
+ author = {Abdulaziz, Mohammad and Norrish, Michael and Gretton, Charles},
+ booktitle = {{Proc. of the 24th International Joint Conference on Artificial Intelligence, IJCAI}},
+ pages = {25--31},
+ title = {{Exploiting symmetries by planning for a descriptive quotient}},
+ year = {2015}}
+
+@inproceedings{abdulaziz2016isabelle,
+ author = {Abdulaziz, Mohammad and Paulson, Lawrence C},
+ booktitle = {{International Conference on Interactive Theorem Proving}},
+ organization = {Springer},
+ pages = {3--19},
+ title = {{An Isabelle/HOL formalisation of Green's theorem}},
+ year = {2016}}
+
+@incollection{abdulaziz2015verified,
+ author = {Abdulaziz, Mohammad and Gretton, Charles and Norrish, Michael},
+ booktitle = {{Interactive Theorem Proving}},
+ pages = {1--16},
+ publisher = {Springer},
+ title = {{Verified Over-Approximation of the Diameter of Propositionally Factored Transition Systems}},
+ year = {2015}}
+
+@inproceedings{icaps2017,
+ author = {Abdulaziz, Mohammad and Gretton, Charles and Norrish, Michael},
+ booktitle = {International Conference on Automated Planning and Scheduling (ICAPS)},
+ organization = {AAAI},
+ title = {{A State Space Acyclicity Property for Exponentially Tighter Plan Length Bounds}},
+ year = {2017}}
+
+@article{DBLP:journals/jar/AbdulazizNG18,
+ author = {Mohammad Abdulaziz and Michael Norrish and Charles Gretton},
+ bibsource = {dblp computer science bibliography, https://dblp.org},
+ biburl = {https://dblp.org/rec/bib/journals/jar/AbdulazizNG18},
+ journal = {J. Autom. Reasoning},
+ number = {1-4},
+ pages = {485--520},
+ timestamp = {Sat, 02 Jun 2018 16:55:32 +0200},
+ title = {{Formally Verified Algorithms for Upper-Bounding State Space Diameters}},
+ volume = {61},
+ year = {2018}}
+
+@article{pardalos2004note,
+ author = {Pardalos, Panos M and Migdalas, Athanasios},
+ journal = {Applied mathematics letters},
+ number = {1},
+ pages = {13--15},
+ publisher = {Elsevier},
+ title = {A note on the complexity of longest path problems related to graph coloring},
+ volume = {17},
+ year = {2004}}
+
+@article{galperin1983succinct,
+ author = {Galperin, Hana and Wigderson, Avi},
+ journal = {Information and Control},
+ number = {3},
+ pages = {183--198},
+ publisher = {Elsevier},
+ title = {Succinct representations of graphs},
+ volume = {56},
+ year = {1983}}
+
+@inproceedings{feigenbaum1998complexity,
+ author = {Feigenbaum, Joan and Kannan, Sampath and Vardi, Moshe Y and Viswanathan, Mahesh},
+ booktitle = {Annual Symposium on Theoretical Aspects of Computer Science},
+ organization = {Springer},
+ pages = {216--226},
+ title = {Complexity of problems on graphs represented as OBDDs},
+ year = {1998}}
+
+@article{hemaspaandra2010complexity,
+ author = {Hemaspaandra, Edith and Hemaspaandra, Lane A and Tantau, Till and Watanabe, Osamu},
+ journal = {Theoretical Computer Science},
+ number = {4-5},
+ pages = {783--798},
+ publisher = {Elsevier},
+ title = {On the complexity of kings},
+ volume = {411},
+ year = {2010}}
+
+@inproceedings{lozano1989complexity,
+ author = {Lozano, Antonio and Balc{\'a}zar, Jos{\'e} L},
+ booktitle = {International Workshop on Graph-Theoretic Concepts in Computer Science},
+ organization = {Springer},
+ pages = {277--286},
+ title = {The complexity of graph problems for succinctly represented graphs},
+ year = {1989}}
+
+@article{papadimitriou1986note,
+ author = {Papadimitriou, Christos H and Yannakakis, Mihalis},
+ journal = {Information and Control},
+ number = {3},
+ pages = {181--185},
+ publisher = {Elsevier},
+ title = {A note on succinct representations of graphs},
+ volume = {71},
+ year = {1986}}
+
+@inproceedings{howey2004val,
+ author = {Howey, Richard and Long, Derek and Fox, Maria},
+ booktitle = {Tools with Artificial Intelligence, 2004},
+ title = {{VAL: Automatic plan validation, continuous effects and mixed initiative planning using PDDL}},
+ year = {2004}}
+
+@inproceedings{howey2004valL,
+ author = {Howey, Richard and Long, Derek and Fox, Maria},
+ booktitle = {Tools with Artificial Intelligence, 2004. ICTAI 2004. 16th IEEE International Conference on},
+ organization = {IEEE},
+ pages = {294--301},
+ title = {{VAL: Automatic plan validation, continuous effects and mixed initiative planning using PDDL}},
+ year = {2004}}
+
+@article{leroy2009formal,
+ author = {Leroy, Xavier},
+ journal = {Communications of the ACM},
+ number = {7},
+ pages = {107--115},
+ publisher = {ACM},
+ title = {Formal verification of a realistic compiler},
+ volume = {52},
+ year = {2009}}
+
+@article{fox2003pddl2,
+ author = {Fox, Maria and Long, Derek},
+ journal = {JAIR},
+ title = {{PDDL2.1: An extension to PDDL for expressing temporal planning domains}},
+ year = {2003}}
+
+@article{fox2003pddl2L,
+ author = {Fox, Maria and Long, Derek},
+ journal = {Journal of artificial intelligence research},
+ title = {{PDDL2.1: An extension to PDDL for expressing temporal planning domains}},
+ year = {2003}}
+
+@inproceedings{fox2005validating,
+ author = {Fox, Maria and Howey, Richard and Long, Derek},
+ booktitle = {AAAI},
+ pages = {1151--1156},
+ title = {Validating plans in the context of processes and exogenous events},
+ volume = {5},
+ year = {2005}}
+
+@inproceedings{brunner2016formal,
+ author = {Brunner, Julian and Lammich, Peter},
+ booktitle = {NASA Formal Methods Symposium},
+ organization = {Springer},
+ pages = {307--321},
+ title = {{Formal Verification of an Executable LTL Model Checker with Partial Order Reduction}},
+ year = {2016}}
+
+@article{holzmann1997model,
+ author = {Holzmann, Gerard J.},
+ journal = {IEEE Transactions on software engineering},
+ number = {5},
+ pages = {279--295},
+ publisher = {IEEE},
+ title = {The model checker SPIN},
+ volume = {23},
+ year = {1997}}
+
+@book{norell2007towards,
+ author = {Norell, Ulf},
+ publisher = {Chalmers University of Technology},
+ title = {Towards a practical programming language based on dependent type theory},
+ volume = {32},
+ year = {2007}}
+
+@article{coquand1988calculus,
+ author = {Coquand, Thierry and Huet, G{\'e}rard},
+ journal = {Information and computation},
+ number = {2-3},
+ pages = {95--120},
+ publisher = {Elsevier},
+ title = {The calculus of constructions},
+ volume = {76},
+ year = {1988}}
+
+@article{haftmann2007code,
+ author = {Haftmann, Florian and Nipkow, Tobias},
+ journal = {Theorem Proving in Higher Order Logics (TPHOLs 2007). Lecture Notes in Computer Science},
+ pages = {128--143},
+ title = {{A code generator framework for Isabelle/HOL}},
+ volume = {4732},
+ year = {2007}}
+
+@book{milner1997definition,
+ author = {Milner, Robin},
+ publisher = {MIT press},
+ title = {{The definition of standard ML: revised}},
+ year = {1997}}
+
+@article{thiebaux2005defense,
+ author = {Thi{\'e}baux, Sylvie and Hoffmann, J{\"o}rg and Nebel, Bernhard},
+ journal = {Artificial Intelligence},
+ number = {1-2},
+ pages = {38--69},
+ publisher = {Elsevier},
+ title = {{In defense of PDDL axioms}},
+ volume = {168},
+ year = {2005}}
+
+@article{eriksson2017unsolvability,
+ author = {Eriksson, Salom{\'e} and R{\"o}ger, Gabriele and Helmert, Malte},
+ title = {Unsolvability Certificates for Classical Planning},
+ year = {2017}}
+
+@article{backstrom1995complexity,
+ author = {B{\"a}ckstr{\"o}m, Christer and Nebel, Bernhard},
+ journal = {Computational Intelligence},
+ number = {4},
+ pages = {625--655},
+ publisher = {Wiley Online Library},
+ title = {Complexity results for SAS+ planning},
+ volume = {11},
+ year = {1995}}
+
+@article{jonsson1998state,
+ author = {Jonsson, Peter and B{\"a}ckstr{\"o}m, Christer},
+ journal = {Artificial Intelligence},
+ number = {1-2},
+ pages = {125--176},
+ publisher = {Elsevier},
+ title = {State-variable planning under structural restrictions: Algorithms and complexity},
+ volume = {100},
+ year = {1998}}
+
+@inproceedings{kumar2014hol,
+ author = {Kumar, Ramana and Arthan, Rob and Myreen, Magnus O and Owens, Scott},
+ booktitle = {ITP},
+ title = {{HOL with definitions: Semantics, soundness, and a verified implementation}},
+ year = {2014}}
+
+@inproceedings{kumar2014holL,
+ author = {Kumar, Ramana and Arthan, Rob and Myreen, Magnus O and Owens, Scott},
+ booktitle = {International Conference on Interactive Theorem Proving},
+ organization = {Springer},
+ pages = {308--324},
+ title = {HOL with definitions: Semantics, soundness, and a verified implementation},
+ year = {2014}}
+
+@inproceedings{blanchette2016verified,
+ author = {Blanchette, Jasmin Christian and Fleury, Mathias and Weidenbach, Christoph},
+ booktitle = {International Joint Conference on Automated Reasoning},
+ organization = {Springer},
+ pages = {25--44},
+ title = {{A verified SAT solver framework with learn, forget, restart, and incrementality}},
+ year = {2016}}
+
+@inproceedings{balyo2013relaxingL,
+ author = {Balyo, Toma},
+ booktitle = {Tools with Artificial Intelligence (ICTAI), 2013 IEEE 25th International Conference on},
+ organization = {IEEE},
+ pages = {865--871},
+ title = {Relaxing the relaxed exist-step parallel planning semantics},
+ year = {2013}}
+
+@inproceedings{balyo2013relaxing,
+ author = {Balyo, Toma},
+ booktitle = {Tools with Artificial Intelligence (ICTAI), 2013},
+ organization = {IEEE},
+ pages = {865--871},
+ title = {Relaxing the relaxed exist-step parallel planning semantics},
+ year = {2013}}
+
+@inproceedings{DBLP:conf/sat/Lammich17,
+ author = {Peter Lammich},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/sat/Lammich17},
+ booktitle = {Theory and Applications of Satisfiability Testing - {SAT} 2017 - 20th International Conference, Melbourne, VIC, Australia, August 28 - September 1, 2017, Proceedings},
+ crossref = {DBLP:conf/sat/2017},
+ doi = {10.1007/978-3-319-66263-3_29},
+ timestamp = {Tue, 15 Aug 2017 09:56:48 +0200},
+ title = {The {GRAT} Tool Chain - Efficient {(UN)SAT} Certificate Checking with Formal Correctness Guarantees},
+ url = {https://doi.org/10.1007/978-3-319-66263-3_29},
+ year = {2017},
+ Bdsk-Url-1 = {https://doi.org/10.1007/978-3-319-66263-3_29}}
+
+@inproceedings{DBLP:conf/cade/Lammich17,
+ author = {Peter Lammich},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/cade/Lammich17},
+ booktitle = {{CADE}},
+ doi = {10.1007/978-3-319-63046-5_15},
+ timestamp = {Wed, 12 Jul 2017 10:22:36 +0200},
+ title = {Efficient Verified {(UN)SAT} Certificate Checking},
+ url = {https://doi.org/10.1007/978-3-319-63046-5_15},
+ year = {2017},
+ Bdsk-Url-1 = {https://doi.org/10.1007/978-3-319-63046-5_15}}
+
+@inproceedings{DBLP:conf/cade/Lammich17L,
+ author = {Peter Lammich},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.uni-trier.de/rec/bib/conf/cade/Lammich17},
+ booktitle = {Automated Deduction - {CADE} 26 - 26th International Conference on Automated Deduction, Gothenburg, Sweden, August 6-11, 2017, Proceedings},
+ doi = {10.1007/978-3-319-63046-5_15},
+ pages = {237--254},
+ timestamp = {Wed, 12 Jul 2017 10:22:36 +0200},
+ title = {Efficient Verified {(UN)SAT} Certificate Checking},
+ url = {https://doi.org/10.1007/978-3-319-63046-5_15},
+ year = {2017},
+ Bdsk-Url-1 = {https://doi.org/10.1007/978-3-319-63046-5_15}}
+
+@inproceedings{lochbihler2013light,
+ author = {Lochbihler, Andreas},
+ booktitle = {International Conference on Interactive Theorem Proving},
+ organization = {Springer},
+ pages = {116--132},
+ title = {{Light-weight containers for Isabelle: efficient, extensible, nestable}},
+ year = {2013}}
+
+@article{kovacscomplete,
+ author = {Kovacs, Daniel L},
+ journal = {IPC-2011},
+ title = {{BNF definition of PDDL 3.1}},
+ year = {2011}}
+
+@techreport{milner1972logic,
+ author = {Milner, Robin},
+ institution = {Stanford University},
+ title = {Logic for computable functions description of a machine implementation},
+ year = {1972}}
+
+@techreport{green1969application,
+ author = {Green, Cordell},
+ institution = {SRI},
+ title = {Application of theorem proving to problem solving},
+ year = {1969}}
+
+@inproceedings{lifschitz1987semantics,
+ author = {Lifschitz, Vladimir},
+ booktitle = {Reasoning about Actions and Plans: Proceedings of the 1986 Workshop},
+ pages = {1--9},
+ title = {On the semantics of STRIPS},
+ year = {1987}}
+
+@article{pednault1989adl,
+ author = {Pednault, Edwin PD},
+ journal = {Kr},
+ pages = {324--332},
+ title = {ADL: Exploring the Middle Ground Between STRIPS and the Situation Calculus.},
+ volume = {89},
+ year = {1989}}
+
+@inproceedings{paulson2010three,
+ author = {Paulson, Lawrence C and Blanchette, Jasmin Christian},
+ booktitle = {PAAR@ IJCAR},
+ pages = {1--10},
+ title = {Three Years of Experience with Sledgehammer, a Practical Link between Automatic and Interactive Theorem Provers.},
+ year = {2010}}
+
+@inproceedings{zhan2016auto2,
+ author = {Zhan, Bohua},
+ booktitle = {International Conference on Interactive Theorem Proving},
+ organization = {Springer},
+ pages = {441--456},
+ title = {AUTO2, a saturation-based heuristic prover for higher-order logic},
+ year = {2016}}
+
+@article{DBLP:journals/afp/MichaelisN17,
+ author = {Julius Michaelis and Tobias Nipkow},
+ bibsource = {dblp computer science bibliography, http://dblp.org},
+ biburl = {http://dblp.org/rec/bib/journals/afp/MichaelisN17},
+ journal = {Archive of Formal Proofs},
+ timestamp = {Fri, 30 Jun 2017 19:26:27 +0200},
+ title = {Propositional Proof Systems},
+ url = {https://www.isa-afp.org/entries/Propositional_Proof_Systems.shtml},
+ volume = {2017},
+ year = {2017},
+ Bdsk-Url-1 = {https://www.isa-afp.org/entries/Propositional_Proof_Systems.shtml}}
+
+@inproceedings{MichaelisN-TYPES17,
+ author = {Julius Michaelis and Tobias Nipkow},
+ booktitle = {23rd Int.\ Conf.\ Types for Proofs and Programs (TYPES 2017)},
+ editor = {A. Abel and F. Nordvall Forsberg and A. Kaposi},
+ pages = {6:1--6:16},
+ publisher = {Schloss Dagstuhl - Leibniz-Zentrum fuer Informatik},
+ series = {LIPIcs},
+ title = {Formalized Proof Systems for Propositional Logic},
+ volume = {104},
+ year = {2018}}
+
+@inproceedings{haslum2003domain,
+ author = {Haslum, Patrik and Scholz, Ulrich},
+ booktitle = {ICAPS Workshop on PDDL},
+ title = {Domain knowledge in planning: Representation and use},
+ year = {2003}}
+
+@article{haslum2011computing,
+ author = {Haslum, Patrik and et al.},
+ publisher = {AAAI Press},
+ title = {Computing genome edit distances using domain-independent planning},
+ year = {2011}}
+
+@techreport{mccarthy1985formalization,
+ author = {McCarthy, John},
+ institution = {Citeseer},
+ title = {{Formalization of STRIPS in situation calculus}},
+ year = {1985}}
+
+@techreport{norrish1998c,
+ author = {Norrish, Michael},
+ institution = {University of Cambridge, Computer Laboratory},
+ title = {{C formalised in HOL}},
+ year = {1998}}
+
+@inproceedings{ictai2018,
+ author = {Abdulaziz, Mohammad and Lammich, Peter},
+ booktitle = {International Conference on Tools in Artificial Intelligence (ICTAI)},
+ organization = {IEEE},
+ title = {{A Formally Verified Validator for Classical Planning Problems and Solutions}},
+ year = {2018}}
+
+@article{Propositional_Proof_Systems-AFP,
+ author = {Julius Michaelis and Tobias Nipkow},
+ issn = {2150-914x},
+ journal = {Archive of Formal Proofs},
+ month = jun,
+ note = {\url{http://isa-afp.org/entries/Propositional_Proof_Systems.html}, Formal proof development},
+ title = {Propositional Proof Systems},
+ year = 2017}
+
+@article{DBLP:journals/ai/RintanenHN06,
+ author = {Jussi Rintanen and Keijo Heljanko and Ilkka Niemel{\"{a}}},
+ bibsource = {dblp computer science bibliography, https://dblp.org},
+ biburl = {https://dblp.org/rec/journals/ai/RintanenHN06.bib},
+ doi = {10.1016/j.artint.2006.08.002},
+ journal = {Artif. Intell.},
+ number = {12-13},
+ pages = {1031--1080},
+ timestamp = {Mon, 05 Jun 2017 12:38:26 +0200},
+ title = {Planning as satisfiability: parallel plans and algorithms for plan search},
+ url = {https://doi.org/10.1016/j.artint.2006.08.002},
+ volume = {170},
+ year = {2006},
+ Bdsk-Url-1 = {https://doi.org/10.1016/j.artint.2006.08.002}}
+
+@misc{abdulaziz2020formally,
+ archiveprefix = {arXiv},
+ author = {Mohammad Abdulaziz and Friedrich Kurz},
+ eprint = {2010.14648},
+ primaryclass = {cs.AI},
+ title = {Formally Verified SAT-Based AI Planning},
+ year = {2020}}
diff --git a/thys/Verified_SAT_Based_AI_Planning/document/root.tex b/thys/Verified_SAT_Based_AI_Planning/document/root.tex
new file mode 100644
--- /dev/null
+++ b/thys/Verified_SAT_Based_AI_Planning/document/root.tex
@@ -0,0 +1,76 @@
+\documentclass[11pt,a4paper]{article}
+\usepackage{amsmath, amssymb}
+\usepackage{isabelle,isabellesym}
+\usepackage{verbatim}
+% further packages required for unusual symbols (see also
+% isabellesym.sty), use only when needed
+
+%\usepackage{amssymb}
+ %for \<leadsto>, \<box>, \<diamond>, \<sqsupset>, \<mho>, \<Join>,
+ %\<lhd>, \<lesssim>, \<greatersim>, \<lessapprox>, \<greaterapprox>,
+ %\<triangleq>, \<yen>, \<lozenge>
+
+%\usepackage{eurosym}
+ %for \<euro>
+
+%\usepackage[only,bigsqcap]{stmaryrd}
+ %for \<Sqinter>
+
+%\usepackage{eufrak}
+ %for \<AA> ... \<ZZ>, \<aa> ... \<zz> (also included in amssymb)
+
+%\usepackage{textcomp}
+ %for \<onequarter>, \<onehalf>, \<threequarters>, \<degree>, \<cent>,
+ %\<currency>
+
+\usepackage{wasysym}
+
+% 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{Verified SAT-Based AI Planning}
+\author{Mohammad Abdulaziz and Friedrich Kurz\footnote{Author names are alphabetically ordered.}}
+
+% \subtitle{Proof Document}
+% \author{M. Abdulaziz \and P. Lammich}
+\date{}
+
+\maketitle
+
+We present an executable formally verified SAT encoding of classical AI planning that is based on the encodings by Kautz and Selman~\cite{kautz:selman:92} and the one by Rintanen et al.~\cite{DBLP:journals/ai/RintanenHN06}.
+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~\cite{verifiedSATPlan}.
+
+\tableofcontents
+
+\clearpage
+
+
+% sane default for proof documents
+\parindent 0pt\parskip 0.5ex
+
+\newcommand{\isaname}[1]{}
+
+% generated text of all theories
+\input{session}
+
+\bibliographystyle{abbrv}
+\bibliography{root}
+
+\end{document}
+
+%%% Local Variables:
+%%% mode: latex
+%%% TeX-master: t
+%%% End:
diff --git a/web/entries/AI_Planning_Languages_Semantics.html b/web/entries/AI_Planning_Languages_Semantics.html
new file mode 100644
--- /dev/null
+++ b/web/entries/AI_Planning_Languages_Semantics.html
@@ -0,0 +1,196 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>AI Planning Languages Semantics - Archive of Formal Proofs
+</title>
+<link rel="stylesheet" type="text/css" href="../front.css">
+<link rel="icon" href="../images/favicon.ico" type="image/icon">
+<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
+<!-- MathJax for LaTeX support in abstracts -->
+<script>
+MathJax = {
+ tex: {
+ inlineMath: [['$', '$'], ['\\(', '\\)']]
+ },
+ processEscapes: true,
+ svg: {
+ fontCache: 'global'
+ }
+};
+</script>
+<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
+</head>
+
+<body class="mathjax_ignore">
+
+<table width="100%">
+<tbody>
+<tr>
+
+<!-- Navigation -->
+<td width="20%" align="center" valign="top">
+ <p>&nbsp;</p>
+ <a href="https://www.isa-afp.org/">
+ <img src="../images/isabelle.png" width="100" height="88" border=0>
+ </a>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+ <table class="nav" width="80%">
+ <tr>
+ <td class="nav" width="100%"><a href="../index.html">Home</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../about.html">About</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../submitting.html">Submission</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../updating.html">Updating Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../using.html">Using Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../search.html">Search</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../statistics.html">Statistics</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../topics.html">Index</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../download.html">Download</a></td>
+ </tr>
+ </table>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+</td>
+
+
+<!-- Content -->
+<td width="80%" valign="top">
+<div align="center">
+ <p>&nbsp;</p>
+ <h1> <font class="first">A</font>I
+
+ <font class="first">P</font>lanning
+
+ <font class="first">L</font>anguages
+
+ <font class="first">S</font>emantics
+
+</h1>
+ <p>&nbsp;</p>
+
+<table width="80%" class="data">
+<tbody>
+<tr>
+ <td class="datahead" width="20%">Title:</td>
+ <td class="data" width="80%">AI Planning Languages Semantics</td>
+</tr>
+
+<tr>
+ <td class="datahead">
+ Authors:
+ </td>
+ <td class="data">
+ <a href="http://home.in.tum.de/~mansour/">Mohammad Abdulaziz</a> and
+ Peter Lammich
+ </td>
+</tr>
+
+
+
+<tr>
+ <td class="datahead">Submission date:</td>
+ <td class="data">2020-10-29</td>
+</tr>
+
+<tr>
+ <td class="datahead" valign="top">Abstract:</td>
+ <td class="abstract mathjax_process">
+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.</td>
+</tr>
+
+
+<tr>
+ <td class="datahead" valign="top">BibTeX:</td>
+ <td class="formatted">
+ <pre>@article{AI_Planning_Languages_Semantics-AFP,
+ author = {Mohammad Abdulaziz and Peter Lammich},
+ title = {AI Planning Languages Semantics},
+ journal = {Archive of Formal Proofs},
+ month = oct,
+ year = 2020,
+ note = {\url{http://isa-afp.org/entries/AI_Planning_Languages_Semantics.html},
+ Formal proof development},
+ ISSN = {2150-914x},
+}</pre>
+ </td>
+</tr>
+
+ <tr><td class="datahead">License:</td>
+ <td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
+
+
+ <tr><td class="datahead">Depends on:</td>
+ <td class="data"><a href="Certification_Monads.html">Certification_Monads</a>, <a href="Containers.html">Containers</a>, <a href="Propositional_Proof_Systems.html">Propositional_Proof_Systems</a>, <a href="Show.html">Show</a> </td></tr>
+
+ <tr><td class="datahead">Used by:</td>
+ <td class="data"><a href="Verified_SAT_Based_AI_Planning.html">Verified_SAT_Based_AI_Planning</a> </td></tr>
+
+
+
+ </tbody>
+</table>
+
+<p></p>
+
+<table class="links">
+ <tbody>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/AI_Planning_Languages_Semantics/outline.pdf">Proof outline</a><br>
+ <a href="../browser_info/current/AFP/AI_Planning_Languages_Semantics/document.pdf">Proof document</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/AI_Planning_Languages_Semantics/index.html">Browse theories</a>
+ </td></tr>
+ <tr>
+ <td class="links">
+ <a href="../release/afp-AI_Planning_Languages_Semantics-current.tar.gz">Download this entry</a>
+ </td>
+ </tr>
+
+
+ <tr><td class="links">Older releases:
+ None
+ </td></tr>
+
+ </tbody>
+</table>
+
+</div>
+</td>
+
+</tr>
+</tbody>
+</table>
+
+<script src="../jquery.min.js"></script>
+<script src="../script.js"></script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/web/entries/Abstract_Completeness.html b/web/entries/Abstract_Completeness.html
--- a/web/entries/Abstract_Completeness.html
+++ b/web/entries/Abstract_Completeness.html
@@ -1,227 +1,227 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Abstract Completeness - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">A</font>bstract
<font class="first">C</font>ompleteness
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Abstract Completeness</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Jasmin Christian Blanchette (j /dot/ c /dot/ blanchette /at/ vu /dot/ nl),
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk) and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a> and
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2014-04-16</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">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].</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Abstract_Completeness-AFP,
author = {Jasmin Christian Blanchette and Andrei Popescu and Dmitriy Traytel},
title = {Abstract Completeness},
journal = {Archive of Formal Proofs},
month = apr,
year = 2014,
note = {\url{http://isa-afp.org/entries/Abstract_Completeness.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Collections.html">Collections</a> </td></tr>
<tr><td class="datahead">Used by:</td>
<td class="data"><a href="Abstract_Soundness.html">Abstract_Soundness</a>, <a href="Incredible_Proof_Machine.html">Incredible_Proof_Machine</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Abstract_Completeness/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Abstract_Completeness/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Abstract_Completeness/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Abstract_Completeness-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Abstract_Completeness-2019-06-11.tar.gz">
afp-Abstract_Completeness-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Abstract_Completeness-2018-08-16.tar.gz">
afp-Abstract_Completeness-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Abstract_Completeness-2017-10-10.tar.gz">
afp-Abstract_Completeness-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Abstract_Completeness-2016-12-17.tar.gz">
afp-Abstract_Completeness-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Abstract_Completeness-2016-02-22.tar.gz">
afp-Abstract_Completeness-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Abstract_Completeness-2015-05-27.tar.gz">
afp-Abstract_Completeness-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Abstract_Completeness-2014-08-28.tar.gz">
afp-Abstract_Completeness-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-Abstract_Completeness-2014-04-16.tar.gz">
afp-Abstract_Completeness-2014-04-16.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Abstract_Soundness.html b/web/entries/Abstract_Soundness.html
--- a/web/entries/Abstract_Soundness.html
+++ b/web/entries/Abstract_Soundness.html
@@ -1,212 +1,212 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Abstract Soundness - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">A</font>bstract
<font class="first">S</font>oundness
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Abstract Soundness</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Jasmin Christian Blanchette (j /dot/ c /dot/ blanchette /at/ vu /dot/ nl),
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk) and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a> and
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2017-02-10</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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 <em>Journal of Automated
Reasoning</em>. The abstract proof can be instantiated for
various formalisms, including first-order logic with inductive
predicates.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Abstract_Soundness-AFP,
author = {Jasmin Christian Blanchette and Andrei Popescu and Dmitriy Traytel},
title = {Abstract Soundness},
journal = {Archive of Formal Proofs},
month = feb,
year = 2017,
note = {\url{http://isa-afp.org/entries/Abstract_Soundness.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Abstract_Completeness.html">Abstract_Completeness</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Abstract_Soundness/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Abstract_Soundness/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Abstract_Soundness/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Abstract_Soundness-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Abstract_Soundness-2019-06-11.tar.gz">
afp-Abstract_Soundness-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Abstract_Soundness-2018-08-16.tar.gz">
afp-Abstract_Soundness-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Abstract_Soundness-2017-10-10.tar.gz">
afp-Abstract_Soundness-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Abstract_Soundness-2017-02-13.tar.gz">
afp-Abstract_Soundness-2017-02-13.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/BNF_Operations.html b/web/entries/BNF_Operations.html
--- a/web/entries/BNF_Operations.html
+++ b/web/entries/BNF_Operations.html
@@ -1,208 +1,208 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Operations on Bounded Natural Functors - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">O</font>perations
on
<font class="first">B</font>ounded
<font class="first">N</font>atural
<font class="first">F</font>unctors
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Operations on Bounded Natural Functors</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Jasmin Christian Blanchette (j /dot/ c /dot/ blanchette /at/ vu /dot/ nl),
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk) and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a> and
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2017-12-19</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{BNF_Operations-AFP,
author = {Jasmin Christian Blanchette and Andrei Popescu and Dmitriy Traytel},
title = {Operations on Bounded Natural Functors},
journal = {Archive of Formal Proofs},
month = dec,
year = 2017,
note = {\url{http://isa-afp.org/entries/BNF_Operations.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/BNF_Operations/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/BNF_Operations/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/BNF_Operations/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-BNF_Operations-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-BNF_Operations-2019-06-11.tar.gz">
afp-BNF_Operations-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-BNF_Operations-2018-08-16.tar.gz">
afp-BNF_Operations-2018-08-16.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Binding_Syntax_Theory.html b/web/entries/Binding_Syntax_Theory.html
--- a/web/entries/Binding_Syntax_Theory.html
+++ b/web/entries/Binding_Syntax_Theory.html
@@ -1,211 +1,211 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A General Theory of Syntax with Bindings - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">A</font>
<font class="first">G</font>eneral
<font class="first">T</font>heory
of
<font class="first">S</font>yntax
with
<font class="first">B</font>indings
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">A General Theory of Syntax with Bindings</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Lorenzo Gheri (lor /dot/ gheri /at/ gmail /dot/ com) and
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk)
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2019-04-06</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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”.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Binding_Syntax_Theory-AFP,
author = {Lorenzo Gheri and Andrei Popescu},
title = {A General Theory of Syntax with Bindings},
journal = {Archive of Formal Proofs},
month = apr,
year = 2019,
note = {\url{http://isa-afp.org/entries/Binding_Syntax_Theory.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Binding_Syntax_Theory/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Binding_Syntax_Theory/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Binding_Syntax_Theory/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Binding_Syntax_Theory-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Binding_Syntax_Theory-2019-06-11.tar.gz">
afp-Binding_Syntax_Theory-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Binding_Syntax_Theory-2019-04-08.tar.gz">
afp-Binding_Syntax_Theory-2019-04-08.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Bounded_Deducibility_Security.html b/web/entries/Bounded_Deducibility_Security.html
--- a/web/entries/Bounded_Deducibility_Security.html
+++ b/web/entries/Bounded_Deducibility_Security.html
@@ -1,228 +1,228 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bounded-Deducibility Security - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">B</font>ounded-Deducibility
<font class="first">S</font>ecurity
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Bounded-Deducibility Security</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk) and
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a> and
Peter Lammich
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2014-04-22</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">This is a formalization of bounded-deducibility security (BD
security), a flexible notion of information-flow security applicable
to arbitrary input-output automata. It generalizes Sutherland's
classic notion of nondeducibility by factoring in declassification
bounds and trigger, whereas nondeducibility states that, in a
system, information cannot flow between specified sources and sinks,
BD security indicates upper bounds for the flow and triggers under
which these upper bounds are no longer guaranteed.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Bounded_Deducibility_Security-AFP,
author = {Andrei Popescu and Peter Lammich},
title = {Bounded-Deducibility Security},
journal = {Archive of Formal Proofs},
month = apr,
year = 2014,
note = {\url{http://isa-afp.org/entries/Bounded_Deducibility_Security.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Bounded_Deducibility_Security/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Bounded_Deducibility_Security/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Bounded_Deducibility_Security/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Bounded_Deducibility_Security-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Bounded_Deducibility_Security-2019-06-11.tar.gz">
afp-Bounded_Deducibility_Security-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Bounded_Deducibility_Security-2018-08-16.tar.gz">
afp-Bounded_Deducibility_Security-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Bounded_Deducibility_Security-2017-10-10.tar.gz">
afp-Bounded_Deducibility_Security-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Bounded_Deducibility_Security-2016-12-17.tar.gz">
afp-Bounded_Deducibility_Security-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Bounded_Deducibility_Security-2016-02-22.tar.gz">
afp-Bounded_Deducibility_Security-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Bounded_Deducibility_Security-2015-05-27.tar.gz">
afp-Bounded_Deducibility_Security-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Bounded_Deducibility_Security-2014-08-28.tar.gz">
afp-Bounded_Deducibility_Security-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-Bounded_Deducibility_Security-2014-04-24.tar.gz">
afp-Bounded_Deducibility_Security-2014-04-24.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Certification_Monads.html b/web/entries/Certification_Monads.html
--- a/web/entries/Certification_Monads.html
+++ b/web/entries/Certification_Monads.html
@@ -1,220 +1,220 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Certification Monads - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">C</font>ertification
<font class="first">M</font>onads
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Certification Monads</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Christian Sternagel (c /dot/ sternagel /at/ gmail /dot/ com) and
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2014-10-03</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">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.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Certification_Monads-AFP,
author = {Christian Sternagel and René Thiemann},
title = {Certification Monads},
journal = {Archive of Formal Proofs},
month = oct,
year = 2014,
note = {\url{http://isa-afp.org/entries/Certification_Monads.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Partial_Function_MR.html">Partial_Function_MR</a>, <a href="Show.html">Show</a> </td></tr>
<tr><td class="datahead">Used by:</td>
- <td class="data"><a href="WOOT_Strong_Eventual_Consistency.html">WOOT_Strong_Eventual_Consistency</a>, <a href="XML.html">XML</a> </td></tr>
+ <td class="data"><a href="AI_Planning_Languages_Semantics.html">AI_Planning_Languages_Semantics</a>, <a href="WOOT_Strong_Eventual_Consistency.html">WOOT_Strong_Eventual_Consistency</a>, <a href="XML.html">XML</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Certification_Monads/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Certification_Monads/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Certification_Monads/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Certification_Monads-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Certification_Monads-2019-06-11.tar.gz">
afp-Certification_Monads-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Certification_Monads-2018-08-16.tar.gz">
afp-Certification_Monads-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Certification_Monads-2017-10-10.tar.gz">
afp-Certification_Monads-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Certification_Monads-2016-12-17.tar.gz">
afp-Certification_Monads-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Certification_Monads-2016-02-22.tar.gz">
afp-Certification_Monads-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Certification_Monads-2015-05-27.tar.gz">
afp-Certification_Monads-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Certification_Monads-2014-10-08.tar.gz">
afp-Certification_Monads-2014-10-08.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Chandy_Lamport.html b/web/entries/Chandy_Lamport.html
--- a/web/entries/Chandy_Lamport.html
+++ b/web/entries/Chandy_Lamport.html
@@ -1,201 +1,201 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A Formal Proof of The Chandy--Lamport Distributed Snapshot Algorithm - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">A</font>
<font class="first">F</font>ormal
<font class="first">P</font>roof
of
<font class="first">T</font>he
<font class="first">C</font>handy--Lamport
<font class="first">D</font>istributed
<font class="first">S</font>napshot
<font class="first">A</font>lgorithm
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">A Formal Proof of The Chandy--Lamport Distributed Snapshot Algorithm</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Ben Fiedler (ben /dot/ fiedler /at/ inf /dot/ ethz /dot/ ch) and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2020-07-21</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Chandy_Lamport-AFP,
author = {Ben Fiedler and Dmitriy Traytel},
title = {A Formal Proof of The Chandy--Lamport Distributed Snapshot Algorithm},
journal = {Archive of Formal Proofs},
month = jul,
year = 2020,
note = {\url{http://isa-afp.org/entries/Chandy_Lamport.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Ordered_Resolution_Prover.html">Ordered_Resolution_Prover</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Chandy_Lamport/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Chandy_Lamport/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Chandy_Lamport/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Chandy_Lamport-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
None
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Coinductive_Languages.html b/web/entries/Coinductive_Languages.html
--- a/web/entries/Coinductive_Languages.html
+++ b/web/entries/Coinductive_Languages.html
@@ -1,251 +1,251 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A Codatatype of Formal Languages - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">A</font>
<font class="first">C</font>odatatype
of
<font class="first">F</font>ormal
<font class="first">L</font>anguages
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">A Codatatype of Formal Languages</td>
</tr>
<tr>
<td class="datahead">
Author:
</td>
<td class="data">
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2013-11-15</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process"><p>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.</p>
<p>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.</p>
<p>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.</p></td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Coinductive_Languages-AFP,
author = {Dmitriy Traytel},
title = {A Codatatype of Formal Languages},
journal = {Archive of Formal Proofs},
month = nov,
year = 2013,
note = {\url{http://isa-afp.org/entries/Coinductive_Languages.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Regular-Sets.html">Regular-Sets</a> </td></tr>
<tr><td class="datahead">Used by:</td>
<td class="data"><a href="Formula_Derivatives.html">Formula_Derivatives</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Coinductive_Languages/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Coinductive_Languages/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Coinductive_Languages/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Coinductive_Languages-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Coinductive_Languages-2019-06-11.tar.gz">
afp-Coinductive_Languages-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Coinductive_Languages-2018-08-16.tar.gz">
afp-Coinductive_Languages-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Coinductive_Languages-2017-10-10.tar.gz">
afp-Coinductive_Languages-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Coinductive_Languages-2016-12-17.tar.gz">
afp-Coinductive_Languages-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Coinductive_Languages-2016-02-22.tar.gz">
afp-Coinductive_Languages-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Coinductive_Languages-2015-05-27.tar.gz">
afp-Coinductive_Languages-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Coinductive_Languages-2014-08-28.tar.gz">
afp-Coinductive_Languages-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-Coinductive_Languages-2013-12-11.tar.gz">
afp-Coinductive_Languages-2013-12-11.tar.gz
</a>
</li>
<li>Isabelle 2013-1:
<a href="../release/afp-Coinductive_Languages-2013-11-17.tar.gz">
afp-Coinductive_Languages-2013-11-17.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Containers.html b/web/entries/Containers.html
--- a/web/entries/Containers.html
+++ b/web/entries/Containers.html
@@ -1,258 +1,258 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Light-weight Containers - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">L</font>ight-weight
<font class="first">C</font>ontainers
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Light-weight Containers</td>
</tr>
<tr>
<td class="datahead">
Author:
</td>
<td class="data">
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="datahead">
Contributor:
</td>
<td class="data">
René Thiemann (rene /dot/ thiemann /at/ uibk /dot/ ac /dot/ at)
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2013-04-15</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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.
<p>
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.</td>
</tr>
<tr>
<td class="datahead" valign="top">Change history:</td>
<td class="abstract">[2013-07-11]: add pretty printing for sets (revision 7f3f52c5f5fa)<br>
[2013-09-20]:
provide generators for canonical type class instantiations
(revision 159f4401f4a8 by René Thiemann)<br>
[2014-07-08]: add support for going from partial functions to mappings (revision 7a6fc957e8ed)<br>
[2018-03-05]: add two application examples: depth-first search and 2SAT (revision e5e1a1da2411)</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Containers-AFP,
author = {Andreas Lochbihler},
title = {Light-weight Containers},
journal = {Archive of Formal Proofs},
month = apr,
year = 2013,
note = {\url{http://isa-afp.org/entries/Containers.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Automatic_Refinement.html">Automatic_Refinement</a>, <a href="Collections.html">Collections</a>, <a href="Deriving.html">Deriving</a>, <a href="Finger-Trees.html">Finger-Trees</a>, <a href="Regular-Sets.html">Regular-Sets</a> </td></tr>
<tr><td class="datahead">Used by:</td>
- <td class="data"><a href="MFOTL_Monitor.html">MFOTL_Monitor</a> </td></tr>
+ <td class="data"><a href="AI_Planning_Languages_Semantics.html">AI_Planning_Languages_Semantics</a>, <a href="MFOTL_Monitor.html">MFOTL_Monitor</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Containers/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Containers/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Containers/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Containers-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Containers-2019-06-11.tar.gz">
afp-Containers-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Containers-2018-08-16.tar.gz">
afp-Containers-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Containers-2017-10-10.tar.gz">
afp-Containers-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Containers-2016-12-17.tar.gz">
afp-Containers-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Containers-2016-02-22.tar.gz">
afp-Containers-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Containers-2015-05-27.tar.gz">
afp-Containers-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Containers-2014-08-28.tar.gz">
afp-Containers-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-Containers-2013-12-11.tar.gz">
afp-Containers-2013-12-11.tar.gz
</a>
</li>
<li>Isabelle 2013-1:
<a href="../release/afp-Containers-2013-11-17.tar.gz">
afp-Containers-2013-11-17.tar.gz
</a>
</li>
<li>Isabelle 2013:
<a href="../release/afp-Containers-2013-04-23.tar.gz">
afp-Containers-2013-04-23.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Core_SC_DOM.html b/web/entries/Core_SC_DOM.html
new file mode 100644
--- /dev/null
+++ b/web/entries/Core_SC_DOM.html
@@ -0,0 +1,200 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The Safely Composable DOM - Archive of Formal Proofs
+</title>
+<link rel="stylesheet" type="text/css" href="../front.css">
+<link rel="icon" href="../images/favicon.ico" type="image/icon">
+<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
+<!-- MathJax for LaTeX support in abstracts -->
+<script>
+MathJax = {
+ tex: {
+ inlineMath: [['$', '$'], ['\\(', '\\)']]
+ },
+ processEscapes: true,
+ svg: {
+ fontCache: 'global'
+ }
+};
+</script>
+<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
+</head>
+
+<body class="mathjax_ignore">
+
+<table width="100%">
+<tbody>
+<tr>
+
+<!-- Navigation -->
+<td width="20%" align="center" valign="top">
+ <p>&nbsp;</p>
+ <a href="https://www.isa-afp.org/">
+ <img src="../images/isabelle.png" width="100" height="88" border=0>
+ </a>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+ <table class="nav" width="80%">
+ <tr>
+ <td class="nav" width="100%"><a href="../index.html">Home</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../about.html">About</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../submitting.html">Submission</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../updating.html">Updating Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../using.html">Using Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../search.html">Search</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../statistics.html">Statistics</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../topics.html">Index</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../download.html">Download</a></td>
+ </tr>
+ </table>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+</td>
+
+
+<!-- Content -->
+<td width="80%" valign="top">
+<div align="center">
+ <p>&nbsp;</p>
+ <h1> <font class="first">T</font>he
+
+ <font class="first">S</font>afely
+
+ <font class="first">C</font>omposable
+
+ <font class="first">D</font>OM
+
+</h1>
+ <p>&nbsp;</p>
+
+<table width="80%" class="data">
+<tbody>
+<tr>
+ <td class="datahead" width="20%">Title:</td>
+ <td class="data" width="80%">The Safely Composable DOM</td>
+</tr>
+
+<tr>
+ <td class="datahead">
+ Authors:
+ </td>
+ <td class="data">
+ Achim D. Brucker (a /dot/ brucker /at/ exeter /dot/ ac /dot/ uk) and
+ <a href="http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.Herzberg">Michael Herzberg</a>
+ </td>
+</tr>
+
+
+
+<tr>
+ <td class="datahead">Submission date:</td>
+ <td class="data">2020-09-28</td>
+</tr>
+
+<tr>
+ <td class="datahead" valign="top">Abstract:</td>
+ <td class="abstract mathjax_process">
+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.</td>
+</tr>
+
+
+<tr>
+ <td class="datahead" valign="top">BibTeX:</td>
+ <td class="formatted">
+ <pre>@article{Core_SC_DOM-AFP,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {The Safely Composable DOM},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ note = {\url{http://isa-afp.org/entries/Core_SC_DOM.html},
+ Formal proof development},
+ ISSN = {2150-914x},
+}</pre>
+ </td>
+</tr>
+
+ <tr><td class="datahead">License:</td>
+ <td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
+
+
+
+ <tr><td class="datahead">Used by:</td>
+ <td class="data"><a href="Shadow_SC_DOM.html">Shadow_SC_DOM</a> </td></tr>
+
+
+
+ </tbody>
+</table>
+
+<p></p>
+
+<table class="links">
+ <tbody>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/Core_SC_DOM/outline.pdf">Proof outline</a><br>
+ <a href="../browser_info/current/AFP/Core_SC_DOM/document.pdf">Proof document</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/Core_SC_DOM/index.html">Browse theories</a>
+ </td></tr>
+ <tr>
+ <td class="links">
+ <a href="../release/afp-Core_SC_DOM-current.tar.gz">Download this entry</a>
+ </td>
+ </tr>
+
+
+ <tr><td class="links">Older releases:
+ None
+ </td></tr>
+
+ </tbody>
+</table>
+
+</div>
+</td>
+
+</tr>
+</tbody>
+</table>
+
+<script src="../jquery.min.js"></script>
+<script src="../script.js"></script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/web/entries/Efficient-Mergesort.html b/web/entries/Efficient-Mergesort.html
--- a/web/entries/Efficient-Mergesort.html
+++ b/web/entries/Efficient-Mergesort.html
@@ -1,261 +1,264 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Efficient Mergesort - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">E</font>fficient
<font class="first">M</font>ergesort
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Efficient Mergesort</td>
</tr>
<tr>
<td class="datahead">
Author:
</td>
<td class="data">
Christian Sternagel (c /dot/ sternagel /at/ gmail /dot/ com)
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2011-11-09</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">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.</td>
</tr>
<tr>
<td class="datahead" valign="top">Change history:</td>
<td class="abstract">[2012-10-24]:
Added reference to journal article.<br>
[2018-09-17]:
Added theory Efficient_Mergesort that works exclusively with the mutual
induction schemas generated by the function package.<br>
[2018-09-19]:
Added theory Mergesort_Complexity that proves an upper bound on the number of
comparisons that are required by mergesort.<br>
[2018-09-19]:
Theory Efficient_Mergesort replaces theory Efficient_Sort but keeping the old
-name Efficient_Sort.</td>
+name Efficient_Sort.
+[2020-11-20]:
+Additional theory Natural_Mergesort that developes an efficient mergesort
+algorithm without key-functions for educational purposes.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Efficient-Mergesort-AFP,
author = {Christian Sternagel},
title = {Efficient Mergesort},
journal = {Archive of Formal Proofs},
month = nov,
year = 2011,
note = {\url{http://isa-afp.org/entries/Efficient-Mergesort.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Used by:</td>
<td class="data"><a href="Regex_Equivalence.html">Regex_Equivalence</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Efficient-Mergesort/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Efficient-Mergesort/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Efficient-Mergesort/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Efficient-Mergesort-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Efficient-Mergesort-2019-06-11.tar.gz">
afp-Efficient-Mergesort-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Efficient-Mergesort-2018-08-16.tar.gz">
afp-Efficient-Mergesort-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Efficient-Mergesort-2017-10-10.tar.gz">
afp-Efficient-Mergesort-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Efficient-Mergesort-2016-12-17.tar.gz">
afp-Efficient-Mergesort-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Efficient-Mergesort-2016-02-22.tar.gz">
afp-Efficient-Mergesort-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Efficient-Mergesort-2015-05-27.tar.gz">
afp-Efficient-Mergesort-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Efficient-Mergesort-2014-08-28.tar.gz">
afp-Efficient-Mergesort-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-Efficient-Mergesort-2013-12-11.tar.gz">
afp-Efficient-Mergesort-2013-12-11.tar.gz
</a>
</li>
<li>Isabelle 2013-1:
<a href="../release/afp-Efficient-Mergesort-2013-11-17.tar.gz">
afp-Efficient-Mergesort-2013-11-17.tar.gz
</a>
</li>
<li>Isabelle 2013:
<a href="../release/afp-Efficient-Mergesort-2013-03-02.tar.gz">
afp-Efficient-Mergesort-2013-03-02.tar.gz
</a>
</li>
<li>Isabelle 2013:
<a href="../release/afp-Efficient-Mergesort-2013-02-16.tar.gz">
afp-Efficient-Mergesort-2013-02-16.tar.gz
</a>
</li>
<li>Isabelle 2012:
<a href="../release/afp-Efficient-Mergesort-2012-05-24.tar.gz">
afp-Efficient-Mergesort-2012-05-24.tar.gz
</a>
</li>
<li>Isabelle 2011-1:
<a href="../release/afp-Efficient-Mergesort-2011-11-10.tar.gz">
afp-Efficient-Mergesort-2011-11-10.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Formula_Derivatives.html b/web/entries/Formula_Derivatives.html
--- a/web/entries/Formula_Derivatives.html
+++ b/web/entries/Formula_Derivatives.html
@@ -1,231 +1,231 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Derivatives of Logical Formulas - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">D</font>erivatives
of
<font class="first">L</font>ogical
<font class="first">F</font>ormulas
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Derivatives of Logical Formulas</td>
</tr>
<tr>
<td class="datahead">
Author:
</td>
<td class="data">
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2015-05-28</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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 <em>not</em> 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).
<p>
The WS1S instance is described in the draft paper <a
href="https://people.inf.ethz.ch/trayteld/papers/csl15-ws1s_derivatives/index.html">A
Coalgebraic Decision Procedure for WS1S</a> by the author.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Formula_Derivatives-AFP,
author = {Dmitriy Traytel},
title = {Derivatives of Logical Formulas},
journal = {Archive of Formal Proofs},
month = may,
year = 2015,
note = {\url{http://isa-afp.org/entries/Formula_Derivatives.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Coinductive_Languages.html">Coinductive_Languages</a>, <a href="Deriving.html">Deriving</a>, <a href="List-Index.html">List-Index</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Formula_Derivatives/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Formula_Derivatives/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Formula_Derivatives/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Formula_Derivatives-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Formula_Derivatives-2019-06-11.tar.gz">
afp-Formula_Derivatives-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Formula_Derivatives-2018-08-16.tar.gz">
afp-Formula_Derivatives-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Formula_Derivatives-2017-10-10.tar.gz">
afp-Formula_Derivatives-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Formula_Derivatives-2016-12-17.tar.gz">
afp-Formula_Derivatives-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Formula_Derivatives-2016-02-22.tar.gz">
afp-Formula_Derivatives-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Formula_Derivatives-2015-05-28.tar.gz">
afp-Formula_Derivatives-2015-05-28.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Functional_Ordered_Resolution_Prover.html b/web/entries/Functional_Ordered_Resolution_Prover.html
--- a/web/entries/Functional_Ordered_Resolution_Prover.html
+++ b/web/entries/Functional_Ordered_Resolution_Prover.html
@@ -1,217 +1,217 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A Verified Functional Implementation of Bachmair and Ganzinger's Ordered Resolution Prover - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">A</font>
<font class="first">V</font>erified
<font class="first">F</font>unctional
<font class="first">I</font>mplementation
of
<font class="first">B</font>achmair
and
<font class="first">G</font>anzinger's
<font class="first">O</font>rdered
<font class="first">R</font>esolution
<font class="first">P</font>rover
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">A Verified Functional Implementation of Bachmair and Ganzinger's Ordered Resolution Prover</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
<a href="https://people.compute.dtu.dk/andschl/">Anders Schlichtkrull</a>,
Jasmin Christian Blanchette (j /dot/ c /dot/ blanchette /at/ vu /dot/ nl) and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2018-11-23</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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
<i>Handbook of Automated Reasoning</i>. The result is a
functional implementation of a first-order prover.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Functional_Ordered_Resolution_Prover-AFP,
author = {Anders Schlichtkrull and Jasmin Christian Blanchette and Dmitriy Traytel},
title = {A Verified Functional Implementation of Bachmair and Ganzinger's Ordered Resolution Prover},
journal = {Archive of Formal Proofs},
month = nov,
year = 2018,
note = {\url{http://isa-afp.org/entries/Functional_Ordered_Resolution_Prover.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="First_Order_Terms.html">First_Order_Terms</a>, <a href="Knuth_Bendix_Order.html">Knuth_Bendix_Order</a>, <a href="Lambda_Free_RPOs.html">Lambda_Free_RPOs</a>, <a href="Nested_Multisets_Ordinals.html">Nested_Multisets_Ordinals</a>, <a href="Open_Induction.html">Open_Induction</a>, <a href="Ordered_Resolution_Prover.html">Ordered_Resolution_Prover</a>, <a href="Polynomial_Factorization.html">Polynomial_Factorization</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Functional_Ordered_Resolution_Prover/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Functional_Ordered_Resolution_Prover/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Functional_Ordered_Resolution_Prover/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Functional_Ordered_Resolution_Prover-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Functional_Ordered_Resolution_Prover-2019-06-11.tar.gz">
afp-Functional_Ordered_Resolution_Prover-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Functional_Ordered_Resolution_Prover-2018-11-29.tar.gz">
afp-Functional_Ordered_Resolution_Prover-2018-11-29.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Goedel_HFSet_Semantic.html b/web/entries/Goedel_HFSet_Semantic.html
--- a/web/entries/Goedel_HFSet_Semantic.html
+++ b/web/entries/Goedel_HFSet_Semantic.html
@@ -1,205 +1,205 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part I - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">F</font>rom
<font class="first">A</font>bstract
to
<font class="first">C</font>oncrete
<font class="first">G</font>&ouml;del's
<font class="first">I</font>ncompleteness
<font class="first">T</font>heorems&mdash;Part
<font class="first">I</font>
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part I</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk) and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a> and
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2020-09-16</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
We validate an abstract formulation of G&ouml;del's First and
Second Incompleteness Theorems from a <a
href="https://www.isa-afp.org/entries/Goedel_Incompleteness.html">separate
AFP entry</a> by instantiating them to the case of
<i>finite sound extensions of the Hereditarily Finite (HF) Set
theory</i>, i.e., FOL theories extending the HF Set theory with
a finite set of axioms that are sound in the standard model. The
concrete results had been previously formalised in an <a
href="https://www.isa-afp.org/entries/Incompleteness.html">AFP
entry by Larry Paulson</a>; our instantiation reuses the
infrastructure developed in that entry.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Goedel_HFSet_Semantic-AFP,
author = {Andrei Popescu and Dmitriy Traytel},
title = {From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part I},
journal = {Archive of Formal Proofs},
month = sep,
year = 2020,
note = {\url{http://isa-afp.org/entries/Goedel_HFSet_Semantic.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Goedel_Incompleteness.html">Goedel_Incompleteness</a>, <a href="Incompleteness.html">Incompleteness</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Goedel_HFSet_Semantic/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Goedel_HFSet_Semantic/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Goedel_HFSet_Semantic/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Goedel_HFSet_Semantic-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
None
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Goedel_HFSet_Semanticless.html b/web/entries/Goedel_HFSet_Semanticless.html
--- a/web/entries/Goedel_HFSet_Semanticless.html
+++ b/web/entries/Goedel_HFSet_Semanticless.html
@@ -1,211 +1,211 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part II - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">F</font>rom
<font class="first">A</font>bstract
to
<font class="first">C</font>oncrete
<font class="first">G</font>&ouml;del's
<font class="first">I</font>ncompleteness
<font class="first">T</font>heorems&mdash;Part
<font class="first">I</font>I
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part II</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk) and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a> and
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2020-09-16</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
We validate an abstract formulation of G&ouml;del's Second
Incompleteness Theorem from a <a
href="https://www.isa-afp.org/entries/Goedel_Incompleteness.html">separate
AFP entry</a> by instantiating it to the case of <i>finite
consistent extensions of the Hereditarily Finite (HF) Set
theory</i>, i.e., consistent FOL theories extending the HF Set
theory with a finite set of axioms. The instantiation draws heavily
on infrastructure previously developed by Larry Paulson in his <a
href="https://www.isa-afp.org/entries/Incompleteness.html">direct
formalisation of the concrete result</a>. It strengthens
Paulson's formalization of G&ouml;del's Second from that
entry by <i>not</i> assuming soundness, and in fact not
relying on any notion of model or semantic interpretation. The
strengthening was obtained by first replacing some of Paulson’s
semantic arguments with proofs within his HF calculus, and then
plugging in some of Paulson's (modified) lemmas to instantiate
our soundness-free G&ouml;del's Second locale.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Goedel_HFSet_Semanticless-AFP,
author = {Andrei Popescu and Dmitriy Traytel},
title = {From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part II},
journal = {Archive of Formal Proofs},
month = sep,
year = 2020,
note = {\url{http://isa-afp.org/entries/Goedel_HFSet_Semanticless.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Goedel_Incompleteness.html">Goedel_Incompleteness</a>, <a href="HereditarilyFinite.html">HereditarilyFinite</a>, <a href="Nominal2.html">Nominal2</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Goedel_HFSet_Semanticless/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Goedel_HFSet_Semanticless/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Goedel_HFSet_Semanticless/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Goedel_HFSet_Semanticless-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
None
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Goedel_Incompleteness.html b/web/entries/Goedel_Incompleteness.html
--- a/web/entries/Goedel_Incompleteness.html
+++ b/web/entries/Goedel_Incompleteness.html
@@ -1,211 +1,211 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>An Abstract Formalization of G&ouml;del's Incompleteness Theorems - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">A</font>n
<font class="first">A</font>bstract
<font class="first">F</font>ormalization
of
<font class="first">G</font>&ouml;del's
<font class="first">I</font>ncompleteness
<font class="first">T</font>heorems
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">An Abstract Formalization of G&ouml;del's Incompleteness Theorems</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk) and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a> and
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2020-09-16</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
We present an abstract formalization of G&ouml;del's
incompleteness theorems. We analyze sufficient conditions for the
theorems' applicability to a partially specified logic. Our
abstract perspective enables a comparison between alternative
approaches from the literature. These include Rosser's variation
of the first theorem, Jeroslow's variation of the second theorem,
and the Swierczkowski&ndash;Paulson semantics-based approach. This
AFP entry is the main entry point to the results described in our
CADE-27 paper <a
href="https://dx.doi.org/10.1007/978-3-030-29436-6_26">A
Formally Verified Abstract Account of Gödel's Incompleteness
Theorems</a>. As part of our abstract formalization's
validation, we instantiate our locales twice in the separate AFP
entries <a
href="https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html">Goedel_HFSet_Semantic</a>
and <a
href="https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html">Goedel_HFSet_Semanticless</a>.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Goedel_Incompleteness-AFP,
author = {Andrei Popescu and Dmitriy Traytel},
title = {An Abstract Formalization of G&ouml;del's Incompleteness Theorems},
journal = {Archive of Formal Proofs},
month = sep,
year = 2020,
note = {\url{http://isa-afp.org/entries/Goedel_Incompleteness.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Syntax_Independent_Logic.html">Syntax_Independent_Logic</a> </td></tr>
<tr><td class="datahead">Used by:</td>
<td class="data"><a href="Goedel_HFSet_Semantic.html">Goedel_HFSet_Semantic</a>, <a href="Goedel_HFSet_Semanticless.html">Goedel_HFSet_Semanticless</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Goedel_Incompleteness/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Goedel_Incompleteness/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Goedel_Incompleteness/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Goedel_Incompleteness-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
None
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/HyperCTL.html b/web/entries/HyperCTL.html
--- a/web/entries/HyperCTL.html
+++ b/web/entries/HyperCTL.html
@@ -1,234 +1,234 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A shallow embedding of HyperCTL* - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">A</font>
shallow
embedding
of
<font class="first">H</font>yperCTL*
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">A shallow embedding of HyperCTL*</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
<a href="http://www.react.uni-saarland.de/people/rabe.html">Markus N. Rabe</a>,
Peter Lammich and
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk)
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2014-04-16</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">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.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{HyperCTL-AFP,
author = {Markus N. Rabe and Peter Lammich and Andrei Popescu},
title = {A shallow embedding of HyperCTL*},
journal = {Archive of Formal Proofs},
month = apr,
year = 2014,
note = {\url{http://isa-afp.org/entries/HyperCTL.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/HyperCTL/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/HyperCTL/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/HyperCTL/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-HyperCTL-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-HyperCTL-2019-06-11.tar.gz">
afp-HyperCTL-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-HyperCTL-2018-08-16.tar.gz">
afp-HyperCTL-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-HyperCTL-2017-10-10.tar.gz">
afp-HyperCTL-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-HyperCTL-2016-12-17.tar.gz">
afp-HyperCTL-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-HyperCTL-2016-02-22.tar.gz">
afp-HyperCTL-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-HyperCTL-2015-05-27.tar.gz">
afp-HyperCTL-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-HyperCTL-2014-08-28.tar.gz">
afp-HyperCTL-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-HyperCTL-2014-04-16.tar.gz">
afp-HyperCTL-2014-04-16.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/LambdaAuth.html b/web/entries/LambdaAuth.html
--- a/web/entries/LambdaAuth.html
+++ b/web/entries/LambdaAuth.html
@@ -1,217 +1,217 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Formalization of Generic Authenticated Data Structures - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">F</font>ormalization
of
<font class="first">G</font>eneric
<font class="first">A</font>uthenticated
<font class="first">D</font>ata
<font class="first">S</font>tructures
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Formalization of Generic Authenticated Data Structures</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Matthias Brun and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2019-05-14</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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. <a
href="https://doi.org/10.1145/2535838.2535851">Miller et
al.</a> introduced &lambda;&bull; (pronounced
<i>lambda auth</i>)&mdash;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 &lambda;&bull; and prove its
correctness and security properties. With Isabelle's help, we
uncover and repair several mistakes in the informal proofs and lemma
statements. Our findings are summarized in a <a
href="http://people.inf.ethz.ch/trayteld/papers/lambdaauth/lambdaauth.pdf">paper
draft</a>.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{LambdaAuth-AFP,
author = {Matthias Brun and Dmitriy Traytel},
title = {Formalization of Generic Authenticated Data Structures},
journal = {Archive of Formal Proofs},
month = may,
year = 2019,
note = {\url{http://isa-afp.org/entries/LambdaAuth.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Nominal2.html">Nominal2</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/LambdaAuth/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/LambdaAuth/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/LambdaAuth/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-LambdaAuth-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-LambdaAuth-2019-06-11.tar.gz">
afp-LambdaAuth-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-LambdaAuth-2019-05-15.tar.gz">
afp-LambdaAuth-2019-05-15.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/List-Index.html b/web/entries/List-Index.html
--- a/web/entries/List-Index.html
+++ b/web/entries/List-Index.html
@@ -1,257 +1,257 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>List Index - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">L</font>ist
<font class="first">I</font>ndex
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">List Index</td>
</tr>
<tr>
<td class="datahead">
Author:
</td>
<td class="data">
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2010-02-20</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">This theory provides functions for finding the index of an element in a list, by predicate and by value.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{List-Index-AFP,
author = {Tobias Nipkow},
title = {List Index},
journal = {Archive of Formal Proofs},
month = feb,
year = 2010,
note = {\url{http://isa-afp.org/entries/List-Index.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Used by:</td>
- <td class="data"><a href="Affine_Arithmetic.html">Affine_Arithmetic</a>, <a href="Comparison_Sort_Lower_Bound.html">Comparison_Sort_Lower_Bound</a>, <a href="Formula_Derivatives.html">Formula_Derivatives</a>, <a href="Higher_Order_Terms.html">Higher_Order_Terms</a>, <a href="Jinja.html">Jinja</a>, <a href="List_Update.html">List_Update</a>, <a href="LTL_to_DRA.html">LTL_to_DRA</a>, <a href="MSO_Regex_Equivalence.html">MSO_Regex_Equivalence</a>, <a href="Nested_Multisets_Ordinals.html">Nested_Multisets_Ordinals</a>, <a href="Ordinary_Differential_Equations.html">Ordinary_Differential_Equations</a>, <a href="Planarity_Certificates.html">Planarity_Certificates</a>, <a href="Quick_Sort_Cost.html">Quick_Sort_Cost</a>, <a href="Randomised_Social_Choice.html">Randomised_Social_Choice</a>, <a href="Refine_Imperative_HOL.html">Refine_Imperative_HOL</a>, <a href="Smith_Normal_Form.html">Smith_Normal_Form</a> </td></tr>
+ <td class="data"><a href="Affine_Arithmetic.html">Affine_Arithmetic</a>, <a href="Comparison_Sort_Lower_Bound.html">Comparison_Sort_Lower_Bound</a>, <a href="Formula_Derivatives.html">Formula_Derivatives</a>, <a href="Higher_Order_Terms.html">Higher_Order_Terms</a>, <a href="Jinja.html">Jinja</a>, <a href="List_Update.html">List_Update</a>, <a href="LTL_to_DRA.html">LTL_to_DRA</a>, <a href="MSO_Regex_Equivalence.html">MSO_Regex_Equivalence</a>, <a href="Nested_Multisets_Ordinals.html">Nested_Multisets_Ordinals</a>, <a href="Ordinary_Differential_Equations.html">Ordinary_Differential_Equations</a>, <a href="Planarity_Certificates.html">Planarity_Certificates</a>, <a href="Quick_Sort_Cost.html">Quick_Sort_Cost</a>, <a href="Randomised_Social_Choice.html">Randomised_Social_Choice</a>, <a href="Refine_Imperative_HOL.html">Refine_Imperative_HOL</a>, <a href="Smith_Normal_Form.html">Smith_Normal_Form</a>, <a href="Verified_SAT_Based_AI_Planning.html">Verified_SAT_Based_AI_Planning</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/List-Index/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/List-Index/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/List-Index/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-List-Index-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-List-Index-2019-06-11.tar.gz">
afp-List-Index-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-List-Index-2018-08-16.tar.gz">
afp-List-Index-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-List-Index-2017-10-10.tar.gz">
afp-List-Index-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-List-Index-2016-12-17.tar.gz">
afp-List-Index-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-List-Index-2016-02-22.tar.gz">
afp-List-Index-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-List-Index-2015-05-27.tar.gz">
afp-List-Index-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-List-Index-2014-08-28.tar.gz">
afp-List-Index-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-List-Index-2013-12-11.tar.gz">
afp-List-Index-2013-12-11.tar.gz
</a>
</li>
<li>Isabelle 2013-1:
<a href="../release/afp-List-Index-2013-11-17.tar.gz">
afp-List-Index-2013-11-17.tar.gz
</a>
</li>
<li>Isabelle 2013:
<a href="../release/afp-List-Index-2013-02-16.tar.gz">
afp-List-Index-2013-02-16.tar.gz
</a>
</li>
<li>Isabelle 2012:
<a href="../release/afp-List-Index-2012-05-24.tar.gz">
afp-List-Index-2012-05-24.tar.gz
</a>
</li>
<li>Isabelle 2011-1:
<a href="../release/afp-List-Index-2011-10-11.tar.gz">
afp-List-Index-2011-10-11.tar.gz
</a>
</li>
<li>Isabelle 2011:
<a href="../release/afp-List-Index-2011-02-11.tar.gz">
afp-List-Index-2011-02-11.tar.gz
</a>
</li>
<li>Isabelle 2009-2:
<a href="../release/afp-List-Index-2010-07-01.tar.gz">
afp-List-Index-2010-07-01.tar.gz
</a>
</li>
<li>Isabelle 2009-1:
<a href="../release/afp-List-Index-2010-02-20.tar.gz">
afp-List-Index-2010-02-20.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ 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,237 +1,237 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">F</font>ormalization
of
an
<font class="first">O</font>ptimized
<font class="first">M</font>onitoring
<font class="first">A</font>lgorithm
for
<font class="first">M</font>etric
<font class="first">F</font>irst-Order
<font class="first">D</font>ynamic
<font class="first">L</font>ogic
with
<font class="first">A</font>ggregations
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Thibault Dardinier,
Lukas Heimes,
Martin Raszyk (martin /dot/ raszyk /at/ inf /dot/ ethz /dot/ ch),
Joshua Schneider and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2020-04-09</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
A monitor is a runtime verification tool that solves the following
problem: Given a stream of time-stamped events and a policy formulated
in a specification language, decide whether the policy is satisfied at
every point in the stream. We verify the correctness of an executable
monitor for specifications given as formulas in metric first-order
dynamic logic (MFODL), which combines the features of metric
first-order temporal logic (MFOTL) and metric dynamic logic. Thus,
MFODL supports real-time constraints, first-order parameters, and
regular expressions. Additionally, the monitor supports aggregation
operations such as count and sum. This formalization, which is
described in a <a
href="http://people.inf.ethz.ch/trayteld/papers/ijcar20-verimonplus/verimonplus.pdf">
forthcoming paper at IJCAR 2020</a>, significantly extends <a
href="https://www.isa-afp.org/entries/MFOTL_Monitor.html">previous
work on a verified monitor</a> for MFOTL. Apart from the
addition of regular expressions and aggregations, we implemented <a
href="https://www.isa-afp.org/entries/Generic_Join.html">multi-way
joins</a> and a specialized sliding window algorithm to further
optimize the monitor.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{MFODL_Monitor_Optimized-AFP,
author = {Thibault Dardinier and Lukas Heimes and Martin Raszyk and Joshua Schneider and Dmitriy Traytel},
title = {Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations},
journal = {Archive of Formal Proofs},
month = apr,
year = 2020,
note = {\url{http://isa-afp.org/entries/MFODL_Monitor_Optimized.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Generic_Join.html">Generic_Join</a>, <a href="IEEE_Floating_Point.html">IEEE_Floating_Point</a>, <a href="MFOTL_Monitor.html">MFOTL_Monitor</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/MFODL_Monitor_Optimized/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/MFODL_Monitor_Optimized/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/MFODL_Monitor_Optimized/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-MFODL_Monitor_Optimized-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-MFODL_Monitor_Optimized-2020-04-12.tar.gz">
afp-MFODL_Monitor_Optimized-2020-04-12.tar.gz
</a>
</li>
<li>Isabelle 2019:
<a href="../release/afp-MFODL_Monitor_Optimized-2020-04-11.tar.gz">
afp-MFODL_Monitor_Optimized-2020-04-11.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/MFOTL_Monitor.html b/web/entries/MFOTL_Monitor.html
--- a/web/entries/MFOTL_Monitor.html
+++ b/web/entries/MFOTL_Monitor.html
@@ -1,226 +1,226 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">F</font>ormalization
of
a
<font class="first">M</font>onitoring
<font class="first">A</font>lgorithm
for
<font class="first">M</font>etric
<font class="first">F</font>irst-Order
<font class="first">T</font>emporal
<font class="first">L</font>ogic
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Joshua Schneider and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2019-07-04</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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 <a href="https://doi.org/10.1007/978-3-030-32079-9_18">RV
2019 paper</a>, 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.</td>
</tr>
<tr>
<td class="datahead" valign="top">Change history:</td>
<td class="abstract">[2020-08-13]:
added the formalization of the abstract slicing framework and joint data
slicer (revision b1639ed541b7)<br></td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{MFOTL_Monitor-AFP,
author = {Joshua Schneider and Dmitriy Traytel},
title = {Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic},
journal = {Archive of Formal Proofs},
month = jul,
year = 2019,
note = {\url{http://isa-afp.org/entries/MFOTL_Monitor.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Containers.html">Containers</a> </td></tr>
<tr><td class="datahead">Used by:</td>
<td class="data"><a href="Generic_Join.html">Generic_Join</a>, <a href="MFODL_Monitor_Optimized.html">MFODL_Monitor_Optimized</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/MFOTL_Monitor/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/MFOTL_Monitor/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/MFOTL_Monitor/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-MFOTL_Monitor-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-MFOTL_Monitor-2019-07-05.tar.gz">
afp-MFOTL_Monitor-2019-07-05.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/MSO_Regex_Equivalence.html b/web/entries/MSO_Regex_Equivalence.html
--- a/web/entries/MSO_Regex_Equivalence.html
+++ b/web/entries/MSO_Regex_Equivalence.html
@@ -1,260 +1,260 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Decision Procedures for MSO on Words Based on Derivatives of Regular Expressions - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">D</font>ecision
<font class="first">P</font>rocedures
for
<font class="first">M</font>SO
on
<font class="first">W</font>ords
<font class="first">B</font>ased
on
<font class="first">D</font>erivatives
of
<font class="first">R</font>egular
<font class="first">E</font>xpressions
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Decision Procedures for MSO on Words Based on Derivatives of Regular Expressions</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a> and
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a> and
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2014-06-12</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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.
<p>
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.
<p>
The formalization is described in this <a href="http://www21.in.tum.de/~nipkow/pubs/icfp13.html">ICFP 2013 functional pearl</a>.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{MSO_Regex_Equivalence-AFP,
author = {Dmitriy Traytel and Tobias Nipkow},
title = {Decision Procedures for MSO on Words Based on Derivatives of Regular Expressions},
journal = {Archive of Formal Proofs},
month = jun,
year = 2014,
note = {\url{http://isa-afp.org/entries/MSO_Regex_Equivalence.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Deriving.html">Deriving</a>, <a href="List-Index.html">List-Index</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/MSO_Regex_Equivalence/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/MSO_Regex_Equivalence/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/MSO_Regex_Equivalence/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-MSO_Regex_Equivalence-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-MSO_Regex_Equivalence-2019-06-11.tar.gz">
afp-MSO_Regex_Equivalence-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-MSO_Regex_Equivalence-2018-08-16.tar.gz">
afp-MSO_Regex_Equivalence-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-MSO_Regex_Equivalence-2017-10-10.tar.gz">
afp-MSO_Regex_Equivalence-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-MSO_Regex_Equivalence-2016-12-17.tar.gz">
afp-MSO_Regex_Equivalence-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-MSO_Regex_Equivalence-2016-02-22.tar.gz">
afp-MSO_Regex_Equivalence-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-MSO_Regex_Equivalence-2015-05-27.tar.gz">
afp-MSO_Regex_Equivalence-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-MSO_Regex_Equivalence-2014-08-28.tar.gz">
afp-MSO_Regex_Equivalence-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-MSO_Regex_Equivalence-2014-06-12.tar.gz">
afp-MSO_Regex_Equivalence-2014-06-12.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Native_Word.html b/web/entries/Native_Word.html
--- a/web/entries/Native_Word.html
+++ b/web/entries/Native_Word.html
@@ -1,251 +1,253 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Native Word - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">N</font>ative
<font class="first">W</font>ord
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Native Word</td>
</tr>
<tr>
<td class="datahead">
Author:
</td>
<td class="data">
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="datahead">
Contributor:
</td>
<td class="data">
<a href="http://www21.in.tum.de/~lammich">Peter Lammich</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2013-09-17</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">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.</td>
</tr>
<tr>
<td class="datahead" valign="top">Change history:</td>
<td class="abstract">[2013-11-06]:
added conversion function between native words and characters
(revision fd23d9a7fe3a)<br>
[2014-03-31]:
added words of default size in the target language (by Peter Lammich)
(revision 25caf5065833)<br>
[2014-10-06]:
proper test setup with compilation and execution of tests in all target languages
(revision 5d7a1c9ae047)<br>
[2017-09-02]:
added 64-bit words (revision c89f86244e3c)<br>
[2018-07-15]:
added cast operators for default-size words (revision fc1f1fb8dd30)<br></td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Native_Word-AFP,
author = {Andreas Lochbihler},
title = {Native Word},
journal = {Archive of Formal Proofs},
month = sep,
year = 2013,
note = {\url{http://isa-afp.org/entries/Native_Word.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
-
+ <tr><td class="datahead">Depends on:</td>
+ <td class="data"><a href="Word_Lib.html">Word_Lib</a> </td></tr>
+
<tr><td class="datahead">Used by:</td>
<td class="data"><a href="Collections.html">Collections</a>, <a href="Datatype_Order_Generator.html">Datatype_Order_Generator</a>, <a href="Iptables_Semantics.html">Iptables_Semantics</a>, <a href="JinjaThreads.html">JinjaThreads</a>, <a href="Mersenne_Primes.html">Mersenne_Primes</a>, <a href="ROBDD.html">ROBDD</a>, <a href="Separation_Logic_Imperative_HOL.html">Separation_Logic_Imperative_HOL</a>, <a href="WebAssembly.html">WebAssembly</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Native_Word/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Native_Word/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Native_Word/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Native_Word-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Native_Word-2019-06-11.tar.gz">
afp-Native_Word-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Native_Word-2018-08-16.tar.gz">
afp-Native_Word-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Native_Word-2017-10-10.tar.gz">
afp-Native_Word-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Native_Word-2016-12-17.tar.gz">
afp-Native_Word-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Native_Word-2016-02-22.tar.gz">
afp-Native_Word-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Native_Word-2015-05-27.tar.gz">
afp-Native_Word-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Native_Word-2014-08-28.tar.gz">
afp-Native_Word-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-Native_Word-2013-12-11.tar.gz">
afp-Native_Word-2013-12-11.tar.gz
</a>
</li>
<li>Isabelle 2013-1:
<a href="../release/afp-Native_Word-2013-11-17.tar.gz">
afp-Native_Word-2013-11-17.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Nested_Multisets_Ordinals.html b/web/entries/Nested_Multisets_Ordinals.html
--- a/web/entries/Nested_Multisets_Ordinals.html
+++ b/web/entries/Nested_Multisets_Ordinals.html
@@ -1,220 +1,220 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Formalization of Nested Multisets, Hereditary Multisets, and Syntactic Ordinals - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">F</font>ormalization
of
<font class="first">N</font>ested
<font class="first">M</font>ultisets,
<font class="first">H</font>ereditary
<font class="first">M</font>ultisets,
and
<font class="first">S</font>yntactic
<font class="first">O</font>rdinals
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Formalization of Nested Multisets, Hereditary Multisets, and Syntactic Ordinals</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Jasmin Christian Blanchette (j /dot/ c /dot/ blanchette /at/ vu /dot/ nl),
<a href="http://fmv.jku.at/fleury">Mathias Fleury</a> and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2016-11-12</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">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.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Nested_Multisets_Ordinals-AFP,
author = {Jasmin Christian Blanchette and Mathias Fleury and Dmitriy Traytel},
title = {Formalization of Nested Multisets, Hereditary Multisets, and Syntactic Ordinals},
journal = {Archive of Formal Proofs},
month = nov,
year = 2016,
note = {\url{http://isa-afp.org/entries/Nested_Multisets_Ordinals.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="List-Index.html">List-Index</a>, <a href="Ordinal.html">Ordinal</a> </td></tr>
<tr><td class="datahead">Used by:</td>
<td class="data"><a href="Functional_Ordered_Resolution_Prover.html">Functional_Ordered_Resolution_Prover</a>, <a href="Lambda_Free_KBOs.html">Lambda_Free_KBOs</a>, <a href="Lambda_Free_RPOs.html">Lambda_Free_RPOs</a>, <a href="Ordered_Resolution_Prover.html">Ordered_Resolution_Prover</a>, <a href="PAC_Checker.html">PAC_Checker</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Nested_Multisets_Ordinals/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Nested_Multisets_Ordinals/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Nested_Multisets_Ordinals/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Nested_Multisets_Ordinals-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Nested_Multisets_Ordinals-2019-06-11.tar.gz">
afp-Nested_Multisets_Ordinals-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Nested_Multisets_Ordinals-2018-08-16.tar.gz">
afp-Nested_Multisets_Ordinals-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Nested_Multisets_Ordinals-2017-10-10.tar.gz">
afp-Nested_Multisets_Ordinals-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Nested_Multisets_Ordinals-2016-12-17.tar.gz">
afp-Nested_Multisets_Ordinals-2016-12-17.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Ordered_Resolution_Prover.html b/web/entries/Ordered_Resolution_Prover.html
--- a/web/entries/Ordered_Resolution_Prover.html
+++ b/web/entries/Ordered_Resolution_Prover.html
@@ -1,221 +1,221 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Formalization of Bachmair and Ganzinger's Ordered Resolution Prover - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">F</font>ormalization
of
<font class="first">B</font>achmair
and
<font class="first">G</font>anzinger's
<font class="first">O</font>rdered
<font class="first">R</font>esolution
<font class="first">P</font>rover
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Formalization of Bachmair and Ganzinger's Ordered Resolution Prover</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
<a href="https://people.compute.dtu.dk/andschl/">Anders Schlichtkrull</a>,
Jasmin Christian Blanchette (j /dot/ c /dot/ blanchette /at/ vu /dot/ nl),
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a> and
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a> and
Uwe Waldmann (uwe /at/ mpi-inf /dot/ mpg /dot/ de)
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2018-01-18</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
This Isabelle/HOL formalization covers Sections 2 to 4 of Bachmair and
Ganzinger's "Resolution Theorem Proving" chapter in the
<em>Handbook of Automated Reasoning</em>. 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.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Ordered_Resolution_Prover-AFP,
author = {Anders Schlichtkrull and Jasmin Christian Blanchette and Dmitriy Traytel and Uwe Waldmann},
title = {Formalization of Bachmair and Ganzinger's Ordered Resolution Prover},
journal = {Archive of Formal Proofs},
month = jan,
year = 2018,
note = {\url{http://isa-afp.org/entries/Ordered_Resolution_Prover.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Coinductive.html">Coinductive</a>, <a href="Nested_Multisets_Ordinals.html">Nested_Multisets_Ordinals</a> </td></tr>
<tr><td class="datahead">Used by:</td>
<td class="data"><a href="Chandy_Lamport.html">Chandy_Lamport</a>, <a href="Functional_Ordered_Resolution_Prover.html">Functional_Ordered_Resolution_Prover</a>, <a href="Saturation_Framework.html">Saturation_Framework</a>, <a href="Saturation_Framework_Extensions.html">Saturation_Framework_Extensions</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Ordered_Resolution_Prover/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Ordered_Resolution_Prover/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Ordered_Resolution_Prover/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Ordered_Resolution_Prover-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Ordered_Resolution_Prover-2019-06-11.tar.gz">
afp-Ordered_Resolution_Prover-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Ordered_Resolution_Prover-2018-08-16.tar.gz">
afp-Ordered_Resolution_Prover-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Ordered_Resolution_Prover-2018-01-22.tar.gz">
afp-Ordered_Resolution_Prover-2018-01-22.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Ordinals_and_Cardinals.html b/web/entries/Ordinals_and_Cardinals.html
--- a/web/entries/Ordinals_and_Cardinals.html
+++ b/web/entries/Ordinals_and_Cardinals.html
@@ -1,271 +1,271 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Ordinals and Cardinals - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">O</font>rdinals
and
<font class="first">C</font>ardinals
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Ordinals and Cardinals</td>
</tr>
<tr>
<td class="datahead">
Author:
</td>
<td class="data">
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk)
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2009-09-01</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">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.</td>
</tr>
<tr>
<td class="datahead" valign="top">Change history:</td>
<td class="abstract">[2012-09-25]: This entry has been discontinued because it is now part of the Isabelle distribution.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Ordinals_and_Cardinals-AFP,
author = {Andrei Popescu},
title = {Ordinals and Cardinals},
journal = {Archive of Formal Proofs},
month = sep,
year = 2009,
note = {\url{http://isa-afp.org/entries/Ordinals_and_Cardinals.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Ordinals_and_Cardinals/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Ordinals_and_Cardinals/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Ordinals_and_Cardinals/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Ordinals_and_Cardinals-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Ordinals_and_Cardinals-2019-06-11.tar.gz">
afp-Ordinals_and_Cardinals-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Ordinals_and_Cardinals-2018-08-16.tar.gz">
afp-Ordinals_and_Cardinals-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Ordinals_and_Cardinals-2017-10-10.tar.gz">
afp-Ordinals_and_Cardinals-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Ordinals_and_Cardinals-2016-12-17.tar.gz">
afp-Ordinals_and_Cardinals-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Ordinals_and_Cardinals-2016-02-22.tar.gz">
afp-Ordinals_and_Cardinals-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Ordinals_and_Cardinals-2015-05-27.tar.gz">
afp-Ordinals_and_Cardinals-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Ordinals_and_Cardinals-2014-08-28.tar.gz">
afp-Ordinals_and_Cardinals-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-Ordinals_and_Cardinals-2013-12-11.tar.gz">
afp-Ordinals_and_Cardinals-2013-12-11.tar.gz
</a>
</li>
<li>Isabelle 2013-1:
<a href="../release/afp-Ordinals_and_Cardinals-2013-11-17.tar.gz">
afp-Ordinals_and_Cardinals-2013-11-17.tar.gz
</a>
</li>
<li>Isabelle 2013:
<a href="../release/afp-Ordinals_and_Cardinals-2013-02-16.tar.gz">
afp-Ordinals_and_Cardinals-2013-02-16.tar.gz
</a>
</li>
<li>Isabelle 2012:
<a href="../release/afp-Ordinals_and_Cardinals-2012-05-24.tar.gz">
afp-Ordinals_and_Cardinals-2012-05-24.tar.gz
</a>
</li>
<li>Isabelle 2011-1:
<a href="../release/afp-Ordinals_and_Cardinals-2011-10-11.tar.gz">
afp-Ordinals_and_Cardinals-2011-10-11.tar.gz
</a>
</li>
<li>Isabelle 2011:
<a href="../release/afp-Ordinals_and_Cardinals-2011-02-11.tar.gz">
afp-Ordinals_and_Cardinals-2011-02-11.tar.gz
</a>
</li>
<li>Isabelle 2009-2:
<a href="../release/afp-Ordinals_and_Cardinals-2010-07-01.tar.gz">
afp-Ordinals_and_Cardinals-2010-07-01.tar.gz
</a>
</li>
<li>Isabelle 2009-1:
<a href="../release/afp-Ordinals_and_Cardinals-2009-12-12.tar.gz">
afp-Ordinals_and_Cardinals-2009-12-12.tar.gz
</a>
</li>
<li>Isabelle 2009:
<a href="../release/afp-Ordinals_and_Cardinals-2009-09-09.tar.gz">
afp-Ordinals_and_Cardinals-2009-09-09.tar.gz
</a>
</li>
<li>Isabelle 2009:
<a href="../release/afp-Ordinals_and_Cardinals-2009-09-07.tar.gz">
afp-Ordinals_and_Cardinals-2009-09-07.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Physical_Quantities.html b/web/entries/Physical_Quantities.html
new file mode 100644
--- /dev/null
+++ b/web/entries/Physical_Quantities.html
@@ -0,0 +1,209 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>A Sound Type System for Physical Quantities, Units, and Measurements - Archive of Formal Proofs
+</title>
+<link rel="stylesheet" type="text/css" href="../front.css">
+<link rel="icon" href="../images/favicon.ico" type="image/icon">
+<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
+<!-- MathJax for LaTeX support in abstracts -->
+<script>
+MathJax = {
+ tex: {
+ inlineMath: [['$', '$'], ['\\(', '\\)']]
+ },
+ processEscapes: true,
+ svg: {
+ fontCache: 'global'
+ }
+};
+</script>
+<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
+</head>
+
+<body class="mathjax_ignore">
+
+<table width="100%">
+<tbody>
+<tr>
+
+<!-- Navigation -->
+<td width="20%" align="center" valign="top">
+ <p>&nbsp;</p>
+ <a href="https://www.isa-afp.org/">
+ <img src="../images/isabelle.png" width="100" height="88" border=0>
+ </a>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+ <table class="nav" width="80%">
+ <tr>
+ <td class="nav" width="100%"><a href="../index.html">Home</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../about.html">About</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../submitting.html">Submission</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../updating.html">Updating Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../using.html">Using Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../search.html">Search</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../statistics.html">Statistics</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../topics.html">Index</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../download.html">Download</a></td>
+ </tr>
+ </table>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+</td>
+
+
+<!-- Content -->
+<td width="80%" valign="top">
+<div align="center">
+ <p>&nbsp;</p>
+ <h1> <font class="first">A</font>
+
+ <font class="first">S</font>ound
+
+ <font class="first">T</font>ype
+
+ <font class="first">S</font>ystem
+
+ for
+
+ <font class="first">P</font>hysical
+
+ <font class="first">Q</font>uantities,
+
+ <font class="first">U</font>nits,
+
+ and
+
+ <font class="first">M</font>easurements
+
+</h1>
+ <p>&nbsp;</p>
+
+<table width="80%" class="data">
+<tbody>
+<tr>
+ <td class="datahead" width="20%">Title:</td>
+ <td class="data" width="80%">A Sound Type System for Physical Quantities, Units, and Measurements</td>
+</tr>
+
+<tr>
+ <td class="datahead">
+ Authors:
+ </td>
+ <td class="data">
+ <a href="https://www-users.cs.york.ac.uk/~simonf/">Simon Foster</a> and
+ <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
+ </td>
+</tr>
+
+
+
+<tr>
+ <td class="datahead">Submission date:</td>
+ <td class="data">2020-10-20</td>
+</tr>
+
+<tr>
+ <td class="datahead" valign="top">Abstract:</td>
+ <td class="abstract mathjax_process">
+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).</td>
+</tr>
+
+
+<tr>
+ <td class="datahead" valign="top">BibTeX:</td>
+ <td class="formatted">
+ <pre>@article{Physical_Quantities-AFP,
+ author = {Simon Foster and Burkhart Wolff},
+ title = {A Sound Type System for Physical Quantities, Units, and Measurements},
+ journal = {Archive of Formal Proofs},
+ month = oct,
+ year = 2020,
+ note = {\url{http://isa-afp.org/entries/Physical_Quantities.html},
+ Formal proof development},
+ ISSN = {2150-914x},
+}</pre>
+ </td>
+</tr>
+
+ <tr><td class="datahead">License:</td>
+ <td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
+
+
+
+
+
+
+ </tbody>
+</table>
+
+<p></p>
+
+<table class="links">
+ <tbody>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/Physical_Quantities/outline.pdf">Proof outline</a><br>
+ <a href="../browser_info/current/AFP/Physical_Quantities/document.pdf">Proof document</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/Physical_Quantities/index.html">Browse theories</a>
+ </td></tr>
+ <tr>
+ <td class="links">
+ <a href="../release/afp-Physical_Quantities-current.tar.gz">Download this entry</a>
+ </td>
+ </tr>
+
+
+ <tr><td class="links">Older releases:
+ None
+ </td></tr>
+
+ </tbody>
+</table>
+
+</div>
+</td>
+
+</tr>
+</tbody>
+</table>
+
+<script src="../jquery.min.js"></script>
+<script src="../script.js"></script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/web/entries/Possibilistic_Noninterference.html b/web/entries/Possibilistic_Noninterference.html
--- a/web/entries/Possibilistic_Noninterference.html
+++ b/web/entries/Possibilistic_Noninterference.html
@@ -1,244 +1,244 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Possibilistic Noninterference - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">P</font>ossibilistic
<font class="first">N</font>oninterference
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Possibilistic Noninterference</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk) and
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a> and
<a href="http://in.tum.de/~hoelzl">Johannes Hölzl</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2012-09-10</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">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.
<p>
An <a href="http://www21.in.tum.de/~nipkow/pubs/cpp12.html">article</a>
about these proofs is published in the proceedings
of the conference Certified Programs and Proofs 2012.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Possibilistic_Noninterference-AFP,
author = {Andrei Popescu and Johannes Hölzl},
title = {Possibilistic Noninterference},
journal = {Archive of Formal Proofs},
month = sep,
year = 2012,
note = {\url{http://isa-afp.org/entries/Possibilistic_Noninterference.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Possibilistic_Noninterference/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Possibilistic_Noninterference/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Possibilistic_Noninterference/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Possibilistic_Noninterference-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Possibilistic_Noninterference-2019-06-11.tar.gz">
afp-Possibilistic_Noninterference-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Possibilistic_Noninterference-2018-08-16.tar.gz">
afp-Possibilistic_Noninterference-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Possibilistic_Noninterference-2017-10-10.tar.gz">
afp-Possibilistic_Noninterference-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Possibilistic_Noninterference-2016-12-17.tar.gz">
afp-Possibilistic_Noninterference-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Possibilistic_Noninterference-2016-02-22.tar.gz">
afp-Possibilistic_Noninterference-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Possibilistic_Noninterference-2015-05-27.tar.gz">
afp-Possibilistic_Noninterference-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Possibilistic_Noninterference-2014-08-28.tar.gz">
afp-Possibilistic_Noninterference-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-Possibilistic_Noninterference-2013-12-11.tar.gz">
afp-Possibilistic_Noninterference-2013-12-11.tar.gz
</a>
</li>
<li>Isabelle 2013-1:
<a href="../release/afp-Possibilistic_Noninterference-2013-11-17.tar.gz">
afp-Possibilistic_Noninterference-2013-11-17.tar.gz
</a>
</li>
<li>Isabelle 2013:
<a href="../release/afp-Possibilistic_Noninterference-2013-02-16.tar.gz">
afp-Possibilistic_Noninterference-2013-02-16.tar.gz
</a>
</li>
<li>Isabelle 2012:
<a href="../release/afp-Possibilistic_Noninterference-2012-09-10.tar.gz">
afp-Possibilistic_Noninterference-2012-09-10.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Probabilistic_Noninterference.html b/web/entries/Probabilistic_Noninterference.html
--- a/web/entries/Probabilistic_Noninterference.html
+++ b/web/entries/Probabilistic_Noninterference.html
@@ -1,223 +1,223 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Probabilistic Noninterference - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">P</font>robabilistic
<font class="first">N</font>oninterference
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Probabilistic Noninterference</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk) and
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a> and
<a href="http://in.tum.de/~hoelzl">Johannes Hölzl</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2014-03-11</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">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.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Probabilistic_Noninterference-AFP,
author = {Andrei Popescu and Johannes Hölzl},
title = {Probabilistic Noninterference},
journal = {Archive of Formal Proofs},
month = mar,
year = 2014,
note = {\url{http://isa-afp.org/entries/Probabilistic_Noninterference.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Coinductive.html">Coinductive</a>, <a href="Markov_Models.html">Markov_Models</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Probabilistic_Noninterference/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Probabilistic_Noninterference/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Probabilistic_Noninterference/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Probabilistic_Noninterference-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Probabilistic_Noninterference-2019-06-11.tar.gz">
afp-Probabilistic_Noninterference-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Probabilistic_Noninterference-2018-08-16.tar.gz">
afp-Probabilistic_Noninterference-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Probabilistic_Noninterference-2017-10-10.tar.gz">
afp-Probabilistic_Noninterference-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Probabilistic_Noninterference-2016-12-17.tar.gz">
afp-Probabilistic_Noninterference-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Probabilistic_Noninterference-2016-02-22.tar.gz">
afp-Probabilistic_Noninterference-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Probabilistic_Noninterference-2015-05-27.tar.gz">
afp-Probabilistic_Noninterference-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Probabilistic_Noninterference-2014-08-28.tar.gz">
afp-Probabilistic_Noninterference-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-Probabilistic_Noninterference-2014-03-16.tar.gz">
afp-Probabilistic_Noninterference-2014-03-16.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Probabilistic_System_Zoo.html b/web/entries/Probabilistic_System_Zoo.html
--- a/web/entries/Probabilistic_System_Zoo.html
+++ b/web/entries/Probabilistic_System_Zoo.html
@@ -1,226 +1,226 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A Zoo of Probabilistic Systems - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">A</font>
<font class="first">Z</font>oo
of
<font class="first">P</font>robabilistic
<font class="first">S</font>ystems
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">A Zoo of Probabilistic Systems</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
<a href="http://in.tum.de/~hoelzl">Johannes Hölzl</a>,
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a> and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2015-05-27</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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.
<p>
This work is described in detail in the ITP 2015 publication by the authors.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Probabilistic_System_Zoo-AFP,
author = {Johannes Hölzl and Andreas Lochbihler and Dmitriy Traytel},
title = {A Zoo of Probabilistic Systems},
journal = {Archive of Formal Proofs},
month = may,
year = 2015,
note = {\url{http://isa-afp.org/entries/Probabilistic_System_Zoo.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Probabilistic_System_Zoo/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Probabilistic_System_Zoo/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Probabilistic_System_Zoo/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Probabilistic_System_Zoo-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Probabilistic_System_Zoo-2019-06-11.tar.gz">
afp-Probabilistic_System_Zoo-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Probabilistic_System_Zoo-2018-08-16.tar.gz">
afp-Probabilistic_System_Zoo-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Probabilistic_System_Zoo-2017-10-10.tar.gz">
afp-Probabilistic_System_Zoo-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Probabilistic_System_Zoo-2016-12-17.tar.gz">
afp-Probabilistic_System_Zoo-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Probabilistic_System_Zoo-2016-02-22.tar.gz">
afp-Probabilistic_System_Zoo-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Probabilistic_System_Zoo-2015-05-28.tar.gz">
afp-Probabilistic_System_Zoo-2015-05-28.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Propositional_Proof_Systems.html b/web/entries/Propositional_Proof_Systems.html
--- a/web/entries/Propositional_Proof_Systems.html
+++ b/web/entries/Propositional_Proof_Systems.html
@@ -1,209 +1,211 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Propositional Proof Systems - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">P</font>ropositional
<font class="first">P</font>roof
<font class="first">S</font>ystems
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Propositional Proof Systems</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
<a href="http://liftm.de">Julius Michaelis</a> and
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2017-06-21</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Propositional_Proof_Systems-AFP,
author = {Julius Michaelis and Tobias Nipkow},
title = {Propositional Proof Systems},
journal = {Archive of Formal Proofs},
month = jun,
year = 2017,
note = {\url{http://isa-afp.org/entries/Propositional_Proof_Systems.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
-
+ <tr><td class="datahead">Used by:</td>
+ <td class="data"><a href="AI_Planning_Languages_Semantics.html">AI_Planning_Languages_Semantics</a>, <a href="Verified_SAT_Based_AI_Planning.html">Verified_SAT_Based_AI_Planning</a> </td></tr>
+
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Propositional_Proof_Systems/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Propositional_Proof_Systems/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Propositional_Proof_Systems/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Propositional_Proof_Systems-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Propositional_Proof_Systems-2019-06-11.tar.gz">
afp-Propositional_Proof_Systems-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Propositional_Proof_Systems-2018-08-16.tar.gz">
afp-Propositional_Proof_Systems-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Propositional_Proof_Systems-2017-10-10.tar.gz">
afp-Propositional_Proof_Systems-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Propositional_Proof_Systems-2017-06-22.tar.gz">
afp-Propositional_Proof_Systems-2017-06-22.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Regex_Equivalence.html b/web/entries/Regex_Equivalence.html
--- a/web/entries/Regex_Equivalence.html
+++ b/web/entries/Regex_Equivalence.html
@@ -1,249 +1,249 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Unified Decision Procedures for Regular Expression Equivalence - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">U</font>nified
<font class="first">D</font>ecision
<font class="first">P</font>rocedures
for
<font class="first">R</font>egular
<font class="first">E</font>xpression
<font class="first">E</font>quivalence
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Unified Decision Procedures for Regular Expression Equivalence</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a> and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2014-01-30</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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.
<a href="http://www21.in.tum.de/~nipkow/pubs/itp14.html">
The formalization is described in a paper of the same name presented at
Interactive Theorem Proving 2014</a>.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Regex_Equivalence-AFP,
author = {Tobias Nipkow and Dmitriy Traytel},
title = {Unified Decision Procedures for Regular Expression Equivalence},
journal = {Archive of Formal Proofs},
month = jan,
year = 2014,
note = {\url{http://isa-afp.org/entries/Regex_Equivalence.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Efficient-Mergesort.html">Efficient-Mergesort</a>, <a href="Regular-Sets.html">Regular-Sets</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Regex_Equivalence/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Regex_Equivalence/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Regex_Equivalence/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Regex_Equivalence-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Regex_Equivalence-2019-06-11.tar.gz">
afp-Regex_Equivalence-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Regex_Equivalence-2018-08-16.tar.gz">
afp-Regex_Equivalence-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Regex_Equivalence-2017-10-10.tar.gz">
afp-Regex_Equivalence-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Regex_Equivalence-2016-12-17.tar.gz">
afp-Regex_Equivalence-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Regex_Equivalence-2016-02-22.tar.gz">
afp-Regex_Equivalence-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Regex_Equivalence-2015-05-27.tar.gz">
afp-Regex_Equivalence-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Regex_Equivalence-2014-11-30.tar.gz">
afp-Regex_Equivalence-2014-11-30.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Regex_Equivalence-2014-08-28.tar.gz">
afp-Regex_Equivalence-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-Regex_Equivalence-2014-01-30.tar.gz">
afp-Regex_Equivalence-2014-01-30.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Robinson_Arithmetic.html b/web/entries/Robinson_Arithmetic.html
--- a/web/entries/Robinson_Arithmetic.html
+++ b/web/entries/Robinson_Arithmetic.html
@@ -1,191 +1,191 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Robinson Arithmetic - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">R</font>obinson
<font class="first">A</font>rithmetic
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Robinson Arithmetic</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk) and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a> and
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2020-09-16</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
We instantiate our syntax-independent logic infrastructure developed
in <a
href="https://www.isa-afp.org/entries/Syntax_Independent_Logic.html">a
separate AFP entry</a> to the FOL theory of Robinson arithmetic
(also known as Q). The latter was formalised using Nominal Isabelle by
adapting <a
href="https://www.isa-afp.org/entries/Incompleteness.html">Larry
Paulson’s formalization of the Hereditarily Finite Set
theory</a>.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Robinson_Arithmetic-AFP,
author = {Andrei Popescu and Dmitriy Traytel},
title = {Robinson Arithmetic},
journal = {Archive of Formal Proofs},
month = sep,
year = 2020,
note = {\url{http://isa-afp.org/entries/Robinson_Arithmetic.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Nominal2.html">Nominal2</a>, <a href="Syntax_Independent_Logic.html">Syntax_Independent_Logic</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Robinson_Arithmetic/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Robinson_Arithmetic/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Robinson_Arithmetic/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Robinson_Arithmetic-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
None
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/SC_DOM_Components.html b/web/entries/SC_DOM_Components.html
new file mode 100644
--- /dev/null
+++ b/web/entries/SC_DOM_Components.html
@@ -0,0 +1,208 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>A Formalization of Safely Composable Web Components - Archive of Formal Proofs
+</title>
+<link rel="stylesheet" type="text/css" href="../front.css">
+<link rel="icon" href="../images/favicon.ico" type="image/icon">
+<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
+<!-- MathJax for LaTeX support in abstracts -->
+<script>
+MathJax = {
+ tex: {
+ inlineMath: [['$', '$'], ['\\(', '\\)']]
+ },
+ processEscapes: true,
+ svg: {
+ fontCache: 'global'
+ }
+};
+</script>
+<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
+</head>
+
+<body class="mathjax_ignore">
+
+<table width="100%">
+<tbody>
+<tr>
+
+<!-- Navigation -->
+<td width="20%" align="center" valign="top">
+ <p>&nbsp;</p>
+ <a href="https://www.isa-afp.org/">
+ <img src="../images/isabelle.png" width="100" height="88" border=0>
+ </a>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+ <table class="nav" width="80%">
+ <tr>
+ <td class="nav" width="100%"><a href="../index.html">Home</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../about.html">About</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../submitting.html">Submission</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../updating.html">Updating Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../using.html">Using Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../search.html">Search</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../statistics.html">Statistics</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../topics.html">Index</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../download.html">Download</a></td>
+ </tr>
+ </table>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+</td>
+
+
+<!-- Content -->
+<td width="80%" valign="top">
+<div align="center">
+ <p>&nbsp;</p>
+ <h1> <font class="first">A</font>
+
+ <font class="first">F</font>ormalization
+
+ of
+
+ <font class="first">S</font>afely
+
+ <font class="first">C</font>omposable
+
+ <font class="first">W</font>eb
+
+ <font class="first">C</font>omponents
+
+</h1>
+ <p>&nbsp;</p>
+
+<table width="80%" class="data">
+<tbody>
+<tr>
+ <td class="datahead" width="20%">Title:</td>
+ <td class="data" width="80%">A Formalization of Safely Composable Web Components</td>
+</tr>
+
+<tr>
+ <td class="datahead">
+ Authors:
+ </td>
+ <td class="data">
+ Achim D. Brucker (a /dot/ brucker /at/ exeter /dot/ ac /dot/ uk) and
+ <a href="http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.Herzberg">Michael Herzberg</a>
+ </td>
+</tr>
+
+
+
+<tr>
+ <td class="datahead">Submission date:</td>
+ <td class="data">2020-09-28</td>
+</tr>
+
+<tr>
+ <td class="datahead" valign="top">Abstract:</td>
+ <td class="abstract mathjax_process">
+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.</td>
+</tr>
+
+
+<tr>
+ <td class="datahead" valign="top">BibTeX:</td>
+ <td class="formatted">
+ <pre>@article{SC_DOM_Components-AFP,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {A Formalization of Safely Composable Web Components},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ note = {\url{http://isa-afp.org/entries/SC_DOM_Components.html},
+ Formal proof development},
+ ISSN = {2150-914x},
+}</pre>
+ </td>
+</tr>
+
+ <tr><td class="datahead">License:</td>
+ <td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
+
+
+ <tr><td class="datahead">Depends on:</td>
+ <td class="data"><a href="Shadow_SC_DOM.html">Shadow_SC_DOM</a> </td></tr>
+
+
+
+
+ </tbody>
+</table>
+
+<p></p>
+
+<table class="links">
+ <tbody>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/SC_DOM_Components/outline.pdf">Proof outline</a><br>
+ <a href="../browser_info/current/AFP/SC_DOM_Components/document.pdf">Proof document</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/SC_DOM_Components/index.html">Browse theories</a>
+ </td></tr>
+ <tr>
+ <td class="links">
+ <a href="../release/afp-SC_DOM_Components-current.tar.gz">Download this entry</a>
+ </td>
+ </tr>
+
+
+ <tr><td class="links">Older releases:
+ None
+ </td></tr>
+
+ </tbody>
+</table>
+
+</div>
+</td>
+
+</tr>
+</tbody>
+</table>
+
+<script src="../jquery.min.js"></script>
+<script src="../script.js"></script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/web/entries/SPARCv8.html b/web/entries/SPARCv8.html
--- a/web/entries/SPARCv8.html
+++ b/web/entries/SPARCv8.html
@@ -1,245 +1,247 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>A formal model for the SPARCv8 ISA and a proof of non-interference for the LEON3 processor - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">A</font>
formal
model
for
the
<font class="first">S</font>PARCv8
<font class="first">I</font>SA
and
a
proof
of
non-interference
for
the
<font class="first">L</font>EON3
processor
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">A formal model for the SPARCv8 ISA and a proof of non-interference for the LEON3 processor</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Zhe Hou (zhe /dot/ hou /at/ ntu /dot/ edu /dot/ sg),
David Sanan (sanan /at/ ntu /dot/ edu /dot/ sg),
Alwen Tiu (ATiu /at/ ntu /dot/ edu /dot/ sg) and
Yang Liu (yangliu /at/ ntu /dot/ edu /dot/ sg)
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2016-10-19</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{SPARCv8-AFP,
author = {Zhe Hou and David Sanan and Alwen Tiu and Yang Liu},
title = {A formal model for the SPARCv8 ISA and a proof of non-interference for the LEON3 processor},
journal = {Archive of Formal Proofs},
month = oct,
year = 2016,
note = {\url{http://isa-afp.org/entries/SPARCv8.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
-
+ <tr><td class="datahead">Depends on:</td>
+ <td class="data"><a href="Word_Lib.html">Word_Lib</a> </td></tr>
+
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/SPARCv8/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/SPARCv8/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/SPARCv8/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-SPARCv8-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-SPARCv8-2019-06-11.tar.gz">
afp-SPARCv8-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-SPARCv8-2018-08-16.tar.gz">
afp-SPARCv8-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-SPARCv8-2017-10-10.tar.gz">
afp-SPARCv8-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-SPARCv8-2016-12-17.tar.gz">
afp-SPARCv8-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-SPARCv8-2016-10-19.tar.gz">
afp-SPARCv8-2016-10-19.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Shadow_SC_DOM.html b/web/entries/Shadow_SC_DOM.html
new file mode 100644
--- /dev/null
+++ b/web/entries/Shadow_SC_DOM.html
@@ -0,0 +1,223 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>A Formal Model of the Safely Composable Document Object Model with Shadow Roots - Archive of Formal Proofs
+</title>
+<link rel="stylesheet" type="text/css" href="../front.css">
+<link rel="icon" href="../images/favicon.ico" type="image/icon">
+<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
+<!-- MathJax for LaTeX support in abstracts -->
+<script>
+MathJax = {
+ tex: {
+ inlineMath: [['$', '$'], ['\\(', '\\)']]
+ },
+ processEscapes: true,
+ svg: {
+ fontCache: 'global'
+ }
+};
+</script>
+<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
+</head>
+
+<body class="mathjax_ignore">
+
+<table width="100%">
+<tbody>
+<tr>
+
+<!-- Navigation -->
+<td width="20%" align="center" valign="top">
+ <p>&nbsp;</p>
+ <a href="https://www.isa-afp.org/">
+ <img src="../images/isabelle.png" width="100" height="88" border=0>
+ </a>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+ <table class="nav" width="80%">
+ <tr>
+ <td class="nav" width="100%"><a href="../index.html">Home</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../about.html">About</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../submitting.html">Submission</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../updating.html">Updating Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../using.html">Using Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../search.html">Search</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../statistics.html">Statistics</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../topics.html">Index</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../download.html">Download</a></td>
+ </tr>
+ </table>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+</td>
+
+
+<!-- Content -->
+<td width="80%" valign="top">
+<div align="center">
+ <p>&nbsp;</p>
+ <h1> <font class="first">A</font>
+
+ <font class="first">F</font>ormal
+
+ <font class="first">M</font>odel
+
+ of
+
+ the
+
+ <font class="first">S</font>afely
+
+ <font class="first">C</font>omposable
+
+ <font class="first">D</font>ocument
+
+ <font class="first">O</font>bject
+
+ <font class="first">M</font>odel
+
+ with
+
+ <font class="first">S</font>hadow
+
+ <font class="first">R</font>oots
+
+</h1>
+ <p>&nbsp;</p>
+
+<table width="80%" class="data">
+<tbody>
+<tr>
+ <td class="datahead" width="20%">Title:</td>
+ <td class="data" width="80%">A Formal Model of the Safely Composable Document Object Model with Shadow Roots</td>
+</tr>
+
+<tr>
+ <td class="datahead">
+ Authors:
+ </td>
+ <td class="data">
+ Achim D. Brucker (a /dot/ brucker /at/ exeter /dot/ ac /dot/ uk) and
+ <a href="http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.Herzberg">Michael Herzberg</a>
+ </td>
+</tr>
+
+
+
+<tr>
+ <td class="datahead">Submission date:</td>
+ <td class="data">2020-09-28</td>
+</tr>
+
+<tr>
+ <td class="datahead" valign="top">Abstract:</td>
+ <td class="abstract mathjax_process">
+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.</td>
+</tr>
+
+
+<tr>
+ <td class="datahead" valign="top">BibTeX:</td>
+ <td class="formatted">
+ <pre>@article{Shadow_SC_DOM-AFP,
+ author = {Achim D. Brucker and Michael Herzberg},
+ title = {A Formal Model of the Safely Composable Document Object Model with Shadow Roots},
+ journal = {Archive of Formal Proofs},
+ month = sep,
+ year = 2020,
+ note = {\url{http://isa-afp.org/entries/Shadow_SC_DOM.html},
+ Formal proof development},
+ ISSN = {2150-914x},
+}</pre>
+ </td>
+</tr>
+
+ <tr><td class="datahead">License:</td>
+ <td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
+
+
+ <tr><td class="datahead">Depends on:</td>
+ <td class="data"><a href="Core_SC_DOM.html">Core_SC_DOM</a> </td></tr>
+
+ <tr><td class="datahead">Used by:</td>
+ <td class="data"><a href="SC_DOM_Components.html">SC_DOM_Components</a> </td></tr>
+
+
+
+ </tbody>
+</table>
+
+<p></p>
+
+<table class="links">
+ <tbody>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/Shadow_SC_DOM/outline.pdf">Proof outline</a><br>
+ <a href="../browser_info/current/AFP/Shadow_SC_DOM/document.pdf">Proof document</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/Shadow_SC_DOM/index.html">Browse theories</a>
+ </td></tr>
+ <tr>
+ <td class="links">
+ <a href="../release/afp-Shadow_SC_DOM-current.tar.gz">Download this entry</a>
+ </td>
+ </tr>
+
+
+ <tr><td class="links">Older releases:
+ None
+ </td></tr>
+
+ </tbody>
+</table>
+
+</div>
+</td>
+
+</tr>
+</tbody>
+</table>
+
+<script src="../jquery.min.js"></script>
+<script src="../script.js"></script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/web/entries/Show.html b/web/entries/Show.html
--- a/web/entries/Show.html
+++ b/web/entries/Show.html
@@ -1,242 +1,242 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Haskell's Show Class in Isabelle/HOL - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">H</font>askell's
<font class="first">S</font>how
<font class="first">C</font>lass
in
<font class="first">I</font>sabelle/HOL
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Haskell's Show Class in Isabelle/HOL</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Christian Sternagel (c /dot/ sternagel /at/ gmail /dot/ com) and
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2014-07-29</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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".</td>
</tr>
<tr>
<td class="datahead" valign="top">Change history:</td>
<td class="abstract">[2015-03-11]: Adapted development to new-style (BNF-based) datatypes.<br>
[2015-04-10]: Moved development for old-style datatypes into subdirectory
"Old_Datatype".<br></td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Show-AFP,
author = {Christian Sternagel and René Thiemann},
title = {Haskell's Show Class in Isabelle/HOL},
journal = {Archive of Formal Proofs},
month = jul,
year = 2014,
note = {\url{http://isa-afp.org/entries/Show.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE.LGPL">GNU Lesser General Public License (LGPL)</a></td></tr>
<tr><td class="datahead">Depends on:</td>
<td class="data"><a href="Deriving.html">Deriving</a> </td></tr>
<tr><td class="datahead">Used by:</td>
- <td class="data"><a href="Affine_Arithmetic.html">Affine_Arithmetic</a>, <a href="CakeML.html">CakeML</a>, <a href="CakeML_Codegen.html">CakeML_Codegen</a>, <a href="Certification_Monads.html">Certification_Monads</a>, <a href="Dict_Construction.html">Dict_Construction</a>, <a href="Monad_Memo_DP.html">Monad_Memo_DP</a>, <a href="Polynomial_Factorization.html">Polynomial_Factorization</a>, <a href="Polynomials.html">Polynomials</a>, <a href="Real_Impl.html">Real_Impl</a>, <a href="XML.html">XML</a> </td></tr>
+ <td class="data"><a href="Affine_Arithmetic.html">Affine_Arithmetic</a>, <a href="AI_Planning_Languages_Semantics.html">AI_Planning_Languages_Semantics</a>, <a href="CakeML.html">CakeML</a>, <a href="CakeML_Codegen.html">CakeML_Codegen</a>, <a href="Certification_Monads.html">Certification_Monads</a>, <a href="Dict_Construction.html">Dict_Construction</a>, <a href="Monad_Memo_DP.html">Monad_Memo_DP</a>, <a href="Polynomial_Factorization.html">Polynomial_Factorization</a>, <a href="Polynomials.html">Polynomials</a>, <a href="Real_Impl.html">Real_Impl</a>, <a href="XML.html">XML</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Show/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Show/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Show/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Show-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Show-2019-06-11.tar.gz">
afp-Show-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Show-2018-08-16.tar.gz">
afp-Show-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Show-2017-10-10.tar.gz">
afp-Show-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Show-2016-12-17.tar.gz">
afp-Show-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Show-2016-02-22.tar.gz">
afp-Show-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Show-2015-05-27.tar.gz">
afp-Show-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Show-2014-08-29.tar.gz">
afp-Show-2014-08-29.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Show-2014-08-28.tar.gz">
afp-Show-2014-08-28.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Sliding_Window_Algorithm.html b/web/entries/Sliding_Window_Algorithm.html
--- a/web/entries/Sliding_Window_Algorithm.html
+++ b/web/entries/Sliding_Window_Algorithm.html
@@ -1,216 +1,216 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">F</font>ormalization
of
an
<font class="first">A</font>lgorithm
for
<font class="first">G</font>reedily
<font class="first">C</font>omputing
<font class="first">A</font>ssociative
<font class="first">A</font>ggregations
on
<font class="first">S</font>liding
<font class="first">W</font>indows
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Lukas Heimes,
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a> and
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a> and
Joshua Schneider
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2020-04-10</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
Basin et al.'s <a
href="https://doi.org/10.1016/j.ipl.2014.09.009">sliding
window algorithm (SWA)</a> is an algorithm for combining the
elements of subsequences of a sequence with an associative operator.
It is greedy and minimizes the number of operator applications. We
formalize the algorithm and verify its functional correctness. We
extend the algorithm with additional operations and provide an
alternative interface to the slide operation that does not require the
entire input sequence.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Sliding_Window_Algorithm-AFP,
author = {Lukas Heimes and Dmitriy Traytel and Joshua Schneider},
title = {Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows},
journal = {Archive of Formal Proofs},
month = apr,
year = 2020,
note = {\url{http://isa-afp.org/entries/Sliding_Window_Algorithm.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Sliding_Window_Algorithm/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Sliding_Window_Algorithm/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Sliding_Window_Algorithm/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Sliding_Window_Algorithm-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Sliding_Window_Algorithm-2020-04-12.tar.gz">
afp-Sliding_Window_Algorithm-2020-04-12.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Sort_Encodings.html b/web/entries/Sort_Encodings.html
--- a/web/entries/Sort_Encodings.html
+++ b/web/entries/Sort_Encodings.html
@@ -1,261 +1,261 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Sound and Complete Sort Encodings for First-Order Logic - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">S</font>ound
and
<font class="first">C</font>omplete
<font class="first">S</font>ort
<font class="first">E</font>ncodings
for
<font class="first">F</font>irst-Order
<font class="first">L</font>ogic
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Sound and Complete Sort Encodings for First-Order Logic</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Jasmin Christian Blanchette (j /dot/ c /dot/ blanchette /at/ vu /dot/ nl) and
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk)
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2013-06-27</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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.
<p>
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.
<p>
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.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Sort_Encodings-AFP,
author = {Jasmin Christian Blanchette and Andrei Popescu},
title = {Sound and Complete Sort Encodings for First-Order Logic},
journal = {Archive of Formal Proofs},
month = jun,
year = 2013,
note = {\url{http://isa-afp.org/entries/Sort_Encodings.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Sort_Encodings/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Sort_Encodings/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Sort_Encodings/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Sort_Encodings-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Sort_Encodings-2019-06-11.tar.gz">
afp-Sort_Encodings-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Sort_Encodings-2018-08-16.tar.gz">
afp-Sort_Encodings-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Sort_Encodings-2017-10-10.tar.gz">
afp-Sort_Encodings-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Sort_Encodings-2016-12-17.tar.gz">
afp-Sort_Encodings-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Sort_Encodings-2016-02-22.tar.gz">
afp-Sort_Encodings-2016-02-22.tar.gz
</a>
</li>
<li>Isabelle 2015:
<a href="../release/afp-Sort_Encodings-2015-05-27.tar.gz">
afp-Sort_Encodings-2015-05-27.tar.gz
</a>
</li>
<li>Isabelle 2014:
<a href="../release/afp-Sort_Encodings-2014-08-28.tar.gz">
afp-Sort_Encodings-2014-08-28.tar.gz
</a>
</li>
<li>Isabelle 2013-2:
<a href="../release/afp-Sort_Encodings-2013-12-11.tar.gz">
afp-Sort_Encodings-2013-12-11.tar.gz
</a>
</li>
<li>Isabelle 2013-1:
<a href="../release/afp-Sort_Encodings-2013-11-17.tar.gz">
afp-Sort_Encodings-2013-11-17.tar.gz
</a>
</li>
<li>Isabelle 2013:
<a href="../release/afp-Sort_Encodings-2013-07-04.tar.gz">
afp-Sort_Encodings-2013-07-04.tar.gz
</a>
</li>
<li>Isabelle 2013:
<a href="../release/afp-Sort_Encodings-2013-07-01.tar.gz">
afp-Sort_Encodings-2013-07-01.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Syntax_Independent_Logic.html b/web/entries/Syntax_Independent_Logic.html
--- a/web/entries/Syntax_Independent_Logic.html
+++ b/web/entries/Syntax_Independent_Logic.html
@@ -1,207 +1,207 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Syntax-Independent Logic Infrastructure - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">S</font>yntax-Independent
<font class="first">L</font>ogic
<font class="first">I</font>nfrastructure
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Syntax-Independent Logic Infrastructure</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
- Andrei Popescu (a /dot/ popescu /at/ mdx /dot/ ac /dot/ uk) and
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a> and
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2020-09-16</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
We formalize a notion of logic whose terms and formulas are kept
abstract. In particular, logical connectives, substitution, free
variables, and provability are not defined, but characterized by their
general properties as locale assumptions. Based on this abstract
characterization, we develop further reusable reasoning
infrastructure. For example, we define parallel substitution (along
with proving its characterizing theorems) from single-point
substitution. Similarly, we develop a natural deduction style proof
system starting from the abstract Hilbert-style one. These one-time
efforts benefit different concrete logics satisfying our locales'
assumptions. We instantiate the syntax-independent logic
infrastructure to Robinson arithmetic (also known as Q) in the AFP
entry <a
href="https://www.isa-afp.org/entries/Robinson_Arithmetic.html">Robinson_Arithmetic</a>
and to hereditarily finite set theory in the AFP entries <a
href="https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html">Goedel_HFSet_Semantic</a>
and <a
href="https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html">Goedel_HFSet_Semanticless</a>,
which are part of our formalization of G&ouml;del's
Incompleteness Theorems described in our CADE-27 paper <a
href="https://dx.doi.org/10.1007/978-3-030-29436-6_26">A
Formally Verified Abstract Account of Gödel's Incompleteness
Theorems</a>.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Syntax_Independent_Logic-AFP,
author = {Andrei Popescu and Dmitriy Traytel},
title = {Syntax-Independent Logic Infrastructure},
journal = {Archive of Formal Proofs},
month = sep,
year = 2020,
note = {\url{http://isa-afp.org/entries/Syntax_Independent_Logic.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Used by:</td>
<td class="data"><a href="Goedel_Incompleteness.html">Goedel_Incompleteness</a>, <a href="Robinson_Arithmetic.html">Robinson_Arithmetic</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Syntax_Independent_Logic/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Syntax_Independent_Logic/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Syntax_Independent_Logic/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Syntax_Independent_Logic-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
None
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ No newline at end of file
diff --git a/web/entries/Verified_SAT_Based_AI_Planning.html b/web/entries/Verified_SAT_Based_AI_Planning.html
new file mode 100644
--- /dev/null
+++ b/web/entries/Verified_SAT_Based_AI_Planning.html
@@ -0,0 +1,194 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>Verified SAT-Based AI Planning - Archive of Formal Proofs
+</title>
+<link rel="stylesheet" type="text/css" href="../front.css">
+<link rel="icon" href="../images/favicon.ico" type="image/icon">
+<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
+<!-- MathJax for LaTeX support in abstracts -->
+<script>
+MathJax = {
+ tex: {
+ inlineMath: [['$', '$'], ['\\(', '\\)']]
+ },
+ processEscapes: true,
+ svg: {
+ fontCache: 'global'
+ }
+};
+</script>
+<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
+</head>
+
+<body class="mathjax_ignore">
+
+<table width="100%">
+<tbody>
+<tr>
+
+<!-- Navigation -->
+<td width="20%" align="center" valign="top">
+ <p>&nbsp;</p>
+ <a href="https://www.isa-afp.org/">
+ <img src="../images/isabelle.png" width="100" height="88" border=0>
+ </a>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+ <table class="nav" width="80%">
+ <tr>
+ <td class="nav" width="100%"><a href="../index.html">Home</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../about.html">About</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../submitting.html">Submission</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../updating.html">Updating Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../using.html">Using Entries</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../search.html">Search</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../statistics.html">Statistics</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../topics.html">Index</a></td>
+ </tr>
+ <tr>
+ <td class="nav"><a href="../download.html">Download</a></td>
+ </tr>
+ </table>
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+</td>
+
+
+<!-- Content -->
+<td width="80%" valign="top">
+<div align="center">
+ <p>&nbsp;</p>
+ <h1> <font class="first">V</font>erified
+
+ <font class="first">S</font>AT-Based
+
+ <font class="first">A</font>I
+
+ <font class="first">P</font>lanning
+
+</h1>
+ <p>&nbsp;</p>
+
+<table width="80%" class="data">
+<tbody>
+<tr>
+ <td class="datahead" width="20%">Title:</td>
+ <td class="data" width="80%">Verified SAT-Based AI Planning</td>
+</tr>
+
+<tr>
+ <td class="datahead">
+ Authors:
+ </td>
+ <td class="data">
+ <a href="http://home.in.tum.de/~mansour/">Mohammad Abdulaziz</a> and
+ Friedrich Kurz
+ </td>
+</tr>
+
+
+
+<tr>
+ <td class="datahead">Submission date:</td>
+ <td class="data">2020-10-29</td>
+</tr>
+
+<tr>
+ <td class="datahead" valign="top">Abstract:</td>
+ <td class="abstract mathjax_process">
+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.</td>
+</tr>
+
+
+<tr>
+ <td class="datahead" valign="top">BibTeX:</td>
+ <td class="formatted">
+ <pre>@article{Verified_SAT_Based_AI_Planning-AFP,
+ author = {Mohammad Abdulaziz and Friedrich Kurz},
+ title = {Verified SAT-Based AI Planning},
+ journal = {Archive of Formal Proofs},
+ month = oct,
+ year = 2020,
+ note = {\url{http://isa-afp.org/entries/Verified_SAT_Based_AI_Planning.html},
+ Formal proof development},
+ ISSN = {2150-914x},
+}</pre>
+ </td>
+</tr>
+
+ <tr><td class="datahead">License:</td>
+ <td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
+
+
+ <tr><td class="datahead">Depends on:</td>
+ <td class="data"><a href="AI_Planning_Languages_Semantics.html">AI_Planning_Languages_Semantics</a>, <a href="List-Index.html">List-Index</a>, <a href="Propositional_Proof_Systems.html">Propositional_Proof_Systems</a> </td></tr>
+
+
+
+
+ </tbody>
+</table>
+
+<p></p>
+
+<table class="links">
+ <tbody>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/Verified_SAT_Based_AI_Planning/outline.pdf">Proof outline</a><br>
+ <a href="../browser_info/current/AFP/Verified_SAT_Based_AI_Planning/document.pdf">Proof document</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="links">
+ <a href="../browser_info/current/AFP/Verified_SAT_Based_AI_Planning/index.html">Browse theories</a>
+ </td></tr>
+ <tr>
+ <td class="links">
+ <a href="../release/afp-Verified_SAT_Based_AI_Planning-current.tar.gz">Download this entry</a>
+ </td>
+ </tr>
+
+
+ <tr><td class="links">Older releases:
+ None
+ </td></tr>
+
+ </tbody>
+</table>
+
+</div>
+</td>
+
+</tr>
+</tbody>
+</table>
+
+<script src="../jquery.min.js"></script>
+<script src="../script.js"></script>
+
+</body>
+</html>
\ No newline at end of file
diff --git a/web/entries/Word_Lib.html b/web/entries/Word_Lib.html
--- a/web/entries/Word_Lib.html
+++ b/web/entries/Word_Lib.html
@@ -1,226 +1,226 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Finite Machine Word Library - Archive of Formal Proofs
</title>
<link rel="stylesheet" type="text/css" href="../front.css">
<link rel="icon" href="../images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="../rss.xml">
<!-- MathJax for LaTeX support in abstracts -->
<script>
MathJax = {
tex: {
inlineMath: [['$', '$'], ['\\(', '\\)']]
},
processEscapes: true,
svg: {
fontCache: 'global'
}
};
</script>
<script id="MathJax-script" async src="../components/mathjax/es5/tex-mml-chtml.js"></script>
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="../images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="../index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="../about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="../submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="../updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="../search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="../statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="../topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="../download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1> <font class="first">F</font>inite
<font class="first">M</font>achine
<font class="first">W</font>ord
<font class="first">L</font>ibrary
</h1>
<p>&nbsp;</p>
<table width="80%" class="data">
<tbody>
<tr>
<td class="datahead" width="20%">Title:</td>
<td class="data" width="80%">Finite Machine Word Library</td>
</tr>
<tr>
<td class="datahead">
Authors:
</td>
<td class="data">
Joel Beeren,
Matthew Fernandez,
Xin Gao,
<a href="http://www.cse.unsw.edu.au/~kleing/">Gerwin Klein</a>,
Rafal Kolanski,
Japheth Lim,
Corey Lewis,
Daniel Matichuk and
Thomas Sewell
</td>
</tr>
<tr>
<td class="datahead">Submission date:</td>
<td class="data">2016-06-09</td>
</tr>
<tr>
<td class="datahead" valign="top">Abstract:</td>
<td class="abstract mathjax_process">
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.</td>
</tr>
<tr>
<td class="datahead" valign="top">BibTeX:</td>
<td class="formatted">
<pre>@article{Word_Lib-AFP,
author = {Joel Beeren and Matthew Fernandez and Xin Gao and Gerwin Klein and Rafal Kolanski and Japheth Lim and Corey Lewis and Daniel Matichuk and Thomas Sewell},
title = {Finite Machine Word Library},
journal = {Archive of Formal Proofs},
month = jun,
year = 2016,
note = {\url{http://isa-afp.org/entries/Word_Lib.html},
Formal proof development},
ISSN = {2150-914x},
}</pre>
</td>
</tr>
<tr><td class="datahead">License:</td>
<td class="data"><a href="http://isa-afp.org/LICENSE">BSD License</a></td></tr>
<tr><td class="datahead">Used by:</td>
- <td class="data"><a href="Complx.html">Complx</a>, <a href="IEEE_Floating_Point.html">IEEE_Floating_Point</a>, <a href="Interval_Arithmetic_Word32.html">Interval_Arithmetic_Word32</a>, <a href="IP_Addresses.html">IP_Addresses</a> </td></tr>
+ <td class="data"><a href="Complx.html">Complx</a>, <a href="IEEE_Floating_Point.html">IEEE_Floating_Point</a>, <a href="Interval_Arithmetic_Word32.html">Interval_Arithmetic_Word32</a>, <a href="IP_Addresses.html">IP_Addresses</a>, <a href="Native_Word.html">Native_Word</a>, <a href="SPARCv8.html">SPARCv8</a> </td></tr>
</tbody>
</table>
<p></p>
<table class="links">
<tbody>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Word_Lib/outline.pdf">Proof outline</a><br>
<a href="../browser_info/current/AFP/Word_Lib/document.pdf">Proof document</a>
</td>
</tr>
<tr>
<td class="links">
<a href="../browser_info/current/AFP/Word_Lib/index.html">Browse theories</a>
</td></tr>
<tr>
<td class="links">
<a href="../release/afp-Word_Lib-current.tar.gz">Download this entry</a>
</td>
</tr>
<tr><td class="links">Older releases:
<ul>
<li>Isabelle 2019:
<a href="../release/afp-Word_Lib-2019-06-11.tar.gz">
afp-Word_Lib-2019-06-11.tar.gz
</a>
</li>
<li>Isabelle 2018:
<a href="../release/afp-Word_Lib-2018-08-16.tar.gz">
afp-Word_Lib-2018-08-16.tar.gz
</a>
</li>
<li>Isabelle 2017:
<a href="../release/afp-Word_Lib-2017-10-10.tar.gz">
afp-Word_Lib-2017-10-10.tar.gz
</a>
</li>
<li>Isabelle 2016-1:
<a href="../release/afp-Word_Lib-2016-12-17.tar.gz">
afp-Word_Lib-2016-12-17.tar.gz
</a>
</li>
<li>Isabelle 2016:
<a href="../release/afp-Word_Lib-2016-06-09.tar.gz">
afp-Word_Lib-2016-06-09.tar.gz
</a>
</li>
</ul>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="../jquery.min.js"></script>
<script src="../script.js"></script>
</body>
</html>
\ 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,5150 +1,5204 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Archive of Formal Proofs</title>
<link rel="stylesheet" type="text/css" href="front.css">
<link rel="icon" href="images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="rss.xml">
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1><font class="first">A</font>rchive of
<font class="first">F</font>ormal
<font class="first">P</font>roofs</h1>
</h1>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td>
The Archive of Formal Proofs is a collection of proof libraries, examples, and larger scientific developments,
mechanically checked in the theorem prover <a href="http://isabelle.in.tum.de/">Isabelle</a>. It is organized in the way
of a scientific journal, is indexed by <a href="http://dblp.uni-trier.de/db/journals/afp/">dblp</a> and has an ISSN:
2150-914x. Submissions are refereed. The preferred citation style is available <a href="citing.html">[here]</a>. We encourage companion AFP submissions to conference and journal publications.
<br><br>A <a href="http://devel.isa-afp.org">development version</a> of the archive is available as well. </td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2020</td>
</tr>
<tr>
<td class="entry">
+ 2020-10-29: <a href="entries/Verified_SAT_Based_AI_Planning.html">Verified SAT-Based AI Planning</a>
+ <br>
+ Authors:
+ <a href="http://home.in.tum.de/~mansour/">Mohammad Abdulaziz</a>
+ and Friedrich Kurz
+ </td>
+ </tr>
+ <tr>
+ <td class="entry">
+ 2020-10-29: <a href="entries/AI_Planning_Languages_Semantics.html">AI Planning Languages Semantics</a>
+ <br>
+ Authors:
+ <a href="http://home.in.tum.de/~mansour/">Mohammad Abdulaziz</a>
+ and Peter Lammich
+ </td>
+ </tr>
+ <tr>
+ <td class="entry">
+ 2020-10-20: <a href="entries/Physical_Quantities.html">A Sound Type System for Physical Quantities, Units, and Measurements</a>
+ <br>
+ Authors:
+ <a href="https://www-users.cs.york.ac.uk/~simonf/">Simon Foster</a>
+ and <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="entry">
+ 2020-09-28: <a href="entries/Shadow_SC_DOM.html">A Formal Model of the Safely Composable Document Object Model with Shadow Roots</a>
+ <br>
+ Authors:
+ Achim D. Brucker
+ and <a href="http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.Herzberg">Michael Herzberg</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="entry">
+ 2020-09-28: <a href="entries/SC_DOM_Components.html">A Formalization of Safely Composable Web Components</a>
+ <br>
+ Authors:
+ Achim D. Brucker
+ and <a href="http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.Herzberg">Michael Herzberg</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="entry">
+ 2020-09-28: <a href="entries/Core_SC_DOM.html">The Safely Composable DOM</a>
+ <br>
+ Authors:
+ Achim D. Brucker
+ and <a href="http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.Herzberg">Michael Herzberg</a>
+ </td>
+ </tr>
+ <tr>
+ <td class="entry">
2020-09-16: <a href="entries/Syntax_Independent_Logic.html">Syntax-Independent Logic Infrastructure</a>
<br>
Authors:
- Andrei Popescu
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2020-09-16: <a href="entries/Robinson_Arithmetic.html">Robinson Arithmetic</a>
<br>
Authors:
- Andrei Popescu
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2020-09-16: <a href="entries/Goedel_Incompleteness.html">An Abstract Formalization of G&ouml;del's Incompleteness Theorems</a>
<br>
Authors:
- Andrei Popescu
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2020-09-16: <a href="entries/Goedel_HFSet_Semanticless.html">From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part II</a>
<br>
Authors:
- Andrei Popescu
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2020-09-16: <a href="entries/Goedel_HFSet_Semantic.html">From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part I</a>
<br>
Authors:
- Andrei Popescu
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2020-09-07: <a href="entries/Extended_Finite_State_Machines.html">A Formal Model of Extended Finite State Machines</a>
<br>
Authors:
Michael Foster,
Achim D. Brucker,
Ramsay G. Taylor
and John Derrick
</td>
</tr>
<tr>
<td class="entry">
2020-09-07: <a href="entries/Extended_Finite_State_Machine_Inference.html">Inference of Extended Finite State Machines</a>
<br>
Authors:
Michael Foster,
Achim D. Brucker,
Ramsay G. Taylor
and John Derrick
</td>
</tr>
<tr>
<td class="entry">
2020-08-31: <a href="entries/PAC_Checker.html">Practical Algebraic Calculus Checker</a>
<br>
Authors:
<a href="http://fmv.jku.at/fleury">Mathias Fleury</a>
and <a href="http://fmv.jku.at/kaufmann">Daniela Kaufmann</a>
</td>
</tr>
<tr>
<td class="entry">
2020-08-31: <a href="entries/Inductive_Inference.html">Some classical results in inductive inference of recursive functions</a>
<br>
Author:
Frank J. Balbach
</td>
</tr>
<tr>
<td class="entry">
2020-08-26: <a href="entries/Relational_Disjoint_Set_Forests.html">Relational Disjoint-Set Forests</a>
<br>
Author:
<a href="http://www.cosc.canterbury.ac.nz/walter.guttmann/">Walter Guttmann</a>
</td>
</tr>
<tr>
<td class="entry">
2020-08-25: <a href="entries/Saturation_Framework_Extensions.html">Extensions to the Comprehensive Framework for Saturation Theorem Proving</a>
<br>
Authors:
<a href="https://www.cs.vu.nl/~jbe248/">Jasmin Blanchette</a>
and <a href="https://www.mpi-inf.mpg.de/departments/automation-of-logic/people/sophie-tourret">Sophie Tourret</a>
</td>
</tr>
<tr>
<td class="entry">
2020-08-25: <a href="entries/BirdKMP.html">Putting the `K' into Bird's derivation of Knuth-Morris-Pratt string matching</a>
<br>
Author:
<a href="http://peteg.org">Peter Gammie</a>
</td>
</tr>
<tr>
<td class="entry">
2020-08-04: <a href="entries/Amicable_Numbers.html">Amicable Numbers</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~ak2110/">Angeliki Koutsoukou-Argyraki</a>
</td>
</tr>
<tr>
<td class="entry">
2020-08-03: <a href="entries/Ordinal_Partitions.html">Ordinal Partitions</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2020-07-21: <a href="entries/Chandy_Lamport.html">A Formal Proof of The Chandy--Lamport Distributed Snapshot Algorithm</a>
<br>
Authors:
Ben Fiedler
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2020-07-13: <a href="entries/Relational_Paths.html">Relational Characterisations of Paths</a>
<br>
Authors:
<a href="http://www.cosc.canterbury.ac.nz/walter.guttmann/">Walter Guttmann</a>
and <a href="http://www.hoefner-online.de/">Peter Höfner</a>
</td>
</tr>
<tr>
<td class="entry">
2020-06-01: <a href="entries/Safe_Distance.html">A Formally Verified Checker of the Safe Distance Traffic Rules for Autonomous Vehicles</a>
<br>
Authors:
Albert Rizaldi
and <a href="http://home.in.tum.de/~immler/">Fabian Immler</a>
</td>
</tr>
<tr>
<td class="entry">
2020-05-23: <a href="entries/Smith_Normal_Form.html">A verified algorithm for computing the Smith normal form of a matrix</a>
<br>
Author:
<a href="https://www.unirioja.es/cu/jodivaso/">Jose Divasón</a>
</td>
</tr>
<tr>
<td class="entry">
2020-05-16: <a href="entries/Nash_Williams.html">The Nash-Williams Partition Theorem</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2020-05-13: <a href="entries/Knuth_Bendix_Order.html">A Formalization of Knuth–Bendix Orders</a>
<br>
Authors:
Christian Sternagel
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2020-05-12: <a href="entries/Irrational_Series_Erdos_Straus.html">Irrationality Criteria for Series by Erdős and Straus</a>
<br>
Authors:
<a href="https://www.cl.cam.ac.uk/~ak2110/">Angeliki Koutsoukou-Argyraki</a>
and <a href="https://www.cl.cam.ac.uk/~wl302/">Wenda Li</a>
</td>
</tr>
<tr>
<td class="entry">
2020-05-11: <a href="entries/Recursion-Addition.html">Recursion Theorem in ZF</a>
<br>
Author:
Georgy Dunaev
</td>
</tr>
<tr>
<td class="entry">
2020-05-08: <a href="entries/LTL_Normal_Form.html">An Efficient Normalisation Procedure for Linear Temporal Logic: Isabelle/HOL Formalisation</a>
<br>
Author:
Salomon Sickert
</td>
</tr>
<tr>
<td class="entry">
2020-05-06: <a href="entries/Forcing.html">Formalization of Forcing in Isabelle/ZF</a>
<br>
Authors:
Emmanuel Gunther,
<a href="https://cs.famaf.unc.edu.ar/~mpagano/">Miguel Pagano</a>
and <a href="https://cs.famaf.unc.edu.ar/~pedro/home_en">Pedro Sánchez Terraf</a>
</td>
</tr>
<tr>
<td class="entry">
2020-05-02: <a href="entries/Banach_Steinhaus.html">Banach-Steinhaus Theorem</a>
<br>
Authors:
<a href="http://kodu.ut.ee/~unruh/">Dominique Unruh</a>
and <a href="https://josephcmac.github.io/">Jose Manuel Rodriguez Caballero</a>
</td>
</tr>
<tr>
<td class="entry">
2020-04-27: <a href="entries/Attack_Trees.html">Attack Trees in Isabelle for GDPR compliance of IoT healthcare systems</a>
<br>
Author:
<a href="http://www.cs.mdx.ac.uk/people/florian-kammueller/">Florian Kammueller</a>
</td>
</tr>
<tr>
<td class="entry">
2020-04-24: <a href="entries/Power_Sum_Polynomials.html">Power Sum Polynomials</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2020-04-24: <a href="entries/Lambert_W.html">The Lambert W Function on the Reals</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2020-04-24: <a href="entries/Gaussian_Integers.html">Gaussian Integers</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2020-04-19: <a href="entries/Matrices_for_ODEs.html">Matrices for ODEs</a>
<br>
Author:
Jonathan Julian Huerta y Munive
</td>
</tr>
<tr>
<td class="entry">
2020-04-16: <a href="entries/ADS_Functor.html">Authenticated Data Structures As Functors</a>
<br>
Authors:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
and Ognjen Marić
</td>
</tr>
<tr>
<td class="entry">
2020-04-10: <a href="entries/Sliding_Window_Algorithm.html">Formalization of an Algorithm for Greedily Computing Associative Aggregations on Sliding Windows</a>
<br>
Authors:
Lukas Heimes,
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
and Joshua Schneider
</td>
</tr>
<tr>
<td class="entry">
2020-04-09: <a href="entries/Saturation_Framework.html">A Comprehensive Framework for Saturation Theorem Proving</a>
<br>
Author:
<a href="https://www.mpi-inf.mpg.de/departments/automation-of-logic/people/sophie-tourret">Sophie Tourret</a>
</td>
</tr>
<tr>
<td class="entry">
2020-04-09: <a href="entries/MFODL_Monitor_Optimized.html">Formalization of an Optimized Monitoring Algorithm for Metric First-Order Dynamic Logic with Aggregations</a>
<br>
Authors:
Thibault Dardinier,
Lukas Heimes,
Martin Raszyk,
Joshua Schneider
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2020-04-08: <a href="entries/Stateful_Protocol_Composition_and_Typing.html">Stateful Protocol Composition and Typing</a>
<br>
Authors:
Andreas V. Hess,
<a href="https://people.compute.dtu.dk/samo/">Sebastian Mödersheim</a>
and Achim D. Brucker
</td>
</tr>
<tr>
<td class="entry">
2020-04-08: <a href="entries/Automated_Stateful_Protocol_Verification.html">Automated Stateful Protocol Verification</a>
<br>
Authors:
Andreas V. Hess,
<a href="https://people.compute.dtu.dk/samo/">Sebastian Mödersheim</a>,
Achim D. Brucker
and <a href="https://people.compute.dtu.dk/andschl/">Anders Schlichtkrull</a>
</td>
</tr>
<tr>
<td class="entry">
2020-04-07: <a href="entries/Lucas_Theorem.html">Lucas's Theorem</a>
<br>
Author:
Chelsea Edmonds
</td>
</tr>
<tr>
<td class="entry">
2020-03-25: <a href="entries/WOOT_Strong_Eventual_Consistency.html">Strong Eventual Consistency of the Collaborative Editing Framework WOOT</a>
<br>
Authors:
<a href="https://orcid.org/0000-0003-3290-5034">Emin Karayel</a>
and Edgar Gonzàlez
</td>
</tr>
<tr>
<td class="entry">
2020-03-22: <a href="entries/Furstenberg_Topology.html">Furstenberg's topology and his proof of the infinitude of primes</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2020-03-12: <a href="entries/Relational-Incorrectness-Logic.html">An Under-Approximate Relational Logic</a>
<br>
Author:
<a href="https://people.eng.unimelb.edu.au/tobym/">Toby Murray</a>
</td>
</tr>
<tr>
<td class="entry">
2020-03-07: <a href="entries/Hello_World.html">Hello World</a>
<br>
Authors:
<a href="http://net.in.tum.de/~diekmann">Cornelius Diekmann</a>
and <a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
</td>
</tr>
<tr>
<td class="entry">
2020-02-21: <a href="entries/Goodstein_Lambda.html">Implementing the Goodstein Function in &lambda;-Calculus</a>
<br>
Author:
Bertram Felgenhauer
</td>
</tr>
<tr>
<td class="entry">
2020-02-10: <a href="entries/VeriComp.html">A Generic Framework for Verified Compilers</a>
<br>
Author:
<a href="https://martin.desharnais.me">Martin Desharnais</a>
</td>
</tr>
<tr>
<td class="entry">
2020-02-01: <a href="entries/Arith_Prog_Rel_Primes.html">Arithmetic progressions and relative primes</a>
<br>
Author:
<a href="https://josephcmac.github.io/">José Manuel Rodríguez Caballero</a>
</td>
</tr>
<tr>
<td class="entry">
2020-01-31: <a href="entries/Subset_Boolean_Algebras.html">A Hierarchy of Algebras for Boolean Subsets</a>
<br>
Authors:
<a href="http://www.cosc.canterbury.ac.nz/walter.guttmann/">Walter Guttmann</a>
and <a href="https://www.informatik.uni-augsburg.de/en/chairs/dbis/pmi/staff/moeller/">Bernhard Möller</a>
</td>
</tr>
<tr>
<td class="entry">
2020-01-17: <a href="entries/Mersenne_Primes.html">Mersenne primes and the Lucas–Lehmer test</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2020-01-16: <a href="entries/Approximation_Algorithms.html">Verified Approximation Algorithms</a>
<br>
Authors:
Robin Eßmann,
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
and <a href="https://simon-robillard.net/">Simon Robillard</a>
</td>
</tr>
<tr>
<td class="entry">
2020-01-13: <a href="entries/Closest_Pair_Points.html">Closest Pair of Points Algorithms</a>
<br>
Authors:
Martin Rau
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2020-01-09: <a href="entries/Skip_Lists.html">Skip Lists</a>
<br>
Authors:
<a href="http://cl-informatik.uibk.ac.at/users/mhaslbeck/">Max W. Haslbeck</a>
and <a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2020-01-06: <a href="entries/Bicategory.html">Bicategories</a>
<br>
Author:
Eugene W. Stark
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2019</td>
</tr>
<tr>
<td class="entry">
2019-12-27: <a href="entries/Zeta_3_Irrational.html">The Irrationality of ζ(3)</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2019-12-20: <a href="entries/Hybrid_Logic.html">Formalizing a Seligman-Style Tableau System for Hybrid Logic</a>
<br>
Author:
<a href="https://people.compute.dtu.dk/ahfrom/">Asta Halkjær From</a>
</td>
</tr>
<tr>
<td class="entry">
2019-12-18: <a href="entries/Poincare_Bendixson.html">The Poincaré-Bendixson Theorem</a>
<br>
Authors:
<a href="http://home.in.tum.de/~immler/">Fabian Immler</a>
and <a href="https://www.cs.cmu.edu/~yongkiat/">Yong Kiam Tan</a>
</td>
</tr>
<tr>
<td class="entry">
2019-12-16: <a href="entries/Poincare_Disc.html">Poincaré Disc Model</a>
<br>
Authors:
<a href="http://poincare.matf.bg.ac.rs/~danijela">Danijela Simić</a>,
Filip Marić
and Pierre Boutry
</td>
</tr>
<tr>
<td class="entry">
2019-12-16: <a href="entries/Complex_Geometry.html">Complex Geometry</a>
<br>
Authors:
Filip Marić
and <a href="http://poincare.matf.bg.ac.rs/~danijela">Danijela Simić</a>
</td>
</tr>
<tr>
<td class="entry">
2019-12-10: <a href="entries/Gauss_Sums.html">Gauss Sums and the Pólya–Vinogradov Inequality</a>
<br>
Authors:
<a href="https://people.epfl.ch/rodrigo.raya">Rodrigo Raya</a>
and <a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2019-12-04: <a href="entries/Generalized_Counting_Sort.html">An Efficient Generalization of Counting Sort for Large, possibly Infinite Key Ranges</a>
<br>
Author:
Pasquale Noce
</td>
</tr>
<tr>
<td class="entry">
2019-11-27: <a href="entries/Interval_Arithmetic_Word32.html">Interval Arithmetic on 32-bit Words</a>
<br>
Author:
Brandon Bohrer
</td>
</tr>
<tr>
<td class="entry">
2019-10-24: <a href="entries/ZFC_in_HOL.html">Zermelo Fraenkel Set Theory in Higher-Order Logic</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2019-10-22: <a href="entries/Isabelle_C.html">Isabelle/C</a>
<br>
Authors:
<a href="https://www.lri.fr/~ftuong/">Frédéric Tuong</a>
and <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
</td>
</tr>
<tr>
<td class="entry">
2019-10-16: <a href="entries/VerifyThis2019.html">VerifyThis 2019 -- Polished Isabelle Solutions</a>
<br>
Authors:
Peter Lammich
and <a href="http://home.in.tum.de/~wimmers/">Simon Wimmer</a>
</td>
</tr>
<tr>
<td class="entry">
2019-10-08: <a href="entries/Aristotles_Assertoric_Syllogistic.html">Aristotle's Assertoric Syllogistic</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~ak2110/">Angeliki Koutsoukou-Argyraki</a>
</td>
</tr>
<tr>
<td class="entry">
2019-10-07: <a href="entries/Sigma_Commit_Crypto.html">Sigma Protocols and Commitment Schemes</a>
<br>
Authors:
<a href="https://www.turing.ac.uk/people/doctoral-students/david-butler">David Butler</a>
and <a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="entry">
2019-10-04: <a href="entries/Clean.html">Clean - An Abstract Imperative Programming Language and its Theory</a>
<br>
Authors:
<a href="https://www.lri.fr/~ftuong/">Frédéric Tuong</a>
and <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
</td>
</tr>
<tr>
<td class="entry">
2019-09-16: <a href="entries/Generic_Join.html">Formalization of Multiway-Join Algorithms</a>
<br>
Author:
Thibault Dardinier
</td>
</tr>
<tr>
<td class="entry">
2019-09-10: <a href="entries/Hybrid_Systems_VCs.html">Verification Components for Hybrid Systems</a>
<br>
Author:
Jonathan Julian Huerta y Munive
</td>
</tr>
<tr>
<td class="entry">
2019-09-06: <a href="entries/Fourier.html">Fourier Series</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2019-08-30: <a href="entries/Jacobson_Basic_Algebra.html">A Case Study in Basic Algebra</a>
<br>
Author:
<a href="http://www21.in.tum.de/~ballarin/">Clemens Ballarin</a>
</td>
</tr>
<tr>
<td class="entry">
2019-08-16: <a href="entries/Adaptive_State_Counting.html">Formalisation of an Adaptive State Counting Algorithm</a>
<br>
Author:
Robert Sachtleben
</td>
</tr>
<tr>
<td class="entry">
2019-08-14: <a href="entries/Laplace_Transform.html">Laplace Transform</a>
<br>
Author:
<a href="http://home.in.tum.de/~immler/">Fabian Immler</a>
</td>
</tr>
<tr>
<td class="entry">
2019-08-06: <a href="entries/Linear_Programming.html">Linear Programming</a>
<br>
Authors:
<a href="http://www.parsert.com/">Julian Parsert</a>
and <a href="http://cl-informatik.uibk.ac.at/cek/">Cezary Kaliszyk</a>
</td>
</tr>
<tr>
<td class="entry">
2019-08-06: <a href="entries/C2KA_DistributedSystems.html">Communicating Concurrent Kleene Algebra for Distributed Systems Specification</a>
<br>
Authors:
Maxime Buyse
and <a href="https://carleton.ca/jaskolka/">Jason Jaskolka</a>
</td>
</tr>
<tr>
<td class="entry">
2019-08-05: <a href="entries/IMO2019.html">Selected Problems from the International Mathematical Olympiad 2019</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2019-08-01: <a href="entries/Stellar_Quorums.html">Stellar Quorum Systems</a>
<br>
Author:
Giuliano Losa
</td>
</tr>
<tr>
<td class="entry">
2019-07-30: <a href="entries/TESL_Language.html">A Formal Development of a Polychronous Polytimed Coordination Language</a>
<br>
Authors:
Hai Nguyen Van,
Frédéric Boulanger
and <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
</td>
</tr>
<tr>
<td class="entry">
2019-07-27: <a href="entries/Szpilrajn.html">Szpilrajn Extension Theorem</a>
<br>
Author:
Peter Zeller
</td>
</tr>
<tr>
<td class="entry">
2019-07-18: <a href="entries/FOL_Seq_Calc1.html">A Sequent Calculus for First-Order Logic</a>
<br>
Author:
<a href="https://people.compute.dtu.dk/ahfrom/">Asta Halkjær From</a>
</td>
</tr>
<tr>
<td class="entry">
2019-07-08: <a href="entries/CakeML_Codegen.html">A Verified Code Generator from Isabelle/HOL to CakeML</a>
<br>
Author:
<a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
</td>
</tr>
<tr>
<td class="entry">
2019-07-04: <a href="entries/MFOTL_Monitor.html">Formalization of a Monitoring Algorithm for Metric First-Order Temporal Logic</a>
<br>
Authors:
Joshua Schneider
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2019-06-27: <a href="entries/Complete_Non_Orders.html">Complete Non-Orders and Fixed Points</a>
<br>
Authors:
<a href="http://group-mmm.org/~ayamada/">Akihisa Yamada</a>
and <a href="http://group-mmm.org/~dubut/">Jérémy Dubut</a>
</td>
</tr>
<tr>
<td class="entry">
2019-06-25: <a href="entries/Priority_Search_Trees.html">Priority Search Trees</a>
<br>
Authors:
Peter Lammich
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2019-06-25: <a href="entries/Prim_Dijkstra_Simple.html">Purely Functional, Simple, and Efficient Implementation of Prim and Dijkstra</a>
<br>
Authors:
Peter Lammich
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2019-06-21: <a href="entries/Linear_Inequalities.html">Linear Inequalities</a>
<br>
Authors:
<a href="http://cl-informatik.uibk.ac.at/users/bottesch/">Ralph Bottesch</a>,
Alban Reynaud
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2019-06-16: <a href="entries/Nullstellensatz.html">Hilbert's Nullstellensatz</a>
<br>
Author:
<a href="https://risc.jku.at/m/alexander-maletzky/">Alexander Maletzky</a>
</td>
</tr>
<tr>
<td class="entry">
2019-06-15: <a href="entries/Groebner_Macaulay.html">Gröbner Bases, Macaulay Matrices and Dubé's Degree Bounds</a>
<br>
Author:
<a href="https://risc.jku.at/m/alexander-maletzky/">Alexander Maletzky</a>
</td>
</tr>
<tr>
<td class="entry">
2019-06-13: <a href="entries/IMP2_Binary_Heap.html">Binary Heaps for IMP2</a>
<br>
Author:
Simon Griebel
</td>
</tr>
<tr>
<td class="entry">
2019-06-03: <a href="entries/Differential_Game_Logic.html">Differential Game Logic</a>
<br>
Author:
<a href="http://www.cs.cmu.edu/~aplatzer/">André Platzer</a>
</td>
</tr>
<tr>
<td class="entry">
2019-05-30: <a href="entries/KD_Tree.html">Multidimensional Binary Search Trees</a>
<br>
Author:
Martin Rau
</td>
</tr>
<tr>
<td class="entry">
2019-05-14: <a href="entries/LambdaAuth.html">Formalization of Generic Authenticated Data Structures</a>
<br>
Authors:
Matthias Brun
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2019-05-09: <a href="entries/Multi_Party_Computation.html">Multi-Party Computation</a>
<br>
Authors:
<a href="http://homepages.inf.ed.ac.uk/da/">David Aspinall</a>
and <a href="https://www.turing.ac.uk/people/doctoral-students/david-butler">David Butler</a>
</td>
</tr>
<tr>
<td class="entry">
2019-04-26: <a href="entries/HOL-CSP.html">HOL-CSP Version 2.0</a>
<br>
Authors:
Safouan Taha,
Lina Ye
and <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
</td>
</tr>
<tr>
<td class="entry">
2019-04-16: <a href="entries/LTL_Master_Theorem.html">A Compositional and Unified Translation of LTL into ω-Automata</a>
<br>
Authors:
Benedikt Seidl
and Salomon Sickert
</td>
</tr>
<tr>
<td class="entry">
2019-04-06: <a href="entries/Binding_Syntax_Theory.html">A General Theory of Syntax with Bindings</a>
<br>
Authors:
Lorenzo Gheri
- and Andrei Popescu
+ and <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
</td>
</tr>
<tr>
<td class="entry">
2019-03-27: <a href="entries/Transcendence_Series_Hancl_Rucki.html">The Transcendence of Certain Infinite Series</a>
<br>
Authors:
<a href="https://www.cl.cam.ac.uk/~ak2110/">Angeliki Koutsoukou-Argyraki</a>
and <a href="https://www.cl.cam.ac.uk/~wl302/">Wenda Li</a>
</td>
</tr>
<tr>
<td class="entry">
2019-03-24: <a href="entries/QHLProver.html">Quantum Hoare Logic</a>
<br>
Authors:
Junyi Liu,
<a href="http://lcs.ios.ac.cn/~bzhan/">Bohua Zhan</a>,
Shuling Wang,
Shenggang Ying,
Tao Liu,
Yangjia Li,
Mingsheng Ying
and Naijun Zhan
</td>
</tr>
<tr>
<td class="entry">
2019-03-09: <a href="entries/Safe_OCL.html">Safe OCL</a>
<br>
Author:
Denis Nikiforov
</td>
</tr>
<tr>
<td class="entry">
2019-02-21: <a href="entries/Prime_Distribution_Elementary.html">Elementary Facts About the Distribution of Primes</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2019-02-14: <a href="entries/Kruskal.html">Kruskal's Algorithm for Minimum Spanning Forest</a>
<br>
Authors:
<a href="http://in.tum.de/~haslbema/">Maximilian P.L. Haslbeck</a>,
Peter Lammich
and Julian Biendarra
</td>
</tr>
<tr>
<td class="entry">
2019-02-11: <a href="entries/Probabilistic_Prime_Tests.html">Probabilistic Primality Testing</a>
<br>
Authors:
Daniel Stüwe
and <a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2019-02-08: <a href="entries/Universal_Turing_Machine.html">Universal Turing Machine</a>
<br>
Authors:
Jian Xu,
Xingyuan Zhang,
<a href="http://www.inf.kcl.ac.uk/staff/urbanc/">Christian Urban</a>
and Sebastiaan J. C. Joosten
</td>
</tr>
<tr>
<td class="entry">
2019-02-01: <a href="entries/UTP.html">Isabelle/UTP: Mechanised Theory Engineering for Unifying Theories of Programming</a>
<br>
Authors:
<a href="https://www-users.cs.york.ac.uk/~simonf/">Simon Foster</a>,
Frank Zeyda,
Yakoub Nemouchi,
Pedro Ribeiro
and <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
</td>
</tr>
<tr>
<td class="entry">
2019-02-01: <a href="entries/List_Inversions.html">The Inversions of a List</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2019-01-17: <a href="entries/Farkas.html">Farkas' Lemma and Motzkin's Transposition Theorem</a>
<br>
Authors:
<a href="http://cl-informatik.uibk.ac.at/users/bottesch/">Ralph Bottesch</a>,
<a href="http://cl-informatik.uibk.ac.at/users/mhaslbeck/">Max W. Haslbeck</a>
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2019-01-15: <a href="entries/IMP2.html">IMP2 – Simple Program Verification in Isabelle/HOL</a>
<br>
Authors:
Peter Lammich
and <a href="http://home.in.tum.de/~wimmers/">Simon Wimmer</a>
</td>
</tr>
<tr>
<td class="entry">
2019-01-15: <a href="entries/Higher_Order_Terms.html">An Algebra for Higher-Order Terms</a>
<br>
Author:
<a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
</td>
</tr>
<tr>
<td class="entry">
2019-01-07: <a href="entries/Store_Buffer_Reduction.html">A Reduction Theorem for Store Buffers</a>
<br>
Authors:
Ernie Cohen
and Norbert Schirmer
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2018</td>
</tr>
<tr>
<td class="entry">
2018-12-26: <a href="entries/Core_DOM.html">A Formal Model of the Document Object Model</a>
<br>
Authors:
Achim D. Brucker
and <a href="http://www.dcs.shef.ac.uk/cgi-bin/makeperson?M.Herzberg">Michael Herzberg</a>
</td>
</tr>
<tr>
<td class="entry">
2018-12-25: <a href="entries/Concurrent_Revisions.html">Formalization of Concurrent Revisions</a>
<br>
Author:
Roy Overbeek
</td>
</tr>
<tr>
<td class="entry">
2018-12-21: <a href="entries/Auto2_Imperative_HOL.html">Verifying Imperative Programs using Auto2</a>
<br>
Author:
<a href="http://lcs.ios.ac.cn/~bzhan/">Bohua Zhan</a>
</td>
</tr>
<tr>
<td class="entry">
2018-12-17: <a href="entries/Constructive_Cryptography.html">Constructive Cryptography in HOL</a>
<br>
Authors:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
and S. Reza Sefidgar
</td>
</tr>
<tr>
<td class="entry">
2018-12-11: <a href="entries/Transformer_Semantics.html">Transformer Semantics</a>
<br>
Author:
<a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
</td>
</tr>
<tr>
<td class="entry">
2018-12-11: <a href="entries/Quantales.html">Quantales</a>
<br>
Author:
<a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
</td>
</tr>
<tr>
<td class="entry">
2018-12-11: <a href="entries/Order_Lattice_Props.html">Properties of Orderings and Lattices</a>
<br>
Author:
<a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
</td>
</tr>
<tr>
<td class="entry">
2018-11-23: <a href="entries/Graph_Saturation.html">Graph Saturation</a>
<br>
Author:
Sebastiaan J. C. Joosten
</td>
</tr>
<tr>
<td class="entry">
2018-11-23: <a href="entries/Functional_Ordered_Resolution_Prover.html">A Verified Functional Implementation of Bachmair and Ganzinger's Ordered Resolution Prover</a>
<br>
Authors:
<a href="https://people.compute.dtu.dk/andschl/">Anders Schlichtkrull</a>,
Jasmin Christian Blanchette
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2018-11-20: <a href="entries/Auto2_HOL.html">Auto2 Prover</a>
<br>
Author:
<a href="http://lcs.ios.ac.cn/~bzhan/">Bohua Zhan</a>
</td>
</tr>
<tr>
<td class="entry">
2018-11-16: <a href="entries/Matroids.html">Matroids</a>
<br>
Author:
Jonas Keinholz
</td>
</tr>
<tr>
<td class="entry">
2018-11-06: <a href="entries/Generic_Deriving.html">Deriving generic class instances for datatypes</a>
<br>
Authors:
Jonas Rädle
and <a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
</td>
</tr>
<tr>
<td class="entry">
2018-10-30: <a href="entries/GewirthPGCProof.html">Formalisation and Evaluation of Alan Gewirth's Proof for the Principle of Generic Consistency in Isabelle/HOL</a>
<br>
Authors:
David Fuenmayor
and <a href="http://christoph-benzmueller.de">Christoph Benzmüller</a>
</td>
</tr>
<tr>
<td class="entry">
2018-10-29: <a href="entries/Epistemic_Logic.html">Epistemic Logic</a>
<br>
Author:
<a href="https://people.compute.dtu.dk/ahfrom/">Asta Halkjær From</a>
</td>
</tr>
<tr>
<td class="entry">
2018-10-22: <a href="entries/Smooth_Manifolds.html">Smooth Manifolds</a>
<br>
Authors:
<a href="http://home.in.tum.de/~immler/">Fabian Immler</a>
and <a href="http://lcs.ios.ac.cn/~bzhan/">Bohua Zhan</a>
</td>
</tr>
<tr>
<td class="entry">
2018-10-19: <a href="entries/Randomised_BSTs.html">Randomised Binary Search Trees</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2018-10-19: <a href="entries/Lambda_Free_EPO.html">Formalization of the Embedding Path Order for Lambda-Free Higher-Order Terms</a>
<br>
Author:
Alexander Bentkamp
</td>
</tr>
<tr>
<td class="entry">
2018-10-12: <a href="entries/Factored_Transition_System_Bounding.html">Upper Bounding Diameters of State Spaces of Factored Transition Systems</a>
<br>
Authors:
Friedrich Kurz
and <a href="http://home.in.tum.de/~mansour/">Mohammad Abdulaziz</a>
</td>
</tr>
<tr>
<td class="entry">
2018-09-28: <a href="entries/Pi_Transcendental.html">The Transcendence of π</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2018-09-25: <a href="entries/Symmetric_Polynomials.html">Symmetric Polynomials</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2018-09-20: <a href="entries/Signature_Groebner.html">Signature-Based Gröbner Basis Algorithms</a>
<br>
Author:
<a href="https://risc.jku.at/m/alexander-maletzky/">Alexander Maletzky</a>
</td>
</tr>
<tr>
<td class="entry">
2018-09-19: <a href="entries/Prime_Number_Theorem.html">The Prime Number Theorem</a>
<br>
Authors:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
and <a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2018-09-15: <a href="entries/Aggregation_Algebras.html">Aggregation Algebras</a>
<br>
Author:
<a href="http://www.cosc.canterbury.ac.nz/walter.guttmann/">Walter Guttmann</a>
</td>
</tr>
<tr>
<td class="entry">
2018-09-14: <a href="entries/Octonions.html">Octonions</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~ak2110/">Angeliki Koutsoukou-Argyraki</a>
</td>
</tr>
<tr>
<td class="entry">
2018-09-05: <a href="entries/Quaternions.html">Quaternions</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2018-09-02: <a href="entries/Budan_Fourier.html">The Budan-Fourier Theorem and Counting Real Roots with Multiplicity</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~wl302/">Wenda Li</a>
</td>
</tr>
<tr>
<td class="entry">
2018-08-24: <a href="entries/Simplex.html">An Incremental Simplex Algorithm with Unsatisfiable Core Generation</a>
<br>
Authors:
Filip Marić,
Mirko Spasić
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2018-08-14: <a href="entries/Minsky_Machines.html">Minsky Machines</a>
<br>
Author:
Bertram Felgenhauer
</td>
</tr>
<tr>
<td class="entry">
2018-07-16: <a href="entries/DiscretePricing.html">Pricing in discrete financial models</a>
<br>
Author:
<a href="http://lig-membres.imag.fr/mechenim/">Mnacho Echenim</a>
</td>
</tr>
<tr>
<td class="entry">
2018-07-04: <a href="entries/Neumann_Morgenstern_Utility.html">Von-Neumann-Morgenstern Utility Theorem</a>
<br>
Authors:
<a href="http://www.parsert.com/">Julian Parsert</a>
and <a href="http://cl-informatik.uibk.ac.at/cek/">Cezary Kaliszyk</a>
</td>
</tr>
<tr>
<td class="entry">
2018-06-23: <a href="entries/Pell.html">Pell's Equation</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2018-06-14: <a href="entries/Projective_Geometry.html">Projective Geometry</a>
<br>
Author:
<a href="https://sites.google.com/site/anthonybordg/">Anthony Bordg</a>
</td>
</tr>
<tr>
<td class="entry">
2018-06-14: <a href="entries/Localization_Ring.html">The Localization of a Commutative Ring</a>
<br>
Author:
<a href="https://sites.google.com/site/anthonybordg/">Anthony Bordg</a>
</td>
</tr>
<tr>
<td class="entry">
2018-06-05: <a href="entries/Partial_Order_Reduction.html">Partial Order Reduction</a>
<br>
Author:
<a href="http://www21.in.tum.de/~brunnerj/">Julian Brunner</a>
</td>
</tr>
<tr>
<td class="entry">
2018-05-27: <a href="entries/Optimal_BST.html">Optimal Binary Search Trees</a>
<br>
Authors:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
and Dániel Somogyi
</td>
</tr>
<tr>
<td class="entry">
2018-05-25: <a href="entries/Hidden_Markov_Models.html">Hidden Markov Models</a>
<br>
Author:
<a href="http://home.in.tum.de/~wimmers/">Simon Wimmer</a>
</td>
</tr>
<tr>
<td class="entry">
2018-05-24: <a href="entries/Probabilistic_Timed_Automata.html">Probabilistic Timed Automata</a>
<br>
Authors:
<a href="http://home.in.tum.de/~wimmers/">Simon Wimmer</a>
and <a href="http://in.tum.de/~hoelzl">Johannes Hölzl</a>
</td>
</tr>
<tr>
<td class="entry">
2018-05-23: <a href="entries/Irrationality_J_Hancl.html">Irrational Rapidly Convergent Series</a>
<br>
Authors:
<a href="https://www.cl.cam.ac.uk/~ak2110/">Angeliki Koutsoukou-Argyraki</a>
and <a href="https://www.cl.cam.ac.uk/~wl302/">Wenda Li</a>
</td>
</tr>
<tr>
<td class="entry">
2018-05-23: <a href="entries/AxiomaticCategoryTheory.html">Axiom Systems for Category Theory in Free Logic</a>
<br>
Authors:
<a href="http://christoph-benzmueller.de">Christoph Benzmüller</a>
and <a href="http://www.cs.cmu.edu/~scott/">Dana Scott</a>
</td>
</tr>
<tr>
<td class="entry">
2018-05-22: <a href="entries/Monad_Memo_DP.html">Monadification, Memoization and Dynamic Programming</a>
<br>
Authors:
<a href="http://home.in.tum.de/~wimmers/">Simon Wimmer</a>,
Shuwei Hu
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2018-05-10: <a href="entries/OpSets.html">OpSets: Sequential Specifications for Replicated Datatypes</a>
<br>
Authors:
Martin Kleppmann,
Victor B. F. Gomes,
Dominic P. Mulligan
and Alastair R. Beresford
</td>
</tr>
<tr>
<td class="entry">
2018-05-07: <a href="entries/Modular_Assembly_Kit_Security.html">An Isabelle/HOL Formalization of the Modular Assembly Kit for Security Properties</a>
<br>
Authors:
Oliver Bračevac,
Richard Gay,
Sylvia Grewe,
Heiko Mantel,
Henning Sudbrock
and Markus Tasch
</td>
</tr>
<tr>
<td class="entry">
2018-04-29: <a href="entries/WebAssembly.html">WebAssembly</a>
<br>
Author:
<a href="http://www.cl.cam.ac.uk/~caw77/">Conrad Watt</a>
</td>
</tr>
<tr>
<td class="entry">
2018-04-27: <a href="entries/VerifyThis2018.html">VerifyThis 2018 - Polished Isabelle Solutions</a>
<br>
Authors:
Peter Lammich
and <a href="http://home.in.tum.de/~wimmers/">Simon Wimmer</a>
</td>
</tr>
<tr>
<td class="entry">
2018-04-24: <a href="entries/BNF_CC.html">Bounded Natural Functors with Covariance and Contravariance</a>
<br>
Authors:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
and Joshua Schneider
</td>
</tr>
<tr>
<td class="entry">
2018-03-22: <a href="entries/Fishburn_Impossibility.html">The Incompatibility of Fishburn-Strategyproofness and Pareto-Efficiency</a>
<br>
Authors:
<a href="http://dss.in.tum.de/staff/brandt.html">Felix Brandt</a>,
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>,
<a href="http://dss.in.tum.de/staff/christian-saile.html">Christian Saile</a>
and <a href="http://dss.in.tum.de/staff/christian-stricker.html">Christian Stricker</a>
</td>
</tr>
<tr>
<td class="entry">
2018-03-13: <a href="entries/Weight_Balanced_Trees.html">Weight-Balanced Trees</a>
<br>
Authors:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
and Stefan Dirix
</td>
</tr>
<tr>
<td class="entry">
2018-03-12: <a href="entries/CakeML.html">CakeML</a>
<br>
Authors:
<a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
and Yu Zhang
</td>
</tr>
<tr>
<td class="entry">
2018-03-01: <a href="entries/Architectural_Design_Patterns.html">A Theory of Architectural Design Patterns</a>
<br>
Author:
<a href="http://marmsoler.com">Diego Marmsoler</a>
</td>
</tr>
<tr>
<td class="entry">
2018-02-26: <a href="entries/Hoare_Time.html">Hoare Logics for Time Bounds</a>
<br>
Authors:
<a href="http://www.in.tum.de/~haslbema">Maximilian P. L. Haslbeck</a>
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2018-02-06: <a href="entries/Treaps.html">Treaps</a>
<br>
Authors:
<a href="http://cl-informatik.uibk.ac.at/users/mhaslbeck/">Maximilian Haslbeck</a>,
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2018-02-06: <a href="entries/LLL_Factorization.html">A verified factorization algorithm for integer polynomials with polynomial complexity</a>
<br>
Authors:
<a href="https://www.unirioja.es/cu/jodivaso/">Jose Divasón</a>,
<a href="http://sjcjoosten.nl/">Sebastiaan Joosten</a>,
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
and <a href="http://group-mmm.org/~ayamada/">Akihisa Yamada</a>
</td>
</tr>
<tr>
<td class="entry">
2018-02-06: <a href="entries/First_Order_Terms.html">First-Order Terms</a>
<br>
Authors:
Christian Sternagel
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2018-02-06: <a href="entries/Error_Function.html">The Error Function</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2018-02-02: <a href="entries/LLL_Basis_Reduction.html">A verified LLL algorithm</a>
<br>
Authors:
<a href="http://cl-informatik.uibk.ac.at/users/bottesch/">Ralph Bottesch</a>,
<a href="https://www.unirioja.es/cu/jodivaso/">Jose Divasón</a>,
<a href="http://cl-informatik.uibk.ac.at/users/mhaslbeck/">Maximilian Haslbeck</a>,
<a href="http://sjcjoosten.nl/">Sebastiaan Joosten</a>,
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
and <a href="http://group-mmm.org/~ayamada/">Akihisa Yamada</a>
</td>
</tr>
<tr>
<td class="entry">
2018-01-18: <a href="entries/Ordered_Resolution_Prover.html">Formalization of Bachmair and Ganzinger's Ordered Resolution Prover</a>
<br>
Authors:
<a href="https://people.compute.dtu.dk/andschl/">Anders Schlichtkrull</a>,
Jasmin Christian Blanchette,
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
and Uwe Waldmann
</td>
</tr>
<tr>
<td class="entry">
2018-01-16: <a href="entries/Gromov_Hyperbolicity.html">Gromov Hyperbolicity</a>
<br>
Author:
Sebastien Gouezel
</td>
</tr>
<tr>
<td class="entry">
2018-01-11: <a href="entries/Green.html">An Isabelle/HOL formalisation of Green's Theorem</a>
<br>
Authors:
<a href="http://home.in.tum.de/~mansour/">Mohammad Abdulaziz</a>
and <a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2018-01-08: <a href="entries/Taylor_Models.html">Taylor Models</a>
<br>
Authors:
Christoph Traut
and <a href="http://home.in.tum.de/~immler/">Fabian Immler</a>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2017</td>
</tr>
<tr>
<td class="entry">
2017-12-22: <a href="entries/Falling_Factorial_Sum.html">The Falling Factorial of a Sum</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
<tr>
<td class="entry">
2017-12-21: <a href="entries/Median_Of_Medians_Selection.html">The Median-of-Medians Selection Algorithm</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-12-21: <a href="entries/Mason_Stothers.html">The Mason–Stothers Theorem</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-12-21: <a href="entries/Dirichlet_L.html">Dirichlet L-Functions and Dirichlet's Theorem</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-12-19: <a href="entries/BNF_Operations.html">Operations on Bounded Natural Functors</a>
<br>
Authors:
Jasmin Christian Blanchette,
- Andrei Popescu
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2017-12-18: <a href="entries/Knuth_Morris_Pratt.html">The string search algorithm by Knuth, Morris and Pratt</a>
<br>
Authors:
Fabian Hellauer
and Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2017-11-22: <a href="entries/Stochastic_Matrices.html">Stochastic Matrices and the Perron-Frobenius Theorem</a>
<br>
Author:
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2017-11-09: <a href="entries/IMAP-CRDT.html">The IMAP CmRDT</a>
<br>
Authors:
Tim Jungnickel,
Lennart Oldenburg
and Matthias Loibl
</td>
</tr>
<tr>
<td class="entry">
2017-11-06: <a href="entries/Hybrid_Multi_Lane_Spatial_Logic.html">Hybrid Multi-Lane Spatial Logic</a>
<br>
Author:
Sven Linker
</td>
</tr>
<tr>
<td class="entry">
2017-10-26: <a href="entries/Kuratowski_Closure_Complement.html">The Kuratowski Closure-Complement Theorem</a>
<br>
Authors:
<a href="http://peteg.org">Peter Gammie</a>
and Gianpaolo Gioiosa
</td>
</tr>
<tr>
<td class="entry">
2017-10-19: <a href="entries/Transition_Systems_and_Automata.html">Transition Systems and Automata</a>
<br>
Author:
<a href="http://www21.in.tum.de/~brunnerj/">Julian Brunner</a>
</td>
</tr>
<tr>
<td class="entry">
2017-10-19: <a href="entries/Buchi_Complementation.html">Büchi Complementation</a>
<br>
Author:
<a href="http://www21.in.tum.de/~brunnerj/">Julian Brunner</a>
</td>
</tr>
<tr>
<td class="entry">
2017-10-17: <a href="entries/Winding_Number_Eval.html">Evaluate Winding Numbers through Cauchy Indices</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~wl302/">Wenda Li</a>
</td>
</tr>
<tr>
<td class="entry">
2017-10-17: <a href="entries/Count_Complex_Roots.html">Count the Number of Complex Roots</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~wl302/">Wenda Li</a>
</td>
</tr>
<tr>
<td class="entry">
2017-10-14: <a href="entries/Diophantine_Eqns_Lin_Hom.html">Homogeneous Linear Diophantine Equations</a>
<br>
Authors:
Florian Messner,
<a href="http://www.parsert.com/">Julian Parsert</a>,
Jonas Schöpf
and Christian Sternagel
</td>
</tr>
<tr>
<td class="entry">
2017-10-12: <a href="entries/Zeta_Function.html">The Hurwitz and Riemann ζ Functions</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-10-12: <a href="entries/Linear_Recurrences.html">Linear Recurrences</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-10-12: <a href="entries/Dirichlet_Series.html">Dirichlet Series</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-09-21: <a href="entries/Lowe_Ontological_Argument.html">Computer-assisted Reconstruction and Assessment of E. J. Lowe's Modal Ontological Argument</a>
<br>
Authors:
David Fuenmayor
and <a href="http://christoph-benzmueller.de">Christoph Benzmüller</a>
</td>
</tr>
<tr>
<td class="entry">
2017-09-17: <a href="entries/PLM.html">Representation and Partial Automation of the Principia Logico-Metaphysica in Isabelle/HOL</a>
<br>
Author:
Daniel Kirchner
</td>
</tr>
<tr>
<td class="entry">
2017-09-06: <a href="entries/AnselmGod.html">Anselm's God in Isabelle/HOL</a>
<br>
Author:
<a href="https://philpapers.org/profile/805">Ben Blumson</a>
</td>
</tr>
<tr>
<td class="entry">
2017-09-01: <a href="entries/First_Welfare_Theorem.html">Microeconomics and the First Welfare Theorem</a>
<br>
Authors:
<a href="http://www.parsert.com/">Julian Parsert</a>
and <a href="http://cl-informatik.uibk.ac.at/cek/">Cezary Kaliszyk</a>
</td>
</tr>
<tr>
<td class="entry">
2017-08-20: <a href="entries/Root_Balanced_Tree.html">Root-Balanced Tree</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2017-08-20: <a href="entries/Orbit_Stabiliser.html">Orbit-Stabiliser Theorem with Application to Rotational Symmetries</a>
<br>
Author:
Jonas Rädle
</td>
</tr>
<tr>
<td class="entry">
2017-08-16: <a href="entries/LambdaMu.html">The LambdaMu-calculus</a>
<br>
Authors:
Cristina Matache,
Victor B. F. Gomes
and Dominic P. Mulligan
</td>
</tr>
<tr>
<td class="entry">
2017-07-31: <a href="entries/Stewart_Apollonius.html">Stewart's Theorem and Apollonius' Theorem</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
<tr>
<td class="entry">
2017-07-28: <a href="entries/DynamicArchitectures.html">Dynamic Architectures</a>
<br>
Author:
<a href="http://marmsoler.com">Diego Marmsoler</a>
</td>
</tr>
<tr>
<td class="entry">
2017-07-21: <a href="entries/Decl_Sem_Fun_PL.html">Declarative Semantics for Functional Languages</a>
<br>
Author:
<a href="http://homes.soic.indiana.edu/jsiek/">Jeremy Siek</a>
</td>
</tr>
<tr>
<td class="entry">
2017-07-15: <a href="entries/HOLCF-Prelude.html">HOLCF-Prelude</a>
<br>
Authors:
Joachim Breitner,
Brian Huffman,
Neil Mitchell
and Christian Sternagel
</td>
</tr>
<tr>
<td class="entry">
2017-07-13: <a href="entries/Minkowskis_Theorem.html">Minkowski's Theorem</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-07-09: <a href="entries/Name_Carrying_Type_Inference.html">Verified Metatheory and Type Inference for a Name-Carrying Simply-Typed Lambda Calculus</a>
<br>
Author:
Michael Rawson
</td>
</tr>
<tr>
<td class="entry">
2017-07-07: <a href="entries/CRDT.html">A framework for establishing Strong Eventual Consistency for Conflict-free Replicated Datatypes</a>
<br>
Authors:
Victor B. F. Gomes,
Martin Kleppmann,
Dominic P. Mulligan
and Alastair R. Beresford
</td>
</tr>
<tr>
<td class="entry">
2017-07-06: <a href="entries/Stone_Kleene_Relation_Algebras.html">Stone-Kleene Relation Algebras</a>
<br>
Author:
<a href="http://www.cosc.canterbury.ac.nz/walter.guttmann/">Walter Guttmann</a>
</td>
</tr>
<tr>
<td class="entry">
2017-06-21: <a href="entries/Propositional_Proof_Systems.html">Propositional Proof Systems</a>
<br>
Authors:
<a href="http://liftm.de">Julius Michaelis</a>
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2017-06-13: <a href="entries/PSemigroupsConvolution.html">Partial Semigroups and Convolution Algebras</a>
<br>
Authors:
Brijesh Dongol,
Victor B. F. Gomes,
Ian J. Hayes
and <a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
</td>
</tr>
<tr>
<td class="entry">
2017-06-06: <a href="entries/Buffons_Needle.html">Buffon's Needle Problem</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-06-01: <a href="entries/Prpu_Maxflow.html">Formalizing Push-Relabel Algorithms</a>
<br>
Authors:
Peter Lammich
and S. Reza Sefidgar
</td>
</tr>
<tr>
<td class="entry">
2017-06-01: <a href="entries/Flow_Networks.html">Flow Networks and the Min-Cut-Max-Flow Theorem</a>
<br>
Authors:
Peter Lammich
and S. Reza Sefidgar
</td>
</tr>
<tr>
<td class="entry">
2017-05-25: <a href="entries/Optics.html">Optics</a>
<br>
Authors:
<a href="https://www-users.cs.york.ac.uk/~simonf/">Simon Foster</a>
and Frank Zeyda
</td>
</tr>
<tr>
<td class="entry">
2017-05-24: <a href="entries/Security_Protocol_Refinement.html">Developing Security Protocols by Refinement</a>
<br>
Authors:
Christoph Sprenger
and Ivano Somaini
</td>
</tr>
<tr>
<td class="entry">
2017-05-24: <a href="entries/Dict_Construction.html">Dictionary Construction</a>
<br>
Author:
<a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
</td>
</tr>
<tr>
<td class="entry">
2017-05-08: <a href="entries/Floyd_Warshall.html">The Floyd-Warshall Algorithm for Shortest Paths</a>
<br>
Authors:
<a href="http://home.in.tum.de/~wimmers/">Simon Wimmer</a>
and Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2017-05-05: <a href="entries/Probabilistic_While.html">Probabilistic while loop</a>
<br>
Author:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="entry">
2017-05-05: <a href="entries/Monomorphic_Monad.html">Effect polymorphism in higher-order logic</a>
<br>
Author:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="entry">
2017-05-05: <a href="entries/Monad_Normalisation.html">Monad normalisation</a>
<br>
Authors:
Joshua Schneider,
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
and <a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="entry">
2017-05-05: <a href="entries/Game_Based_Crypto.html">Game-based cryptography in HOL</a>
<br>
Authors:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>,
S. Reza Sefidgar
and Bhargav Bhatt
</td>
</tr>
<tr>
<td class="entry">
2017-05-05: <a href="entries/CryptHOL.html">CryptHOL</a>
<br>
Author:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="entry">
2017-05-04: <a href="entries/MonoidalCategory.html">Monoidal Categories</a>
<br>
Author:
Eugene W. Stark
</td>
</tr>
<tr>
<td class="entry">
2017-05-01: <a href="entries/Types_Tableaus_and_Goedels_God.html">Types, Tableaus and Gödel’s God in Isabelle/HOL</a>
<br>
Authors:
David Fuenmayor
and <a href="http://christoph-benzmueller.de">Christoph Benzmüller</a>
</td>
</tr>
<tr>
<td class="entry">
2017-04-28: <a href="entries/LocalLexing.html">Local Lexing</a>
<br>
Author:
Steven Obua
</td>
</tr>
<tr>
<td class="entry">
2017-04-19: <a href="entries/Constructor_Funs.html">Constructor Functions</a>
<br>
Author:
<a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
</td>
</tr>
<tr>
<td class="entry">
2017-04-18: <a href="entries/Lazy_Case.html">Lazifying case constants</a>
<br>
Author:
<a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
</td>
</tr>
<tr>
<td class="entry">
2017-04-06: <a href="entries/Subresultants.html">Subresultants</a>
<br>
Authors:
<a href="http://sjcjoosten.nl/">Sebastiaan Joosten</a>,
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
and <a href="http://group-mmm.org/~ayamada/">Akihisa Yamada</a>
</td>
</tr>
<tr>
<td class="entry">
2017-04-04: <a href="entries/Random_BSTs.html">Expected Shape of Random Binary Search Trees</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-03-15: <a href="entries/Quick_Sort_Cost.html">The number of comparisons in QuickSort</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-03-15: <a href="entries/Comparison_Sort_Lower_Bound.html">Lower bound on comparison-based sorting algorithms</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-03-10: <a href="entries/Euler_MacLaurin.html">The Euler–MacLaurin Formula</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-02-28: <a href="entries/Elliptic_Curves_Group_Law.html">The Group Law for Elliptic Curves</a>
<br>
Author:
<a href="http://www.in.tum.de/~berghofe">Stefan Berghofer</a>
</td>
</tr>
<tr>
<td class="entry">
2017-02-26: <a href="entries/Menger.html">Menger's Theorem</a>
<br>
Author:
<a href="http://logic.las.tu-berlin.de/Members/Dittmann/">Christoph Dittmann</a>
</td>
</tr>
<tr>
<td class="entry">
2017-02-13: <a href="entries/Differential_Dynamic_Logic.html">Differential Dynamic Logic</a>
<br>
Author:
Brandon Bohrer
</td>
</tr>
<tr>
<td class="entry">
2017-02-10: <a href="entries/Abstract_Soundness.html">Abstract Soundness</a>
<br>
Authors:
Jasmin Christian Blanchette,
- Andrei Popescu
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2017-02-07: <a href="entries/Stone_Relation_Algebras.html">Stone Relation Algebras</a>
<br>
Author:
<a href="http://www.cosc.canterbury.ac.nz/walter.guttmann/">Walter Guttmann</a>
</td>
</tr>
<tr>
<td class="entry">
2017-01-31: <a href="entries/Key_Agreement_Strong_Adversaries.html">Refining Authenticated Key Agreement with Strong Adversaries</a>
<br>
Authors:
Joseph Lallemand
and Christoph Sprenger
</td>
</tr>
<tr>
<td class="entry">
2017-01-24: <a href="entries/Bernoulli.html">Bernoulli Numbers</a>
<br>
Authors:
Lukas Bulwahn
and <a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-01-17: <a href="entries/Minimal_SSA.html">Minimal Static Single Assignment Form</a>
<br>
Authors:
Max Wagner
and <a href="http://pp.ipd.kit.edu/person.php?id=88">Denis Lohner</a>
</td>
</tr>
<tr>
<td class="entry">
2017-01-17: <a href="entries/Bertrands_Postulate.html">Bertrand's postulate</a>
<br>
Authors:
Julian Biendarra
and <a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-01-12: <a href="entries/E_Transcendental.html">The Transcendence of e</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2017-01-08: <a href="entries/UPF_Firewall.html">Formal Network Models and Their Application to Firewall Policies</a>
<br>
Authors:
Achim D. Brucker,
Lukas Brügger
and <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
</td>
</tr>
<tr>
<td class="entry">
2017-01-03: <a href="entries/Password_Authentication_Protocol.html">Verification of a Diffie-Hellman Password-based Authentication Protocol by Extending the Inductive Method</a>
<br>
Author:
Pasquale Noce
</td>
</tr>
<tr>
<td class="entry">
2017-01-01: <a href="entries/FOL_Harrison.html">First-Order Logic According to Harrison</a>
<br>
Authors:
<a href="https://people.compute.dtu.dk/aleje/">Alexander Birch Jensen</a>,
<a href="https://people.compute.dtu.dk/andschl/">Anders Schlichtkrull</a>
and <a href="https://people.compute.dtu.dk/jovi/">Jørgen Villadsen</a>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2016</td>
</tr>
<tr>
<td class="entry">
2016-12-30: <a href="entries/Concurrent_Ref_Alg.html">Concurrent Refinement Algebra and Rely Quotients</a>
<br>
Authors:
Julian Fell,
Ian J. Hayes
and <a href="http://andrius.velykis.lt">Andrius Velykis</a>
</td>
</tr>
<tr>
<td class="entry">
2016-12-29: <a href="entries/Twelvefold_Way.html">The Twelvefold Way</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
<tr>
<td class="entry">
2016-12-20: <a href="entries/Proof_Strategy_Language.html">Proof Strategy Language</a>
<br>
Author:
Yutaka Nagashima
</td>
</tr>
<tr>
<td class="entry">
2016-12-07: <a href="entries/Paraconsistency.html">Paraconsistency</a>
<br>
Authors:
<a href="https://people.compute.dtu.dk/andschl/">Anders Schlichtkrull</a>
and <a href="https://people.compute.dtu.dk/jovi/">Jørgen Villadsen</a>
</td>
</tr>
<tr>
<td class="entry">
2016-11-29: <a href="entries/Complx.html">COMPLX: A Verification Framework for Concurrent Imperative Programs</a>
<br>
Authors:
Sidney Amani,
June Andronick,
Maksym Bortin,
Corey Lewis,
Christine Rizkallah
and Joseph Tuong
</td>
</tr>
<tr>
<td class="entry">
2016-11-23: <a href="entries/Abs_Int_ITP2012.html">Abstract Interpretation of Annotated Commands</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2016-11-16: <a href="entries/Separata.html">Separata: Isabelle tactics for Separation Algebra</a>
<br>
Authors:
Zhe Hou,
David Sanan,
Alwen Tiu,
Rajeev Gore
and Ranald Clouston
</td>
</tr>
<tr>
<td class="entry">
2016-11-12: <a href="entries/Nested_Multisets_Ordinals.html">Formalization of Nested Multisets, Hereditary Multisets, and Syntactic Ordinals</a>
<br>
Authors:
Jasmin Christian Blanchette,
<a href="http://fmv.jku.at/fleury">Mathias Fleury</a>
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2016-11-12: <a href="entries/Lambda_Free_KBOs.html">Formalization of Knuth–Bendix Orders for Lambda-Free Higher-Order Terms</a>
<br>
Authors:
Heiko Becker,
Jasmin Christian Blanchette,
Uwe Waldmann
and Daniel Wand
</td>
</tr>
<tr>
<td class="entry">
2016-11-10: <a href="entries/Deep_Learning.html">Expressiveness of Deep Learning</a>
<br>
Author:
Alexander Bentkamp
</td>
</tr>
<tr>
<td class="entry">
2016-10-25: <a href="entries/Modal_Logics_for_NTS.html">Modal Logics for Nominal Transition Systems</a>
<br>
Authors:
Tjark Weber,
Lars-Henrik Eriksson,
Joachim Parrow,
Johannes Borgström
and Ramunas Gutkovas
</td>
</tr>
<tr>
<td class="entry">
2016-10-24: <a href="entries/Stable_Matching.html">Stable Matching</a>
<br>
Author:
<a href="http://peteg.org">Peter Gammie</a>
</td>
</tr>
<tr>
<td class="entry">
2016-10-21: <a href="entries/LOFT.html">LOFT — Verified Migration of Linux Firewalls to SDN</a>
<br>
Authors:
<a href="http://liftm.de">Julius Michaelis</a>
and <a href="http://net.in.tum.de/~diekmann">Cornelius Diekmann</a>
</td>
</tr>
<tr>
<td class="entry">
2016-10-19: <a href="entries/Source_Coding_Theorem.html">Source Coding Theorem</a>
<br>
Authors:
Quentin Hibon
and <a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2016-10-19: <a href="entries/SPARCv8.html">A formal model for the SPARCv8 ISA and a proof of non-interference for the LEON3 processor</a>
<br>
Authors:
Zhe Hou,
David Sanan,
Alwen Tiu
and Yang Liu
</td>
</tr>
<tr>
<td class="entry">
2016-10-14: <a href="entries/Berlekamp_Zassenhaus.html">The Factorization Algorithm of Berlekamp and Zassenhaus</a>
<br>
Authors:
<a href="https://www.unirioja.es/cu/jodivaso/">Jose Divasón</a>,
<a href="http://sjcjoosten.nl/">Sebastiaan Joosten</a>,
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
and <a href="http://group-mmm.org/~ayamada/">Akihisa Yamada</a>
</td>
</tr>
<tr>
<td class="entry">
2016-10-11: <a href="entries/Chord_Segments.html">Intersecting Chords Theorem</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
<tr>
<td class="entry">
2016-10-05: <a href="entries/Lp.html">Lp spaces</a>
<br>
Author:
Sebastien Gouezel
</td>
</tr>
<tr>
<td class="entry">
2016-09-30: <a href="entries/Fisher_Yates.html">Fisher–Yates shuffle</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2016-09-29: <a href="entries/Allen_Calculus.html">Allen's Interval Calculus</a>
<br>
Author:
Fadoua Ghourabi
</td>
</tr>
<tr>
<td class="entry">
2016-09-23: <a href="entries/Lambda_Free_RPOs.html">Formalization of Recursive Path Orders for Lambda-Free Higher-Order Terms</a>
<br>
Authors:
Jasmin Christian Blanchette,
Uwe Waldmann
and Daniel Wand
</td>
</tr>
<tr>
<td class="entry">
2016-09-09: <a href="entries/Iptables_Semantics.html">Iptables Semantics</a>
<br>
Authors:
<a href="http://net.in.tum.de/~diekmann">Cornelius Diekmann</a>
and <a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
</td>
</tr>
<tr>
<td class="entry">
2016-09-06: <a href="entries/SuperCalc.html">A Variant of the Superposition Calculus</a>
<br>
Author:
<a href="http://membres-lig.imag.fr/peltier/">Nicolas Peltier</a>
</td>
</tr>
<tr>
<td class="entry">
2016-09-06: <a href="entries/Stone_Algebras.html">Stone Algebras</a>
<br>
Author:
<a href="http://www.cosc.canterbury.ac.nz/walter.guttmann/">Walter Guttmann</a>
</td>
</tr>
<tr>
<td class="entry">
2016-09-01: <a href="entries/Stirling_Formula.html">Stirling's formula</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2016-08-31: <a href="entries/Routing.html">Routing</a>
<br>
Authors:
<a href="http://liftm.de">Julius Michaelis</a>
and <a href="http://net.in.tum.de/~diekmann">Cornelius Diekmann</a>
</td>
</tr>
<tr>
<td class="entry">
2016-08-24: <a href="entries/Simple_Firewall.html">Simple Firewall</a>
<br>
Authors:
<a href="http://net.in.tum.de/~diekmann">Cornelius Diekmann</a>,
<a href="http://liftm.de">Julius Michaelis</a>
and <a href="http://cl-informatik.uibk.ac.at/users/mhaslbeck/">Maximilian Haslbeck</a>
</td>
</tr>
<tr>
<td class="entry">
2016-08-18: <a href="entries/InfPathElimination.html">Infeasible Paths Elimination by Symbolic Execution Techniques: Proof of Correctness and Preservation of Paths</a>
<br>
Authors:
Romain Aissat,
Frederic Voisin
and <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
</td>
</tr>
<tr>
<td class="entry">
2016-08-12: <a href="entries/EdmondsKarp_Maxflow.html">Formalizing the Edmonds-Karp Algorithm</a>
<br>
Authors:
Peter Lammich
and S. Reza Sefidgar
</td>
</tr>
<tr>
<td class="entry">
2016-08-08: <a href="entries/Refine_Imperative_HOL.html">The Imperative Refinement Framework</a>
<br>
Author:
Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2016-08-07: <a href="entries/Ptolemys_Theorem.html">Ptolemy's Theorem</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
<tr>
<td class="entry">
2016-07-17: <a href="entries/Surprise_Paradox.html">Surprise Paradox</a>
<br>
Author:
Joachim Breitner
</td>
</tr>
<tr>
<td class="entry">
2016-07-14: <a href="entries/Pairing_Heap.html">Pairing Heap</a>
<br>
Authors:
Hauke Brinkop
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2016-07-05: <a href="entries/DFS_Framework.html">A Framework for Verifying Depth-First Search Algorithms</a>
<br>
Authors:
Peter Lammich
and René Neumann
</td>
</tr>
<tr>
<td class="entry">
2016-07-01: <a href="entries/Buildings.html">Chamber Complexes, Coxeter Systems, and Buildings</a>
<br>
Author:
<a href="http://ualberta.ca/~jsylvest/">Jeremy Sylvestre</a>
</td>
</tr>
<tr>
<td class="entry">
2016-06-30: <a href="entries/Rewriting_Z.html">The Z Property</a>
<br>
Authors:
Bertram Felgenhauer,
Julian Nagele,
Vincent van Oostrom
and Christian Sternagel
</td>
</tr>
<tr>
<td class="entry">
2016-06-30: <a href="entries/Resolution_FOL.html">The Resolution Calculus for First-Order Logic</a>
<br>
Author:
<a href="https://people.compute.dtu.dk/andschl/">Anders Schlichtkrull</a>
</td>
</tr>
<tr>
<td class="entry">
2016-06-28: <a href="entries/IP_Addresses.html">IP Addresses</a>
<br>
Authors:
<a href="http://net.in.tum.de/~diekmann">Cornelius Diekmann</a>,
<a href="http://liftm.de">Julius Michaelis</a>
and <a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
</td>
</tr>
<tr>
<td class="entry">
2016-06-28: <a href="entries/Dependent_SIFUM_Refinement.html">Compositional Security-Preserving Refinement for Concurrent Imperative Programs</a>
<br>
Authors:
<a href="https://people.eng.unimelb.edu.au/tobym/">Toby Murray</a>,
Robert Sison,
Edward Pierzchalski
and Christine Rizkallah
</td>
</tr>
<tr>
<td class="entry">
2016-06-26: <a href="entries/Category3.html">Category Theory with Adjunctions and Limits</a>
<br>
Author:
Eugene W. Stark
</td>
</tr>
<tr>
<td class="entry">
2016-06-26: <a href="entries/Card_Multisets.html">Cardinality of Multisets</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
<tr>
<td class="entry">
2016-06-25: <a href="entries/Dependent_SIFUM_Type_Systems.html">A Dependent Security Type System for Concurrent Imperative Programs</a>
<br>
Authors:
<a href="https://people.eng.unimelb.edu.au/tobym/">Toby Murray</a>,
Robert Sison,
Edward Pierzchalski
and Christine Rizkallah
</td>
</tr>
<tr>
<td class="entry">
2016-06-21: <a href="entries/Catalan_Numbers.html">Catalan Numbers</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2016-06-18: <a href="entries/Algebraic_VCs.html">Program Construction and Verification Components Based on Kleene Algebra</a>
<br>
Authors:
Victor B. F. Gomes
and <a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
</td>
</tr>
<tr>
<td class="entry">
2016-06-13: <a href="entries/Noninterference_Concurrent_Composition.html">Conservation of CSP Noninterference Security under Concurrent Composition</a>
<br>
Author:
Pasquale Noce
</td>
</tr>
<tr>
<td class="entry">
2016-06-09: <a href="entries/Word_Lib.html">Finite Machine Word Library</a>
<br>
Authors:
Joel Beeren,
Matthew Fernandez,
Xin Gao,
<a href="http://www.cse.unsw.edu.au/~kleing/">Gerwin Klein</a>,
Rafal Kolanski,
Japheth Lim,
Corey Lewis,
Daniel Matichuk
and Thomas Sewell
</td>
</tr>
<tr>
<td class="entry">
2016-05-31: <a href="entries/Tree_Decomposition.html">Tree Decomposition</a>
<br>
Author:
<a href="http://logic.las.tu-berlin.de/Members/Dittmann/">Christoph Dittmann</a>
</td>
</tr>
<tr>
<td class="entry">
2016-05-24: <a href="entries/Posix-Lexing.html">POSIX Lexing with Derivatives of Regular Expressions</a>
<br>
Authors:
<a href="http://kcl.academia.edu/FahadAusaf">Fahad Ausaf</a>,
<a href="https://rd.host.cs.st-andrews.ac.uk">Roy Dyckhoff</a>
and <a href="http://www.inf.kcl.ac.uk/staff/urbanc/">Christian Urban</a>
</td>
</tr>
<tr>
<td class="entry">
2016-05-24: <a href="entries/Card_Equiv_Relations.html">Cardinality of Equivalence Relations</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
<tr>
<td class="entry">
2016-05-20: <a href="entries/Perron_Frobenius.html">Perron-Frobenius Theorem for Spectral Radius Analysis</a>
<br>
Authors:
<a href="https://www.unirioja.es/cu/jodivaso/">Jose Divasón</a>,
<a href="http://www21.in.tum.de/~kuncar/">Ondřej Kunčar</a>,
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
and <a href="http://group-mmm.org/~ayamada/">Akihisa Yamada</a>
</td>
</tr>
<tr>
<td class="entry">
2016-05-20: <a href="entries/Incredible_Proof_Machine.html">The meta theory of the Incredible Proof Machine</a>
<br>
Authors:
Joachim Breitner
and <a href="http://pp.ipd.kit.edu/person.php?id=88">Denis Lohner</a>
</td>
</tr>
<tr>
<td class="entry">
2016-05-18: <a href="entries/FLP.html">A Constructive Proof for FLP</a>
<br>
Authors:
Benjamin Bisping,
Paul-David Brodmann,
Tim Jungnickel,
Christina Rickmann,
Henning Seidler,
Anke Stüber,
Arno Wilhelm-Weidner,
Kirstin Peters
and <a href="https://www.mtv.tu-berlin.de/nestmann/">Uwe Nestmann</a>
</td>
</tr>
<tr>
<td class="entry">
2016-05-09: <a href="entries/MFMC_Countable.html">A Formal Proof of the Max-Flow Min-Cut Theorem for Countable Networks</a>
<br>
Author:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="entry">
2016-05-05: <a href="entries/Randomised_Social_Choice.html">Randomised Social Choice Theory</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2016-05-04: <a href="entries/SDS_Impossibility.html">The Incompatibility of SD-Efficiency and SD-Strategy-Proofness</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2016-05-04: <a href="entries/Bell_Numbers_Spivey.html">Spivey's Generalized Recurrence for Bell Numbers</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
<tr>
<td class="entry">
2016-05-02: <a href="entries/Groebner_Bases.html">Gröbner Bases Theory</a>
<br>
Authors:
<a href="http://home.in.tum.de/~immler/">Fabian Immler</a>
and <a href="https://risc.jku.at/m/alexander-maletzky/">Alexander Maletzky</a>
</td>
</tr>
<tr>
<td class="entry">
2016-04-28: <a href="entries/No_FTL_observers.html">No Faster-Than-Light Observers</a>
<br>
Authors:
Mike Stannett
and <a href="http://www.renyi.hu/~nemeti/">István Németi</a>
</td>
</tr>
<tr>
<td class="entry">
2016-04-27: <a href="entries/ROBDD.html">Algorithms for Reduced Ordered Binary Decision Diagrams</a>
<br>
Authors:
<a href="http://liftm.de">Julius Michaelis</a>,
<a href="http://cl-informatik.uibk.ac.at/users/mhaslbeck/">Maximilian Haslbeck</a>,
Peter Lammich
and <a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
</td>
</tr>
<tr>
<td class="entry">
2016-04-27: <a href="entries/CYK.html">A formalisation of the Cocke-Younger-Kasami algorithm</a>
<br>
Author:
Maksym Bortin
</td>
</tr>
<tr>
<td class="entry">
2016-04-26: <a href="entries/Noninterference_Sequential_Composition.html">Conservation of CSP Noninterference Security under Sequential Composition</a>
<br>
Author:
Pasquale Noce
</td>
</tr>
<tr>
<td class="entry">
2016-04-12: <a href="entries/KAD.html">Kleene Algebras with Domain</a>
<br>
Authors:
Victor B. F. Gomes,
<a href="http://www.cosc.canterbury.ac.nz/walter.guttmann/">Walter Guttmann</a>,
<a href="http://www.hoefner-online.de/">Peter Höfner</a>,
<a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
and Tjark Weber
</td>
</tr>
<tr>
<td class="entry">
2016-03-11: <a href="entries/PropResPI.html">Propositional Resolution and Prime Implicates Generation</a>
<br>
Author:
<a href="http://membres-lig.imag.fr/peltier/">Nicolas Peltier</a>
</td>
</tr>
<tr>
<td class="entry">
2016-03-08: <a href="entries/Timed_Automata.html">Timed Automata</a>
<br>
Author:
<a href="http://home.in.tum.de/~wimmers/">Simon Wimmer</a>
</td>
</tr>
<tr>
<td class="entry">
2016-03-08: <a href="entries/Cartan_FP.html">The Cartan Fixed Point Theorems</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2016-03-01: <a href="entries/LTL.html">Linear Temporal Logic</a>
<br>
Author:
Salomon Sickert
</td>
</tr>
<tr>
<td class="entry">
2016-02-17: <a href="entries/List_Update.html">Analysis of List Update Algorithms</a>
<br>
Authors:
<a href="http://in.tum.de/~haslbema/">Maximilian P.L. Haslbeck</a>
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2016-02-05: <a href="entries/Formal_SSA.html">Verified Construction of Static Single Assignment Form</a>
<br>
Authors:
Sebastian Ullrich
and <a href="http://pp.ipd.kit.edu/person.php?id=88">Denis Lohner</a>
</td>
</tr>
<tr>
<td class="entry">
2016-01-29: <a href="entries/Polynomial_Interpolation.html">Polynomial Interpolation</a>
<br>
Authors:
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
and <a href="http://group-mmm.org/~ayamada/">Akihisa Yamada</a>
</td>
</tr>
<tr>
<td class="entry">
2016-01-29: <a href="entries/Polynomial_Factorization.html">Polynomial Factorization</a>
<br>
Authors:
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
and <a href="http://group-mmm.org/~ayamada/">Akihisa Yamada</a>
</td>
</tr>
<tr>
<td class="entry">
2016-01-20: <a href="entries/Knot_Theory.html">Knot Theory</a>
<br>
Author:
T.V.H. Prathamesh
</td>
</tr>
<tr>
<td class="entry">
2016-01-18: <a href="entries/Matrix_Tensor.html">Tensor Product of Matrices</a>
<br>
Author:
T.V.H. Prathamesh
</td>
</tr>
<tr>
<td class="entry">
2016-01-14: <a href="entries/Card_Number_Partitions.html">Cardinality of Number Partitions</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2015</td>
</tr>
<tr>
<td class="entry">
2015-12-28: <a href="entries/Triangle.html">Basic Geometric Properties of Triangles</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2015-12-28: <a href="entries/Prime_Harmonic_Series.html">The Divergence of the Prime Harmonic Series</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2015-12-28: <a href="entries/Liouville_Numbers.html">Liouville numbers</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2015-12-28: <a href="entries/Descartes_Sign_Rule.html">Descartes' Rule of Signs</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2015-12-22: <a href="entries/Stern_Brocot.html">The Stern-Brocot Tree</a>
<br>
Authors:
<a href="http://peteg.org">Peter Gammie</a>
and <a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="entry">
2015-12-22: <a href="entries/Applicative_Lifting.html">Applicative Lifting</a>
<br>
Authors:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
and Joshua Schneider
</td>
</tr>
<tr>
<td class="entry">
2015-12-22: <a href="entries/Algebraic_Numbers.html">Algebraic Numbers in Isabelle/HOL</a>
<br>
Authors:
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>,
<a href="http://group-mmm.org/~ayamada/">Akihisa Yamada</a>
and <a href="http://sjcjoosten.nl/">Sebastiaan Joosten</a>
</td>
</tr>
<tr>
<td class="entry">
2015-12-12: <a href="entries/Card_Partitions.html">Cardinality of Set Partitions</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
<tr>
<td class="entry">
2015-12-02: <a href="entries/Latin_Square.html">Latin Square</a>
<br>
Author:
Alexander Bentkamp
</td>
</tr>
<tr>
<td class="entry">
2015-12-01: <a href="entries/Ergodic_Theory.html">Ergodic Theory</a>
<br>
Author:
Sebastien Gouezel
</td>
</tr>
<tr>
<td class="entry">
2015-11-19: <a href="entries/Euler_Partition.html">Euler's Partition Theorem</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
<tr>
<td class="entry">
2015-11-18: <a href="entries/TortoiseHare.html">The Tortoise and Hare Algorithm</a>
<br>
Author:
<a href="http://peteg.org">Peter Gammie</a>
</td>
</tr>
<tr>
<td class="entry">
2015-11-11: <a href="entries/Planarity_Certificates.html">Planarity Certificates</a>
<br>
Author:
<a href="http://www21.in.tum.de/~noschinl/">Lars Noschinski</a>
</td>
</tr>
<tr>
<td class="entry">
2015-11-02: <a href="entries/Parity_Game.html">Positional Determinacy of Parity Games</a>
<br>
Author:
<a href="http://logic.las.tu-berlin.de/Members/Dittmann/">Christoph Dittmann</a>
</td>
</tr>
<tr>
<td class="entry">
2015-09-16: <a href="entries/Isabelle_Meta_Model.html">A Meta-Model for the Isabelle API</a>
<br>
Authors:
<a href="https://www.lri.fr/~ftuong/">Frédéric Tuong</a>
and <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
</td>
</tr>
<tr>
<td class="entry">
2015-09-04: <a href="entries/LTL_to_DRA.html">Converting Linear Temporal Logic to Deterministic (Generalized) Rabin Automata</a>
<br>
Author:
Salomon Sickert
</td>
</tr>
<tr>
<td class="entry">
2015-08-21: <a href="entries/Jordan_Normal_Form.html">Matrices, Jordan Normal Forms, and Spectral Radius Theory</a>
<br>
Authors:
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
and <a href="http://group-mmm.org/~ayamada/">Akihisa Yamada</a>
</td>
</tr>
<tr>
<td class="entry">
2015-08-20: <a href="entries/Decreasing-Diagrams-II.html">Decreasing Diagrams II</a>
<br>
Author:
Bertram Felgenhauer
</td>
</tr>
<tr>
<td class="entry">
2015-08-18: <a href="entries/Noninterference_Inductive_Unwinding.html">The Inductive Unwinding Theorem for CSP Noninterference Security</a>
<br>
Author:
Pasquale Noce
</td>
</tr>
<tr>
<td class="entry">
2015-08-12: <a href="entries/Rep_Fin_Groups.html">Representations of Finite Groups</a>
<br>
Author:
<a href="http://ualberta.ca/~jsylvest/">Jeremy Sylvestre</a>
</td>
</tr>
<tr>
<td class="entry">
2015-08-10: <a href="entries/Encodability_Process_Calculi.html">Analysing and Comparing Encodability Criteria for Process Calculi</a>
<br>
Authors:
Kirstin Peters
and <a href="http://theory.stanford.edu/~rvg/">Rob van Glabbeek</a>
</td>
</tr>
<tr>
<td class="entry">
2015-07-21: <a href="entries/Case_Labeling.html">Generating Cases from Labeled Subgoals</a>
<br>
Author:
<a href="http://www21.in.tum.de/~noschinl/">Lars Noschinski</a>
</td>
</tr>
<tr>
<td class="entry">
2015-07-14: <a href="entries/Landau_Symbols.html">Landau Symbols</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2015-07-14: <a href="entries/Akra_Bazzi.html">The Akra-Bazzi theorem and the Master theorem</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2015-07-07: <a href="entries/Hermite.html">Hermite Normal Form</a>
<br>
Authors:
<a href="https://www.unirioja.es/cu/jodivaso/">Jose Divasón</a>
and <a href="http://www.unirioja.es/cu/jearansa">Jesús Aransay</a>
</td>
</tr>
<tr>
<td class="entry">
2015-06-27: <a href="entries/Derangements.html">Derangements Formula</a>
<br>
Author:
Lukas Bulwahn
</td>
</tr>
<tr>
<td class="entry">
2015-06-11: <a href="entries/Noninterference_Ipurge_Unwinding.html">The Ipurge Unwinding Theorem for CSP Noninterference Security</a>
<br>
Author:
Pasquale Noce
</td>
</tr>
<tr>
<td class="entry">
2015-06-11: <a href="entries/Noninterference_Generic_Unwinding.html">The Generic Unwinding Theorem for CSP Noninterference Security</a>
<br>
Author:
Pasquale Noce
</td>
</tr>
<tr>
<td class="entry">
2015-06-11: <a href="entries/Multirelations.html">Binary Multirelations</a>
<br>
Authors:
<a href="http://www.sci.kagoshima-u.ac.jp/~furusawa/">Hitoshi Furusawa</a>
and <a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
</td>
</tr>
<tr>
<td class="entry">
2015-06-11: <a href="entries/List_Interleaving.html">Reasoning about Lists via List Interleaving</a>
<br>
Author:
Pasquale Noce
</td>
</tr>
<tr>
<td class="entry">
2015-06-07: <a href="entries/Dynamic_Tables.html">Parameterized Dynamic Tables</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2015-05-28: <a href="entries/Formula_Derivatives.html">Derivatives of Logical Formulas</a>
<br>
Author:
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2015-05-27: <a href="entries/Probabilistic_System_Zoo.html">A Zoo of Probabilistic Systems</a>
<br>
Authors:
<a href="http://in.tum.de/~hoelzl">Johannes Hölzl</a>,
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2015-04-30: <a href="entries/Vickrey_Clarke_Groves.html">VCG - Combinatorial Vickrey-Clarke-Groves Auctions</a>
<br>
Authors:
Marco B. Caminati,
<a href="http://www.cs.bham.ac.uk/~mmk">Manfred Kerber</a>,
Christoph Lange
and Colin Rowat
</td>
</tr>
<tr>
<td class="entry">
2015-04-15: <a href="entries/Residuated_Lattices.html">Residuated Lattices</a>
<br>
Authors:
Victor B. F. Gomes
and <a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
</td>
</tr>
<tr>
<td class="entry">
2015-04-13: <a href="entries/ConcurrentIMP.html">Concurrent IMP</a>
<br>
Author:
<a href="http://peteg.org">Peter Gammie</a>
</td>
</tr>
<tr>
<td class="entry">
2015-04-13: <a href="entries/ConcurrentGC.html">Relaxing Safely: Verified On-the-Fly Garbage Collection for x86-TSO</a>
<br>
Authors:
<a href="http://peteg.org">Peter Gammie</a>,
<a href="https://www.cs.purdue.edu/homes/hosking/">Tony Hosking</a>
and Kai Engelhardt
</td>
</tr>
<tr>
<td class="entry">
2015-03-30: <a href="entries/Trie.html">Trie</a>
<br>
Authors:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2015-03-18: <a href="entries/Consensus_Refined.html">Consensus Refined</a>
<br>
Authors:
Ognjen Maric
and Christoph Sprenger
</td>
</tr>
<tr>
<td class="entry">
2015-03-11: <a href="entries/Deriving.html">Deriving class instances for datatypes</a>
<br>
Authors:
Christian Sternagel
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2015-02-20: <a href="entries/Call_Arity.html">The Safety of Call Arity</a>
<br>
Author:
Joachim Breitner
</td>
</tr>
<tr>
<td class="entry">
2015-02-12: <a href="entries/QR_Decomposition.html">QR Decomposition</a>
<br>
Authors:
<a href="https://www.unirioja.es/cu/jodivaso/">Jose Divasón</a>
and <a href="http://www.unirioja.es/cu/jearansa">Jesús Aransay</a>
</td>
</tr>
<tr>
<td class="entry">
2015-02-12: <a href="entries/Echelon_Form.html">Echelon Form</a>
<br>
Authors:
<a href="https://www.unirioja.es/cu/jodivaso/">Jose Divasón</a>
and <a href="http://www.unirioja.es/cu/jearansa">Jesús Aransay</a>
</td>
</tr>
<tr>
<td class="entry">
2015-02-05: <a href="entries/Finite_Automata_HF.html">Finite Automata in Hereditarily Finite Set Theory</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2015-01-28: <a href="entries/UpDown_Scheme.html">Verification of the UpDown Scheme</a>
<br>
Author:
<a href="http://in.tum.de/~hoelzl">Johannes Hölzl</a>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2014</td>
</tr>
<tr>
<td class="entry">
2014-11-28: <a href="entries/UPF.html">The Unified Policy Framework (UPF)</a>
<br>
Authors:
Achim D. Brucker,
Lukas Brügger
and <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
</td>
</tr>
<tr>
<td class="entry">
2014-10-23: <a href="entries/AODV.html">Loop freedom of the (untimed) AODV routing protocol</a>
<br>
Authors:
<a href="http://www.tbrk.org">Timothy Bourke</a>
and <a href="http://www.hoefner-online.de/">Peter Höfner</a>
</td>
</tr>
<tr>
<td class="entry">
2014-10-13: <a href="entries/Lifting_Definition_Option.html">Lifting Definition Option</a>
<br>
Author:
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2014-10-10: <a href="entries/Stream_Fusion_Code.html">Stream Fusion in HOL with Code Generation</a>
<br>
Authors:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
and Alexandra Maximova
</td>
</tr>
<tr>
<td class="entry">
2014-10-09: <a href="entries/Density_Compiler.html">A Verified Compiler for Probability Density Functions</a>
<br>
Authors:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>,
<a href="http://in.tum.de/~hoelzl">Johannes Hölzl</a>
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2014-10-08: <a href="entries/RefinementReactive.html">Formalization of Refinement Calculus for Reactive Systems</a>
<br>
Author:
Viorel Preoteasa
</td>
</tr>
<tr>
<td class="entry">
2014-10-03: <a href="entries/XML.html">XML</a>
<br>
Authors:
Christian Sternagel
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2014-10-03: <a href="entries/Certification_Monads.html">Certification Monads</a>
<br>
Authors:
Christian Sternagel
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2014-09-25: <a href="entries/Imperative_Insertion_Sort.html">Imperative Insertion Sort</a>
<br>
Author:
Christian Sternagel
</td>
</tr>
<tr>
<td class="entry">
2014-09-19: <a href="entries/Sturm_Tarski.html">The Sturm-Tarski Theorem</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~wl302/">Wenda Li</a>
</td>
</tr>
<tr>
<td class="entry">
2014-09-15: <a href="entries/Cayley_Hamilton.html">The Cayley-Hamilton Theorem</a>
<br>
Authors:
<a href="http://nm.wu.ac.at/nm/sadelsbe">Stephan Adelsberger</a>,
<a href="http://www.logic.at/people/hetzl/">Stefan Hetzl</a>
and Florian Pollak
</td>
</tr>
<tr>
<td class="entry">
2014-09-09: <a href="entries/Jordan_Hoelder.html">The Jordan-Hölder Theorem</a>
<br>
Author:
Jakob von Raumer
</td>
</tr>
<tr>
<td class="entry">
2014-09-04: <a href="entries/Priority_Queue_Braun.html">Priority Queues Based on Braun Trees</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2014-09-03: <a href="entries/Gauss_Jordan.html">Gauss-Jordan Algorithm and Its Applications</a>
<br>
Authors:
<a href="https://www.unirioja.es/cu/jodivaso/">Jose Divasón</a>
and <a href="http://www.unirioja.es/cu/jearansa">Jesús Aransay</a>
</td>
</tr>
<tr>
<td class="entry">
2014-08-29: <a href="entries/VectorSpace.html">Vector Spaces</a>
<br>
Author:
Holden Lee
</td>
</tr>
<tr>
<td class="entry">
2014-08-29: <a href="entries/Special_Function_Bounds.html">Real-Valued Special Functions: Upper and Lower Bounds</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2014-08-13: <a href="entries/Skew_Heap.html">Skew Heap</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2014-08-12: <a href="entries/Splay_Tree.html">Splay Tree</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2014-07-29: <a href="entries/Show.html">Haskell's Show Class in Isabelle/HOL</a>
<br>
Authors:
Christian Sternagel
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2014-07-18: <a href="entries/CISC-Kernel.html">Formal Specification of a Generic Separation Kernel</a>
<br>
Authors:
Freek Verbeek,
Sergey Tverdyshev,
Oto Havle,
Holger Blasum,
Bruno Langenstein,
Werner Stephan,
Yakoub Nemouchi,
Abderrahmane Feliachi,
<a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
and Julien Schmaltz
</td>
</tr>
<tr>
<td class="entry">
2014-07-13: <a href="entries/pGCL.html">pGCL for Isabelle</a>
<br>
Author:
David Cock
</td>
</tr>
<tr>
<td class="entry">
2014-07-07: <a href="entries/Amortized_Complexity.html">Amortized Complexity Verified</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2014-07-04: <a href="entries/Network_Security_Policy_Verification.html">Network Security Policy Verification</a>
<br>
Author:
<a href="http://net.in.tum.de/~diekmann">Cornelius Diekmann</a>
</td>
</tr>
<tr>
<td class="entry">
2014-07-03: <a href="entries/Pop_Refinement.html">Pop-Refinement</a>
<br>
Author:
<a href="http://www.kestrel.edu/~coglio">Alessandro Coglio</a>
</td>
</tr>
<tr>
<td class="entry">
2014-06-12: <a href="entries/MSO_Regex_Equivalence.html">Decision Procedures for MSO on Words Based on Derivatives of Regular Expressions</a>
<br>
Authors:
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2014-06-08: <a href="entries/Boolean_Expression_Checkers.html">Boolean Expression Checkers</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2014-05-28: <a href="entries/Promela.html">Promela Formalization</a>
<br>
Author:
René Neumann
</td>
</tr>
<tr>
<td class="entry">
2014-05-28: <a href="entries/LTL_to_GBA.html">Converting Linear-Time Temporal Logic to Generalized Büchi Automata</a>
<br>
Authors:
Alexander Schimpf
and Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2014-05-28: <a href="entries/Gabow_SCC.html">Verified Efficient Implementation of Gabow's Strongly Connected Components Algorithm</a>
<br>
Author:
Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2014-05-28: <a href="entries/CAVA_LTL_Modelchecker.html">A Fully Verified Executable LTL Model Checker</a>
<br>
Authors:
<a href="https://www7.in.tum.de/~esparza/">Javier Esparza</a>,
Peter Lammich,
René Neumann,
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>,
Alexander Schimpf
and <a href="http://www.irit.fr/~Jan-Georg.Smaus">Jan-Georg Smaus</a>
</td>
</tr>
<tr>
<td class="entry">
2014-05-28: <a href="entries/CAVA_Automata.html">The CAVA Automata Library</a>
<br>
Author:
Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2014-05-23: <a href="entries/Roy_Floyd_Warshall.html">Transitive closure according to Roy-Floyd-Warshall</a>
<br>
Author:
Makarius Wenzel
</td>
</tr>
<tr>
<td class="entry">
2014-05-23: <a href="entries/Noninterference_CSP.html">Noninterference Security in Communicating Sequential Processes</a>
<br>
Author:
Pasquale Noce
</td>
</tr>
<tr>
<td class="entry">
2014-05-21: <a href="entries/Regular_Algebras.html">Regular Algebras</a>
<br>
Authors:
<a href="https://www-users.cs.york.ac.uk/~simonf/">Simon Foster</a>
and <a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
</td>
</tr>
<tr>
<td class="entry">
2014-04-28: <a href="entries/ComponentDependencies.html">Formalisation and Analysis of Component Dependencies</a>
<br>
Author:
Maria Spichkova
</td>
</tr>
<tr>
<td class="entry">
2014-04-23: <a href="entries/WHATandWHERE_Security.html">A Formalization of Declassification with WHAT-and-WHERE-Security</a>
<br>
Authors:
Sylvia Grewe,
Alexander Lux,
Heiko Mantel
and Jens Sauer
</td>
</tr>
<tr>
<td class="entry">
2014-04-23: <a href="entries/Strong_Security.html">A Formalization of Strong Security</a>
<br>
Authors:
Sylvia Grewe,
Alexander Lux,
Heiko Mantel
and Jens Sauer
</td>
</tr>
<tr>
<td class="entry">
2014-04-23: <a href="entries/SIFUM_Type_Systems.html">A Formalization of Assumptions and Guarantees for Compositional Noninterference</a>
<br>
Authors:
Sylvia Grewe,
Heiko Mantel
and Daniel Schoepe
</td>
</tr>
<tr>
<td class="entry">
2014-04-22: <a href="entries/Bounded_Deducibility_Security.html">Bounded-Deducibility Security</a>
<br>
Authors:
- Andrei Popescu
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
and Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2014-04-16: <a href="entries/HyperCTL.html">A shallow embedding of HyperCTL*</a>
<br>
Authors:
<a href="http://www.react.uni-saarland.de/people/rabe.html">Markus N. Rabe</a>,
Peter Lammich
- and Andrei Popescu
+ and <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
</td>
</tr>
<tr>
<td class="entry">
2014-04-16: <a href="entries/Abstract_Completeness.html">Abstract Completeness</a>
<br>
Authors:
Jasmin Christian Blanchette,
- Andrei Popescu
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2014-04-13: <a href="entries/Discrete_Summation.html">Discrete Summation</a>
<br>
Author:
<a href="http://isabelle.in.tum.de/~haftmann">Florian Haftmann</a>
</td>
</tr>
<tr>
<td class="entry">
2014-04-03: <a href="entries/GPU_Kernel_PL.html">Syntax and semantics of a GPU kernel programming language</a>
<br>
Author:
John Wickerson
</td>
</tr>
<tr>
<td class="entry">
2014-03-11: <a href="entries/Probabilistic_Noninterference.html">Probabilistic Noninterference</a>
<br>
Authors:
- Andrei Popescu
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
and <a href="http://in.tum.de/~hoelzl">Johannes Hölzl</a>
</td>
</tr>
<tr>
<td class="entry">
2014-03-08: <a href="entries/AWN.html">Mechanization of the Algebra for Wireless Networks (AWN)</a>
<br>
Author:
<a href="http://www.tbrk.org">Timothy Bourke</a>
</td>
</tr>
<tr>
<td class="entry">
2014-02-18: <a href="entries/Partial_Function_MR.html">Mutually Recursive Partial Functions</a>
<br>
Author:
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2014-02-13: <a href="entries/Random_Graph_Subgraph_Threshold.html">Properties of Random Graphs -- Subgraph Containment</a>
<br>
Author:
<a href="https://www21.in.tum.de/~hupel/">Lars Hupel</a>
</td>
</tr>
<tr>
<td class="entry">
2014-02-11: <a href="entries/Selection_Heap_Sort.html">Verification of Selection and Heap Sort Using Locales</a>
<br>
Author:
<a href="http://www.matf.bg.ac.rs/~danijela">Danijela Petrovic</a>
</td>
</tr>
<tr>
<td class="entry">
2014-02-07: <a href="entries/Affine_Arithmetic.html">Affine Arithmetic</a>
<br>
Author:
<a href="http://home.in.tum.de/~immler/">Fabian Immler</a>
</td>
</tr>
<tr>
<td class="entry">
2014-02-06: <a href="entries/Real_Impl.html">Implementing field extensions of the form Q[sqrt(b)]</a>
<br>
Author:
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2014-01-30: <a href="entries/Regex_Equivalence.html">Unified Decision Procedures for Regular Expression Equivalence</a>
<br>
Authors:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
- and <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ and <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2014-01-28: <a href="entries/Secondary_Sylow.html">Secondary Sylow Theorems</a>
<br>
Author:
Jakob von Raumer
</td>
</tr>
<tr>
<td class="entry">
2014-01-25: <a href="entries/Relation_Algebra.html">Relation Algebra</a>
<br>
Authors:
Alasdair Armstrong,
<a href="https://www-users.cs.york.ac.uk/~simonf/">Simon Foster</a>,
<a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
and Tjark Weber
</td>
</tr>
<tr>
<td class="entry">
2014-01-23: <a href="entries/KAT_and_DRA.html">Kleene Algebra with Tests and Demonic Refinement Algebras</a>
<br>
Authors:
Alasdair Armstrong,
Victor B. F. Gomes
and <a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
</td>
</tr>
<tr>
<td class="entry">
2014-01-16: <a href="entries/Featherweight_OCL.html">Featherweight OCL: A Proposal for a Machine-Checked Formal Semantics for OCL 2.5</a>
<br>
Authors:
Achim D. Brucker,
<a href="https://www.lri.fr/~ftuong/">Frédéric Tuong</a>
and <a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
</td>
</tr>
<tr>
<td class="entry">
2014-01-11: <a href="entries/Sturm_Sequences.html">Sturm's Theorem</a>
<br>
Author:
<a href="https://www21.in.tum.de/~eberlm">Manuel Eberl</a>
</td>
</tr>
<tr>
<td class="entry">
2014-01-11: <a href="entries/CryptoBasedCompositionalProperties.html">Compositional Properties of Crypto-Based Components</a>
<br>
Author:
Maria Spichkova
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2013</td>
</tr>
<tr>
<td class="entry">
2013-12-01: <a href="entries/Tail_Recursive_Functions.html">A General Method for the Proof of Theorems on Tail-recursive Functions</a>
<br>
Author:
Pasquale Noce
</td>
</tr>
<tr>
<td class="entry">
2013-11-17: <a href="entries/Incompleteness.html">Gödel's Incompleteness Theorems</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2013-11-17: <a href="entries/HereditarilyFinite.html">The Hereditarily Finite Sets</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2013-11-15: <a href="entries/Coinductive_Languages.html">A Codatatype of Formal Languages</a>
<br>
Author:
- <a href="http://people.inf.ethz.ch/trayteld/">Dmitriy Traytel</a>
+ <a href="https://traytel.bitbucket.io">Dmitriy Traytel</a>
</td>
</tr>
<tr>
<td class="entry">
2013-11-14: <a href="entries/FocusStreamsCaseStudies.html">Stream Processing Components: Isabelle/HOL Formalisation and Case Studies</a>
<br>
Author:
Maria Spichkova
</td>
</tr>
<tr>
<td class="entry">
2013-11-12: <a href="entries/GoedelGod.html">Gödel's God in Isabelle/HOL</a>
<br>
Authors:
<a href="http://christoph-benzmueller.de">Christoph Benzmüller</a>
and <a href="http://www.logic.at/staff/bruno/">Bruno Woltzenlogel Paleo</a>
</td>
</tr>
<tr>
<td class="entry">
2013-11-01: <a href="entries/Decreasing-Diagrams.html">Decreasing Diagrams</a>
<br>
Author:
<a href="http://cl-informatik.uibk.ac.at/users/hzankl">Harald Zankl</a>
</td>
</tr>
<tr>
<td class="entry">
2013-10-02: <a href="entries/Automatic_Refinement.html">Automatic Data Refinement</a>
<br>
Author:
Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2013-09-17: <a href="entries/Native_Word.html">Native Word</a>
<br>
Author:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="entry">
2013-07-27: <a href="entries/IEEE_Floating_Point.html">A Formal Model of IEEE Floating Point Arithmetic</a>
<br>
Author:
Lei Yu
</td>
</tr>
<tr>
<td class="entry">
2013-07-22: <a href="entries/Pratt_Certificate.html">Pratt's Primality Certificates</a>
<br>
Authors:
<a href="http://home.in.tum.de/~wimmers/">Simon Wimmer</a>
and <a href="http://www21.in.tum.de/~noschinl/">Lars Noschinski</a>
</td>
</tr>
<tr>
<td class="entry">
2013-07-22: <a href="entries/Lehmer.html">Lehmer's Theorem</a>
<br>
Authors:
<a href="http://home.in.tum.de/~wimmers/">Simon Wimmer</a>
and <a href="http://www21.in.tum.de/~noschinl/">Lars Noschinski</a>
</td>
</tr>
<tr>
<td class="entry">
2013-07-19: <a href="entries/Koenigsberg_Friendship.html">The Königsberg Bridge Problem and the Friendship Theorem</a>
<br>
Author:
<a href="https://www.cl.cam.ac.uk/~wl302/">Wenda Li</a>
</td>
</tr>
<tr>
<td class="entry">
2013-06-27: <a href="entries/Sort_Encodings.html">Sound and Complete Sort Encodings for First-Order Logic</a>
<br>
Authors:
Jasmin Christian Blanchette
- and Andrei Popescu
+ and <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
</td>
</tr>
<tr>
<td class="entry">
2013-05-22: <a href="entries/ShortestPath.html">An Axiomatic Characterization of the Single-Source Shortest Path Problem</a>
<br>
Author:
Christine Rizkallah
</td>
</tr>
<tr>
<td class="entry">
2013-04-28: <a href="entries/Graph_Theory.html">Graph Theory</a>
<br>
Author:
<a href="http://www21.in.tum.de/~noschinl/">Lars Noschinski</a>
</td>
</tr>
<tr>
<td class="entry">
2013-04-15: <a href="entries/Containers.html">Light-weight Containers</a>
<br>
Author:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="entry">
2013-02-21: <a href="entries/Nominal2.html">Nominal 2</a>
<br>
Authors:
<a href="http://www.inf.kcl.ac.uk/staff/urbanc/">Christian Urban</a>,
<a href="http://www.in.tum.de/~berghofe">Stefan Berghofer</a>
and <a href="http://cl-informatik.uibk.ac.at/cek/">Cezary Kaliszyk</a>
</td>
</tr>
<tr>
<td class="entry">
2013-01-31: <a href="entries/Launchbury.html">The Correctness of Launchbury's Natural Semantics for Lazy Evaluation</a>
<br>
Author:
Joachim Breitner
</td>
</tr>
<tr>
<td class="entry">
2013-01-19: <a href="entries/Ribbon_Proofs.html">Ribbon Proofs</a>
<br>
Author:
John Wickerson
</td>
</tr>
<tr>
<td class="entry">
2013-01-16: <a href="entries/Rank_Nullity_Theorem.html">Rank-Nullity Theorem in Linear Algebra</a>
<br>
Authors:
<a href="https://www.unirioja.es/cu/jodivaso/">Jose Divasón</a>
and <a href="http://www.unirioja.es/cu/jearansa">Jesús Aransay</a>
</td>
</tr>
<tr>
<td class="entry">
2013-01-15: <a href="entries/Kleene_Algebra.html">Kleene Algebra</a>
<br>
Authors:
Alasdair Armstrong,
<a href="http://staffwww.dcs.shef.ac.uk/people/G.Struth/">Georg Struth</a>
and Tjark Weber
</td>
</tr>
<tr>
<td class="entry">
2013-01-03: <a href="entries/Sqrt_Babylonian.html">Computing N-th Roots using the Babylonian Method</a>
<br>
Author:
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2012</td>
</tr>
<tr>
<td class="entry">
2012-11-14: <a href="entries/Separation_Logic_Imperative_HOL.html">A Separation Logic Framework for Imperative HOL</a>
<br>
Authors:
Peter Lammich
and Rene Meis
</td>
</tr>
<tr>
<td class="entry">
2012-11-02: <a href="entries/Open_Induction.html">Open Induction</a>
<br>
Authors:
Mizuhito Ogawa
and Christian Sternagel
</td>
</tr>
<tr>
<td class="entry">
2012-10-30: <a href="entries/Tarskis_Geometry.html">The independence of Tarski's Euclidean axiom</a>
<br>
Author:
T. J. M. Makarios
</td>
</tr>
<tr>
<td class="entry">
2012-10-27: <a href="entries/Bondy.html">Bondy's Theorem</a>
<br>
Authors:
<a href="http://www.andrew.cmu.edu/user/avigad/">Jeremy Avigad</a>
and <a href="http://www.logic.at/people/hetzl/">Stefan Hetzl</a>
</td>
</tr>
<tr>
<td class="entry">
2012-09-10: <a href="entries/Possibilistic_Noninterference.html">Possibilistic Noninterference</a>
<br>
Authors:
- Andrei Popescu
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
and <a href="http://in.tum.de/~hoelzl">Johannes Hölzl</a>
</td>
</tr>
<tr>
<td class="entry">
2012-08-07: <a href="entries/Datatype_Order_Generator.html">Generating linear orders for datatypes</a>
<br>
Author:
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2012-08-05: <a href="entries/Impossible_Geometry.html">Proving the Impossibility of Trisecting an Angle and Doubling the Cube</a>
<br>
Authors:
Ralph Romanos
and <a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2012-07-27: <a href="entries/Heard_Of.html">Verifying Fault-Tolerant Distributed Algorithms in the Heard-Of Model</a>
<br>
Authors:
Henri Debrat
and <a href="http://www.loria.fr/~merz">Stephan Merz</a>
</td>
</tr>
<tr>
<td class="entry">
2012-07-01: <a href="entries/PCF.html">Logical Relations for PCF</a>
<br>
Author:
<a href="http://peteg.org">Peter Gammie</a>
</td>
</tr>
<tr>
<td class="entry">
2012-06-26: <a href="entries/Tycon.html">Type Constructor Classes and Monad Transformers</a>
<br>
Author:
Brian Huffman
</td>
</tr>
<tr>
<td class="entry">
2012-05-29: <a href="entries/Psi_Calculi.html">Psi-calculi in Isabelle</a>
<br>
Author:
<a href="http://www.itu.dk/people/jebe">Jesper Bengtson</a>
</td>
</tr>
<tr>
<td class="entry">
2012-05-29: <a href="entries/Pi_Calculus.html">The pi-calculus in nominal logic</a>
<br>
Author:
<a href="http://www.itu.dk/people/jebe">Jesper Bengtson</a>
</td>
</tr>
<tr>
<td class="entry">
2012-05-29: <a href="entries/CCS.html">CCS in nominal logic</a>
<br>
Author:
<a href="http://www.itu.dk/people/jebe">Jesper Bengtson</a>
</td>
</tr>
<tr>
<td class="entry">
2012-05-27: <a href="entries/Circus.html">Isabelle/Circus</a>
<br>
Authors:
Abderrahmane Feliachi,
<a href="https://www.lri.fr/~wolff/">Burkhart Wolff</a>
and Marie-Claude Gaudel
</td>
</tr>
<tr>
<td class="entry">
2012-05-11: <a href="entries/Separation_Algebra.html">Separation Algebra</a>
<br>
Authors:
<a href="http://www.cse.unsw.edu.au/~kleing/">Gerwin Klein</a>,
Rafal Kolanski
and Andrew Boyton
</td>
</tr>
<tr>
<td class="entry">
2012-05-07: <a href="entries/Stuttering_Equivalence.html">Stuttering Equivalence</a>
<br>
Author:
<a href="http://www.loria.fr/~merz">Stephan Merz</a>
</td>
</tr>
<tr>
<td class="entry">
2012-05-02: <a href="entries/Inductive_Confidentiality.html">Inductive Study of Confidentiality</a>
<br>
Author:
<a href="http://www.dmi.unict.it/~giamp/">Giampaolo Bella</a>
</td>
</tr>
<tr>
<td class="entry">
2012-04-26: <a href="entries/Ordinary_Differential_Equations.html">Ordinary Differential Equations</a>
<br>
Authors:
<a href="http://home.in.tum.de/~immler/">Fabian Immler</a>
and <a href="http://in.tum.de/~hoelzl">Johannes Hölzl</a>
</td>
</tr>
<tr>
<td class="entry">
2012-04-13: <a href="entries/Well_Quasi_Orders.html">Well-Quasi-Orders</a>
<br>
Author:
Christian Sternagel
</td>
</tr>
<tr>
<td class="entry">
2012-03-01: <a href="entries/Abortable_Linearizable_Modules.html">Abortable Linearizable Modules</a>
<br>
Authors:
Rachid Guerraoui,
<a href="http://lara.epfl.ch/~kuncak/">Viktor Kuncak</a>
and Giuliano Losa
</td>
</tr>
<tr>
<td class="entry">
2012-02-29: <a href="entries/Transitive-Closure-II.html">Executable Transitive Closures</a>
<br>
Author:
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2012-02-06: <a href="entries/Girth_Chromatic.html">A Probabilistic Proof of the Girth-Chromatic Number Theorem</a>
<br>
Author:
<a href="http://www21.in.tum.de/~noschinl/">Lars Noschinski</a>
</td>
</tr>
<tr>
<td class="entry">
2012-01-30: <a href="entries/Refine_Monadic.html">Refinement for Monadic Programs</a>
<br>
Author:
Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2012-01-30: <a href="entries/Dijkstra_Shortest_Path.html">Dijkstra's Shortest Path Algorithm</a>
<br>
Authors:
Benedikt Nordhoff
and Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2012-01-03: <a href="entries/Markov_Models.html">Markov Models</a>
<br>
Authors:
<a href="http://in.tum.de/~hoelzl">Johannes Hölzl</a>
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2011</td>
</tr>
<tr>
<td class="entry">
2011-11-19: <a href="entries/TLA.html">A Definitional Encoding of TLA* in Isabelle/HOL</a>
<br>
Authors:
<a href="http://homepages.inf.ed.ac.uk/ggrov">Gudmund Grov</a>
and <a href="http://www.loria.fr/~merz">Stephan Merz</a>
</td>
</tr>
<tr>
<td class="entry">
2011-11-09: <a href="entries/Efficient-Mergesort.html">Efficient Mergesort</a>
<br>
Author:
Christian Sternagel
</td>
</tr>
<tr>
<td class="entry">
2011-09-22: <a href="entries/PseudoHoops.html">Pseudo Hoops</a>
<br>
Authors:
George Georgescu,
Laurentiu Leustean
and Viorel Preoteasa
</td>
</tr>
<tr>
<td class="entry">
2011-09-22: <a href="entries/MonoBoolTranAlgebra.html">Algebra of Monotonic Boolean Transformers</a>
<br>
Author:
Viorel Preoteasa
</td>
</tr>
<tr>
<td class="entry">
2011-09-22: <a href="entries/LatticeProperties.html">Lattice Properties</a>
<br>
Author:
Viorel Preoteasa
</td>
</tr>
<tr>
<td class="entry">
2011-08-26: <a href="entries/Myhill-Nerode.html">The Myhill-Nerode Theorem Based on Regular Expressions</a>
<br>
Authors:
Chunhan Wu,
Xingyuan Zhang
and <a href="http://www.inf.kcl.ac.uk/staff/urbanc/">Christian Urban</a>
</td>
</tr>
<tr>
<td class="entry">
2011-08-19: <a href="entries/Gauss-Jordan-Elim-Fun.html">Gauss-Jordan Elimination for Matrices Represented as Functions</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2011-07-21: <a href="entries/Max-Card-Matching.html">Maximum Cardinality Matching</a>
<br>
Author:
Christine Rizkallah
</td>
</tr>
<tr>
<td class="entry">
2011-05-17: <a href="entries/KBPs.html">Knowledge-based programs</a>
<br>
Author:
<a href="http://peteg.org">Peter Gammie</a>
</td>
</tr>
<tr>
<td class="entry">
2011-04-01: <a href="entries/General-Triangle.html">The General Triangle Is Unique</a>
<br>
Author:
Joachim Breitner
</td>
</tr>
<tr>
<td class="entry">
2011-03-14: <a href="entries/Transitive-Closure.html">Executable Transitive Closures of Finite Relations</a>
<br>
Authors:
Christian Sternagel
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2011-02-23: <a href="entries/Nat-Interval-Logic.html">Interval Temporal Logic on Natural Numbers</a>
<br>
Author:
David Trachtenherz
</td>
</tr>
<tr>
<td class="entry">
2011-02-23: <a href="entries/List-Infinite.html">Infinite Lists</a>
<br>
Author:
David Trachtenherz
</td>
</tr>
<tr>
<td class="entry">
2011-02-23: <a href="entries/AutoFocus-Stream.html">AutoFocus Stream Processing for Single-Clocking and Multi-Clocking Semantics</a>
<br>
Author:
David Trachtenherz
</td>
</tr>
<tr>
<td class="entry">
2011-02-07: <a href="entries/LightweightJava.html">Lightweight Java</a>
<br>
Authors:
<a href="http://rok.strnisa.com/lj/">Rok Strniša</a>
and <a href="http://research.microsoft.com/people/mattpark/">Matthew Parkinson</a>
</td>
</tr>
<tr>
<td class="entry">
2011-01-10: <a href="entries/RIPEMD-160-SPARK.html">RIPEMD-160</a>
<br>
Author:
<a href="http://home.in.tum.de/~immler/">Fabian Immler</a>
</td>
</tr>
<tr>
<td class="entry">
2011-01-08: <a href="entries/Lower_Semicontinuous.html">Lower Semicontinuous Functions</a>
<br>
Author:
Bogdan Grechuk
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2010</td>
</tr>
<tr>
<td class="entry">
2010-12-17: <a href="entries/Marriage.html">Hall's Marriage Theorem</a>
<br>
Authors:
Dongchen Jiang
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2010-11-16: <a href="entries/Shivers-CFA.html">Shivers' Control Flow Analysis</a>
<br>
Author:
Joachim Breitner
</td>
</tr>
<tr>
<td class="entry">
2010-10-28: <a href="entries/Finger-Trees.html">Finger Trees</a>
<br>
Authors:
Benedikt Nordhoff,
Stefan Körner
and Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2010-10-28: <a href="entries/Binomial-Queues.html">Functional Binomial Queues</a>
<br>
Author:
René Neumann
</td>
</tr>
<tr>
<td class="entry">
2010-10-28: <a href="entries/Binomial-Heaps.html">Binomial Heaps and Skew Binomial Heaps</a>
<br>
Authors:
Rene Meis,
Finn Nielsen
and Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2010-08-29: <a href="entries/Lam-ml-Normalization.html">Strong Normalization of Moggis's Computational Metalanguage</a>
<br>
Author:
Christian Doczkal
</td>
</tr>
<tr>
<td class="entry">
2010-08-10: <a href="entries/Polynomials.html">Executable Multivariate Polynomials</a>
<br>
Authors:
Christian Sternagel,
<a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>,
<a href="https://risc.jku.at/m/alexander-maletzky/">Alexander Maletzky</a>,
<a href="http://home.in.tum.de/~immler/">Fabian Immler</a>,
<a href="http://isabelle.in.tum.de/~haftmann">Florian Haftmann</a>,
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
and Alexander Bentkamp
</td>
</tr>
<tr>
<td class="entry">
2010-08-08: <a href="entries/Statecharts.html">Formalizing Statecharts using Hierarchical Automata</a>
<br>
Authors:
Steffen Helke
and Florian Kammüller
</td>
</tr>
<tr>
<td class="entry">
2010-06-24: <a href="entries/Free-Groups.html">Free Groups</a>
<br>
Author:
Joachim Breitner
</td>
</tr>
<tr>
<td class="entry">
2010-06-20: <a href="entries/Category2.html">Category Theory</a>
<br>
Author:
Alexander Katovsky
</td>
</tr>
<tr>
<td class="entry">
2010-06-17: <a href="entries/Matrix.html">Executable Matrix Operations on Matrices of Arbitrary Dimensions</a>
<br>
Authors:
Christian Sternagel
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2010-06-14: <a href="entries/Abstract-Rewriting.html">Abstract Rewriting</a>
<br>
Authors:
Christian Sternagel
and <a href="http://cl-informatik.uibk.ac.at/~thiemann/">René Thiemann</a>
</td>
</tr>
<tr>
<td class="entry">
2010-05-28: <a href="entries/GraphMarkingIBP.html">Verification of the Deutsch-Schorr-Waite Graph Marking Algorithm using Data Refinement</a>
<br>
Authors:
Viorel Preoteasa
and <a href="http://users.abo.fi/Ralph-Johan.Back/">Ralph-Johan Back</a>
</td>
</tr>
<tr>
<td class="entry">
2010-05-28: <a href="entries/DataRefinementIBP.html">Semantics and Data Refinement of Invariant Based Programs</a>
<br>
Authors:
Viorel Preoteasa
and <a href="http://users.abo.fi/Ralph-Johan.Back/">Ralph-Johan Back</a>
</td>
</tr>
<tr>
<td class="entry">
2010-05-22: <a href="entries/Robbins-Conjecture.html">A Complete Proof of the Robbins Conjecture</a>
<br>
Author:
Matthew Wampler-Doty
</td>
</tr>
<tr>
<td class="entry">
2010-05-12: <a href="entries/Regular-Sets.html">Regular Sets and Expressions</a>
<br>
Authors:
<a href="http://www.in.tum.de/~krauss">Alexander Krauss</a>
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2010-04-30: <a href="entries/Locally-Nameless-Sigma.html">Locally Nameless Sigma Calculus</a>
<br>
Authors:
Ludovic Henrio,
Florian Kammüller,
Bianca Lutz
and Henry Sudhof
</td>
</tr>
<tr>
<td class="entry">
2010-03-29: <a href="entries/Free-Boolean-Algebra.html">Free Boolean Algebra</a>
<br>
Author:
Brian Huffman
</td>
</tr>
<tr>
<td class="entry">
2010-03-23: <a href="entries/InformationFlowSlicing_Inter.html">Inter-Procedural Information Flow Noninterference via Slicing</a>
<br>
Author:
<a href="http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php">Daniel Wasserrab</a>
</td>
</tr>
<tr>
<td class="entry">
2010-03-23: <a href="entries/InformationFlowSlicing.html">Information Flow Noninterference via Slicing</a>
<br>
Author:
<a href="http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php">Daniel Wasserrab</a>
</td>
</tr>
<tr>
<td class="entry">
2010-02-20: <a href="entries/List-Index.html">List Index</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2010-02-12: <a href="entries/Coinductive.html">Coinductive</a>
<br>
Author:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2009</td>
</tr>
<tr>
<td class="entry">
2009-12-09: <a href="entries/DPT-SAT-Solver.html">A Fast SAT Solver for Isabelle in Standard ML</a>
<br>
Author:
Armin Heller
</td>
</tr>
<tr>
<td class="entry">
2009-12-03: <a href="entries/Presburger-Automata.html">Formalizing the Logic-Automaton Connection</a>
<br>
Authors:
<a href="http://www.in.tum.de/~berghofe">Stefan Berghofer</a>
and Markus Reiter
</td>
</tr>
<tr>
<td class="entry">
2009-11-25: <a href="entries/Tree-Automata.html">Tree Automata</a>
<br>
Author:
Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2009-11-25: <a href="entries/Collections.html">Collections Framework</a>
<br>
Author:
Peter Lammich
</td>
</tr>
<tr>
<td class="entry">
2009-11-22: <a href="entries/Perfect-Number-Thm.html">Perfect Number Theorem</a>
<br>
Author:
Mark Ijbema
</td>
</tr>
<tr>
<td class="entry">
2009-11-13: <a href="entries/HRB-Slicing.html">Backing up Slicing: Verifying the Interprocedural Two-Phase Horwitz-Reps-Binkley Slicer</a>
<br>
Author:
<a href="http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php">Daniel Wasserrab</a>
</td>
</tr>
<tr>
<td class="entry">
2009-10-30: <a href="entries/WorkerWrapper.html">The Worker/Wrapper Transformation</a>
<br>
Author:
<a href="http://peteg.org">Peter Gammie</a>
</td>
</tr>
<tr>
<td class="entry">
2009-09-01: <a href="entries/Ordinals_and_Cardinals.html">Ordinals and Cardinals</a>
<br>
Author:
- Andrei Popescu
+ <a href="https://www.andreipopescu.uk">Andrei Popescu</a>
</td>
</tr>
<tr>
<td class="entry">
2009-08-28: <a href="entries/SequentInvertibility.html">Invertibility in Sequent Calculi</a>
<br>
Author:
Peter Chapman
</td>
</tr>
<tr>
<td class="entry">
2009-08-04: <a href="entries/CofGroups.html">An Example of a Cofinitary Group in Isabelle/HOL</a>
<br>
Author:
<a href="http://kasterma.net">Bart Kastermans</a>
</td>
</tr>
<tr>
<td class="entry">
2009-05-06: <a href="entries/FinFun.html">Code Generation for Functions as Data</a>
<br>
Author:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="entry">
2009-04-29: <a href="entries/Stream-Fusion.html">Stream Fusion</a>
<br>
Author:
Brian Huffman
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2008</td>
</tr>
<tr>
<td class="entry">
2008-12-12: <a href="entries/BytecodeLogicJmlTypes.html">A Bytecode Logic for JML and Types</a>
<br>
Authors:
Lennart Beringer
and <a href="http://www.tcs.informatik.uni-muenchen.de/~mhofmann">Martin Hofmann</a>
</td>
</tr>
<tr>
<td class="entry">
2008-11-10: <a href="entries/SIFPL.html">Secure information flow and program logics</a>
<br>
Authors:
Lennart Beringer
and <a href="http://www.tcs.informatik.uni-muenchen.de/~mhofmann">Martin Hofmann</a>
</td>
</tr>
<tr>
<td class="entry">
2008-11-09: <a href="entries/SenSocialChoice.html">Some classical results in Social Choice Theory</a>
<br>
Author:
<a href="http://peteg.org">Peter Gammie</a>
</td>
</tr>
<tr>
<td class="entry">
2008-11-07: <a href="entries/FunWithTilings.html">Fun With Tilings</a>
<br>
Authors:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
and <a href="https://www.cl.cam.ac.uk/~lp15/">Lawrence C. Paulson</a>
</td>
</tr>
<tr>
<td class="entry">
2008-10-15: <a href="entries/Huffman.html">The Textbook Proof of Huffman's Algorithm</a>
<br>
Author:
Jasmin Christian Blanchette
</td>
</tr>
<tr>
<td class="entry">
2008-09-16: <a href="entries/Slicing.html">Towards Certified Slicing</a>
<br>
Author:
<a href="http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php">Daniel Wasserrab</a>
</td>
</tr>
<tr>
<td class="entry">
2008-09-02: <a href="entries/VolpanoSmith.html">A Correctness Proof for the Volpano/Smith Security Typing System</a>
<br>
Authors:
<a href="http://pp.info.uni-karlsruhe.de/personhp/gregor_snelting.php">Gregor Snelting</a>
and <a href="http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php">Daniel Wasserrab</a>
</td>
</tr>
<tr>
<td class="entry">
2008-09-01: <a href="entries/ArrowImpossibilityGS.html">Arrow and Gibbard-Satterthwaite</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2008-08-26: <a href="entries/FunWithFunctions.html">Fun With Functions</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2008-07-23: <a href="entries/SATSolverVerification.html">Formal Verification of Modern SAT Solvers</a>
<br>
Author:
Filip Marić
</td>
</tr>
<tr>
<td class="entry">
2008-04-05: <a href="entries/Recursion-Theory-I.html">Recursion Theory I</a>
<br>
Author:
Michael Nedzelsky
</td>
</tr>
<tr>
<td class="entry">
2008-02-29: <a href="entries/Simpl.html">A Sequential Imperative Programming Language Syntax, Semantics, Hoare Logics and Verification Environment</a>
<br>
Author:
Norbert Schirmer
</td>
</tr>
<tr>
<td class="entry">
2008-02-29: <a href="entries/BDD.html">BDD Normalisation</a>
<br>
Authors:
Veronika Ortner
and Norbert Schirmer
</td>
</tr>
<tr>
<td class="entry">
2008-02-18: <a href="entries/NormByEval.html">Normalization by Evaluation</a>
<br>
Authors:
<a href="http://www.linta.de/~aehlig/">Klaus Aehlig</a>
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2008-01-11: <a href="entries/LinearQuantifierElim.html">Quantifier Elimination for Linear Arithmetic</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2007</td>
</tr>
<tr>
<td class="entry">
2007-12-14: <a href="entries/Program-Conflict-Analysis.html">Formalization of Conflict Analysis of Programs with Procedures, Thread Creation, and Monitors</a>
<br>
Authors:
Peter Lammich
and <a href="http://cs.uni-muenster.de/u/mmo/">Markus Müller-Olm</a>
</td>
</tr>
<tr>
<td class="entry">
2007-12-03: <a href="entries/JinjaThreads.html">Jinja with Threads</a>
<br>
Author:
<a href="http://www.andreas-lochbihler.de">Andreas Lochbihler</a>
</td>
</tr>
<tr>
<td class="entry">
2007-11-06: <a href="entries/MuchAdoAboutTwo.html">Much Ado About Two</a>
<br>
Author:
<a href="http://www21.in.tum.de/~boehmes/">Sascha Böhme</a>
</td>
</tr>
<tr>
<td class="entry">
2007-08-12: <a href="entries/SumSquares.html">Sums of Two and Four Squares</a>
<br>
Author:
Roelof Oosterhuis
</td>
</tr>
<tr>
<td class="entry">
2007-08-12: <a href="entries/Fermat3_4.html">Fermat's Last Theorem for Exponents 3 and 4 and the Parametrisation of Pythagorean Triples</a>
<br>
Author:
Roelof Oosterhuis
</td>
</tr>
<tr>
<td class="entry">
2007-08-08: <a href="entries/Valuation.html">Fundamental Properties of Valuation Theory and Hensel's Lemma</a>
<br>
Author:
Hidetsune Kobayashi
</td>
</tr>
<tr>
<td class="entry">
2007-08-02: <a href="entries/POPLmark-deBruijn.html">POPLmark Challenge Via de Bruijn Indices</a>
<br>
Author:
<a href="http://www.in.tum.de/~berghofe">Stefan Berghofer</a>
</td>
</tr>
<tr>
<td class="entry">
2007-08-02: <a href="entries/FOL-Fitting.html">First-Order Logic According to Fitting</a>
<br>
Author:
<a href="http://www.in.tum.de/~berghofe">Stefan Berghofer</a>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2006</td>
</tr>
<tr>
<td class="entry">
2006-09-09: <a href="entries/HotelKeyCards.html">Hotel Key Card System</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2006-08-08: <a href="entries/Abstract-Hoare-Logics.html">Abstract Hoare Logics</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2006-05-22: <a href="entries/Flyspeck-Tame.html">Flyspeck I: Tame Graphs</a>
<br>
Authors:
Gertrud Bauer
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2006-05-15: <a href="entries/CoreC++.html">CoreC++</a>
<br>
Author:
<a href="http://pp.info.uni-karlsruhe.de/personhp/daniel_wasserrab.php">Daniel Wasserrab</a>
</td>
</tr>
<tr>
<td class="entry">
2006-03-31: <a href="entries/FeatherweightJava.html">A Theory of Featherweight Java in Isabelle/HOL</a>
<br>
Authors:
<a href="http://www.cs.cornell.edu/~jnfoster/">J. Nathan Foster</a>
and <a href="http://research.microsoft.com/en-us/people/dimitris/">Dimitrios Vytiniotis</a>
</td>
</tr>
<tr>
<td class="entry">
2006-03-15: <a href="entries/ClockSynchInst.html">Instances of Schneider's generalized protocol of clock synchronization</a>
<br>
Author:
<a href="http://www.cs.famaf.unc.edu.ar/~damian/">Damián Barsotti</a>
</td>
</tr>
<tr>
<td class="entry">
2006-03-14: <a href="entries/Cauchy.html">Cauchy's Mean Theorem and the Cauchy-Schwarz Inequality</a>
<br>
Author:
Benjamin Porter
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2005</td>
</tr>
<tr>
<td class="entry">
2005-11-11: <a href="entries/Ordinal.html">Countable Ordinals</a>
<br>
Author:
Brian Huffman
</td>
</tr>
<tr>
<td class="entry">
2005-10-12: <a href="entries/FFT.html">Fast Fourier Transform</a>
<br>
Author:
<a href="http://www21.in.tum.de/~ballarin/">Clemens Ballarin</a>
</td>
</tr>
<tr>
<td class="entry">
2005-06-24: <a href="entries/GenClock.html">Formalization of a Generalized Protocol for Clock Synchronization</a>
<br>
Author:
Alwen Tiu
</td>
</tr>
<tr>
<td class="entry">
2005-06-22: <a href="entries/DiskPaxos.html">Proving the Correctness of Disk Paxos</a>
<br>
Authors:
<a href="http://www.fceia.unr.edu.ar/~mauro/">Mauro Jaskelioff</a>
and <a href="http://www.loria.fr/~merz">Stephan Merz</a>
</td>
</tr>
<tr>
<td class="entry">
2005-06-20: <a href="entries/JiveDataStoreModel.html">Jive Data and Store Model</a>
<br>
Authors:
Nicole Rauch
and Norbert Schirmer
</td>
</tr>
<tr>
<td class="entry">
2005-06-01: <a href="entries/Jinja.html">Jinja is not Java</a>
<br>
Authors:
<a href="http://www.cse.unsw.edu.au/~kleing/">Gerwin Klein</a>
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2005-05-02: <a href="entries/RSAPSS.html">SHA1, RSA, PSS and more</a>
<br>
Authors:
Christina Lindenberg
and Kai Wirt
</td>
</tr>
<tr>
<td class="entry">
2005-04-21: <a href="entries/Category.html">Category Theory to Yoneda's Lemma</a>
<br>
Author:
<a href="http://users.rsise.anu.edu.au/~okeefe/">Greg O'Keefe</a>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<table width="80%" class="entries">
<tbody>
<tr>
<td class="head">2004</td>
</tr>
<tr>
<td class="entry">
2004-12-09: <a href="entries/FileRefinement.html">File Refinement</a>
<br>
Authors:
<a href="http://www.mit.edu/~kkz/">Karen Zee</a>
and <a href="http://lara.epfl.ch/~kuncak/">Viktor Kuncak</a>
</td>
</tr>
<tr>
<td class="entry">
2004-11-19: <a href="entries/Integration.html">Integration theory and random variables</a>
<br>
Author:
<a href="http://www-lti.informatik.rwth-aachen.de/~richter/">Stefan Richter</a>
</td>
</tr>
<tr>
<td class="entry">
2004-09-28: <a href="entries/Verified-Prover.html">A Mechanically Verified, Efficient, Sound and Complete Theorem Prover For First Order Logic</a>
<br>
Author:
Tom Ridge
</td>
</tr>
<tr>
<td class="entry">
2004-09-20: <a href="entries/Ramsey-Infinite.html">Ramsey's theorem, infinitary version</a>
<br>
Author:
Tom Ridge
</td>
</tr>
<tr>
<td class="entry">
2004-09-20: <a href="entries/Completeness.html">Completeness theorem</a>
<br>
Authors:
James Margetson
and Tom Ridge
</td>
</tr>
<tr>
<td class="entry">
2004-07-09: <a href="entries/Compiling-Exceptions-Correctly.html">Compiling Exceptions Correctly</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2004-06-24: <a href="entries/Depth-First-Search.html">Depth First Search</a>
<br>
Authors:
Toshiaki Nishihara
and Yasuhiko Minamide
</td>
</tr>
<tr>
<td class="entry">
2004-05-18: <a href="entries/Group-Ring-Module.html">Groups, Rings and Modules</a>
<br>
Authors:
Hidetsune Kobayashi,
L. Chen
and H. Murao
</td>
</tr>
<tr>
<td class="entry">
2004-04-26: <a href="entries/Topology.html">Topology</a>
<br>
Author:
Stefan Friedrich
</td>
</tr>
<tr>
<td class="entry">
2004-04-26: <a href="entries/Lazy-Lists-II.html">Lazy Lists II</a>
<br>
Author:
Stefan Friedrich
</td>
</tr>
<tr>
<td class="entry">
2004-04-05: <a href="entries/BinarySearchTree.html">Binary Search Trees</a>
<br>
Author:
<a href="http://lara.epfl.ch/~kuncak/">Viktor Kuncak</a>
</td>
</tr>
<tr>
<td class="entry">
2004-03-30: <a href="entries/Functional-Automata.html">Functional Automata</a>
<br>
Author:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2004-03-19: <a href="entries/MiniML.html">Mini ML</a>
<br>
Authors:
Wolfgang Naraschewski
and <a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
</td>
</tr>
<tr>
<td class="entry">
2004-03-19: <a href="entries/AVL-Trees.html">AVL Trees</a>
<br>
Authors:
<a href="http://www21.in.tum.de/~nipkow">Tobias Nipkow</a>
and Cornelia Pusch
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
\ 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,626 +1,603 @@
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<atom:link href="https://www.isa-afp.org/rss.xml" rel="self" type="application/rss+xml" />
<title>Archive of Formal Proofs</title>
<link>https://www.isa-afp.org</link>
<description>
The Archive of Formal Proofs is a collection of proof libraries, examples,
and larger scientific developments, mechanically checked
in the theorem prover Isabelle.
</description>
- <pubDate>16 Sep 2020 00:00:00 +0000</pubDate>
+ <pubDate>29 Oct 2020 00:00:00 +0000</pubDate>
+ <item>
+ <title>Verified SAT-Based AI Planning</title>
+ <link>https://www.isa-afp.org/entries/Verified_SAT_Based_AI_Planning.html</link>
+ <guid>https://www.isa-afp.org/entries/Verified_SAT_Based_AI_Planning.html</guid>
+ <dc:creator> Mohammad Abdulaziz, Friedrich Kurz </dc:creator>
+ <pubDate>29 Oct 2020 00:00:00 +0000</pubDate>
+ <description>
+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.</description>
+ </item>
+ <item>
+ <title>AI Planning Languages Semantics</title>
+ <link>https://www.isa-afp.org/entries/AI_Planning_Languages_Semantics.html</link>
+ <guid>https://www.isa-afp.org/entries/AI_Planning_Languages_Semantics.html</guid>
+ <dc:creator> Mohammad Abdulaziz, Peter Lammich </dc:creator>
+ <pubDate>29 Oct 2020 00:00:00 +0000</pubDate>
+ <description>
+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.</description>
+ </item>
+ <item>
+ <title>A Sound Type System for Physical Quantities, Units, and Measurements</title>
+ <link>https://www.isa-afp.org/entries/Physical_Quantities.html</link>
+ <guid>https://www.isa-afp.org/entries/Physical_Quantities.html</guid>
+ <dc:creator> Simon Foster, Burkhart Wolff </dc:creator>
+ <pubDate>20 Oct 2020 00:00:00 +0000</pubDate>
+ <description>
+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&#39;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 &#34;algebra of
+quantities&#34; 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).</description>
+ </item>
+ <item>
+ <title>A Formal Model of the Safely Composable Document Object Model with Shadow Roots</title>
+ <link>https://www.isa-afp.org/entries/Shadow_SC_DOM.html</link>
+ <guid>https://www.isa-afp.org/entries/Shadow_SC_DOM.html</guid>
+ <dc:creator> Achim D. Brucker, Michael Herzberg </dc:creator>
+ <pubDate>28 Sep 2020 00:00:00 +0000</pubDate>
+ <description>
+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 &#34;Shadow DOM&#34;). 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.</description>
+ </item>
+ <item>
+ <title>A Formalization of Safely Composable Web Components</title>
+ <link>https://www.isa-afp.org/entries/SC_DOM_Components.html</link>
+ <guid>https://www.isa-afp.org/entries/SC_DOM_Components.html</guid>
+ <dc:creator> Achim D. Brucker, Michael Herzberg </dc:creator>
+ <pubDate>28 Sep 2020 00:00:00 +0000</pubDate>
+ <description>
+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
+&#34;DOM_Components&#34;, the notion of components in this entry
+(based on &#34;SC_DOM&#34; and &#34;Shadow_SC_DOM&#34;) provides
+much stronger safety guarantees.</description>
+ </item>
+ <item>
+ <title>The Safely Composable DOM</title>
+ <link>https://www.isa-afp.org/entries/Core_SC_DOM.html</link>
+ <guid>https://www.isa-afp.org/entries/Core_SC_DOM.html</guid>
+ <dc:creator> Achim D. Brucker, Michael Herzberg </dc:creator>
+ <pubDate>28 Sep 2020 00:00:00 +0000</pubDate>
+ <description>
+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 &#34;Core DOM&#34;) 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&#39;&#39;
+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.</description>
+ </item>
<item>
<title>Syntax-Independent Logic Infrastructure</title>
<link>https://www.isa-afp.org/entries/Syntax_Independent_Logic.html</link>
<guid>https://www.isa-afp.org/entries/Syntax_Independent_Logic.html</guid>
<dc:creator> Andrei Popescu, Dmitriy Traytel </dc:creator>
<pubDate>16 Sep 2020 00:00:00 +0000</pubDate>
<description>
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&#39;
assumptions. We instantiate the syntax-independent logic
infrastructure to Robinson arithmetic (also known as Q) in the AFP
entry &lt;a
href=&#34;https://www.isa-afp.org/entries/Robinson_Arithmetic.html&#34;&gt;Robinson_Arithmetic&lt;/a&gt;
and to hereditarily finite set theory in the AFP entries &lt;a
href=&#34;https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html&#34;&gt;Goedel_HFSet_Semantic&lt;/a&gt;
and &lt;a
href=&#34;https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html&#34;&gt;Goedel_HFSet_Semanticless&lt;/a&gt;,
which are part of our formalization of G&amp;ouml;del&#39;s
Incompleteness Theorems described in our CADE-27 paper &lt;a
href=&#34;https://dx.doi.org/10.1007/978-3-030-29436-6_26&#34;&gt;A
Formally Verified Abstract Account of Gödel&#39;s Incompleteness
Theorems&lt;/a&gt;.</description>
</item>
<item>
<title>Robinson Arithmetic</title>
<link>https://www.isa-afp.org/entries/Robinson_Arithmetic.html</link>
<guid>https://www.isa-afp.org/entries/Robinson_Arithmetic.html</guid>
<dc:creator> Andrei Popescu, Dmitriy Traytel </dc:creator>
<pubDate>16 Sep 2020 00:00:00 +0000</pubDate>
<description>
We instantiate our syntax-independent logic infrastructure developed
in &lt;a
href=&#34;https://www.isa-afp.org/entries/Syntax_Independent_Logic.html&#34;&gt;a
separate AFP entry&lt;/a&gt; to the FOL theory of Robinson arithmetic
(also known as Q). The latter was formalised using Nominal Isabelle by
adapting &lt;a
href=&#34;https://www.isa-afp.org/entries/Incompleteness.html&#34;&gt;Larry
Paulson’s formalization of the Hereditarily Finite Set
theory&lt;/a&gt;.</description>
</item>
<item>
<title>An Abstract Formalization of G&ouml;del's Incompleteness Theorems</title>
<link>https://www.isa-afp.org/entries/Goedel_Incompleteness.html</link>
<guid>https://www.isa-afp.org/entries/Goedel_Incompleteness.html</guid>
<dc:creator> Andrei Popescu, Dmitriy Traytel </dc:creator>
<pubDate>16 Sep 2020 00:00:00 +0000</pubDate>
<description>
We present an abstract formalization of G&amp;ouml;del&#39;s
incompleteness theorems. We analyze sufficient conditions for the
theorems&#39; applicability to a partially specified logic. Our
abstract perspective enables a comparison between alternative
approaches from the literature. These include Rosser&#39;s variation
of the first theorem, Jeroslow&#39;s variation of the second theorem,
and the Swierczkowski&amp;ndash;Paulson semantics-based approach. This
AFP entry is the main entry point to the results described in our
CADE-27 paper &lt;a
href=&#34;https://dx.doi.org/10.1007/978-3-030-29436-6_26&#34;&gt;A
Formally Verified Abstract Account of Gödel&#39;s Incompleteness
Theorems&lt;/a&gt;. As part of our abstract formalization&#39;s
validation, we instantiate our locales twice in the separate AFP
entries &lt;a
href=&#34;https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html&#34;&gt;Goedel_HFSet_Semantic&lt;/a&gt;
and &lt;a
href=&#34;https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html&#34;&gt;Goedel_HFSet_Semanticless&lt;/a&gt;.</description>
</item>
<item>
<title>From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part II</title>
<link>https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html</link>
<guid>https://www.isa-afp.org/entries/Goedel_HFSet_Semanticless.html</guid>
<dc:creator> Andrei Popescu, Dmitriy Traytel </dc:creator>
<pubDate>16 Sep 2020 00:00:00 +0000</pubDate>
<description>
We validate an abstract formulation of G&amp;ouml;del&#39;s Second
Incompleteness Theorem from a &lt;a
href=&#34;https://www.isa-afp.org/entries/Goedel_Incompleteness.html&#34;&gt;separate
AFP entry&lt;/a&gt; by instantiating it to the case of &lt;i&gt;finite
consistent extensions of the Hereditarily Finite (HF) Set
theory&lt;/i&gt;, 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 &lt;a
href=&#34;https://www.isa-afp.org/entries/Incompleteness.html&#34;&gt;direct
formalisation of the concrete result&lt;/a&gt;. It strengthens
Paulson&#39;s formalization of G&amp;ouml;del&#39;s Second from that
entry by &lt;i&gt;not&lt;/i&gt; 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&#39;s (modified) lemmas to instantiate
our soundness-free G&amp;ouml;del&#39;s Second locale.</description>
</item>
<item>
<title>From Abstract to Concrete G&ouml;del's Incompleteness Theorems&mdash;Part I</title>
<link>https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html</link>
<guid>https://www.isa-afp.org/entries/Goedel_HFSet_Semantic.html</guid>
<dc:creator> Andrei Popescu, Dmitriy Traytel </dc:creator>
<pubDate>16 Sep 2020 00:00:00 +0000</pubDate>
<description>
We validate an abstract formulation of G&amp;ouml;del&#39;s First and
Second Incompleteness Theorems from a &lt;a
href=&#34;https://www.isa-afp.org/entries/Goedel_Incompleteness.html&#34;&gt;separate
AFP entry&lt;/a&gt; by instantiating them to the case of
&lt;i&gt;finite sound extensions of the Hereditarily Finite (HF) Set
theory&lt;/i&gt;, 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 &lt;a
href=&#34;https://www.isa-afp.org/entries/Incompleteness.html&#34;&gt;AFP
entry by Larry Paulson&lt;/a&gt;; our instantiation reuses the
infrastructure developed in that entry.</description>
</item>
<item>
<title>A Formal Model of Extended Finite State Machines</title>
<link>https://www.isa-afp.org/entries/Extended_Finite_State_Machines.html</link>
<guid>https://www.isa-afp.org/entries/Extended_Finite_State_Machines.html</guid>
<dc:creator> Michael Foster, Achim D. Brucker, Ramsay G. Taylor, John Derrick </dc:creator>
<pubDate>07 Sep 2020 00:00:00 +0000</pubDate>
<description>
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.</description>
</item>
<item>
<title>Inference of Extended Finite State Machines</title>
<link>https://www.isa-afp.org/entries/Extended_Finite_State_Machine_Inference.html</link>
<guid>https://www.isa-afp.org/entries/Extended_Finite_State_Machine_Inference.html</guid>
<dc:creator> Michael Foster, Achim D. Brucker, Ramsay G. Taylor, John Derrick </dc:creator>
<pubDate>07 Sep 2020 00:00:00 +0000</pubDate>
<description>
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.</description>
</item>
<item>
<title>Practical Algebraic Calculus Checker</title>
<link>https://www.isa-afp.org/entries/PAC_Checker.html</link>
<guid>https://www.isa-afp.org/entries/PAC_Checker.html</guid>
<dc:creator> Mathias Fleury, Daniela Kaufmann </dc:creator>
<pubDate>31 Aug 2020 00:00:00 +0000</pubDate>
<description>
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&#39;20 tool presentation.</description>
</item>
<item>
<title>Some classical results in inductive inference of recursive functions</title>
<link>https://www.isa-afp.org/entries/Inductive_Inference.html</link>
<guid>https://www.isa-afp.org/entries/Inductive_Inference.html</guid>
<dc:creator> Frank J. Balbach </dc:creator>
<pubDate>31 Aug 2020 00:00:00 +0000</pubDate>
<description>
&lt;p&gt; This entry formalizes some classical concepts and results
from inductive inference of recursive functions. In the basic setting
a partial recursive function (&#34;strategy&#34;) must identify
(&#34;learn&#34;) all functions from a set (&#34;class&#34;) 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 (&#34;hypotheses&#34;) converges to a
description of $f$. A class of functions learnable in this sense is
called &#34;learnable in the limit&#34;. The set of all these
classes is denoted by LIM. &lt;/p&gt; &lt;p&gt; 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. &lt;/p&gt; &lt;p&gt; The above
is based on a formalization of recursive functions heavily inspired by
the &lt;a
href=&#34;https://www.isa-afp.org/entries/Universal_Turing_Machine.html&#34;&gt;Universal
Turing Machine&lt;/a&gt; entry by Xu et al., but different in that it
models partial functions with codomain &lt;em&gt;nat
option&lt;/em&gt;. 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
&lt;em&gt;s-m-n&lt;/em&gt; theorem, Rice&#39;s theorem, and assorted
fixed-point theorems (recursion theorems) by Kleene, Rogers, and
Smullyan. &lt;/p&gt;</description>
</item>
<item>
<title>Relational Disjoint-Set Forests</title>
<link>https://www.isa-afp.org/entries/Relational_Disjoint_Set_Forests.html</link>
<guid>https://www.isa-afp.org/entries/Relational_Disjoint_Set_Forests.html</guid>
<dc:creator> Walter Guttmann </dc:creator>
<pubDate>26 Aug 2020 00:00:00 +0000</pubDate>
<description>
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.</description>
</item>
<item>
<title>Extensions to the Comprehensive Framework for Saturation Theorem Proving</title>
<link>https://www.isa-afp.org/entries/Saturation_Framework_Extensions.html</link>
<guid>https://www.isa-afp.org/entries/Saturation_Framework_Extensions.html</guid>
<dc:creator> Jasmin Blanchette, Sophie Tourret </dc:creator>
<pubDate>25 Aug 2020 00:00:00 +0000</pubDate>
<description>
This Isabelle/HOL formalization extends the AFP entry
&lt;em&gt;Saturation_Framework&lt;/em&gt; with the following
contributions: &lt;ul&gt; &lt;li&gt;an application of the framework
to prove Bachmair and Ganzinger&#39;s resolution prover RP
refutationally complete, which was formalized in a more ad hoc fashion
by Schlichtkrull et al. in the AFP entry
&lt;em&gt;Ordered_Resultion_Prover&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;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;&lt;/li&gt;
&lt;li&gt;alternative proofs of fairness (and hence saturation and
ultimately refutational completeness) for the given clause procedures
GC and LGC, based on invariance.&lt;/li&gt; &lt;/ul&gt;</description>
</item>
<item>
<title>Putting the `K' into Bird's derivation of Knuth-Morris-Pratt string matching</title>
<link>https://www.isa-afp.org/entries/BirdKMP.html</link>
<guid>https://www.isa-afp.org/entries/BirdKMP.html</guid>
<dc:creator> Peter Gammie </dc:creator>
<pubDate>25 Aug 2020 00:00:00 +0000</pubDate>
<description>
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&#39;s derivation and complete it by adding Knuth&#39;s
optimisation.</description>
</item>
<item>
<title>Amicable Numbers</title>
<link>https://www.isa-afp.org/entries/Amicable_Numbers.html</link>
<guid>https://www.isa-afp.org/entries/Amicable_Numbers.html</guid>
<dc:creator> Angeliki Koutsoukou-Argyraki </dc:creator>
<pubDate>04 Aug 2020 00:00:00 +0000</pubDate>
<description>
This is a formalisation of Amicable Numbers, involving some relevant
material including Euler&#39;s sigma function, some relevant
definitions, results and examples as well as rules such as
Th&amp;#257;bit ibn Qurra&#39;s Rule, Euler&#39;s Rule, te
Riele&#39;s Rule and Borho&#39;s Rule with breeders.</description>
</item>
<item>
<title>Ordinal Partitions</title>
<link>https://www.isa-afp.org/entries/Ordinal_Partitions.html</link>
<guid>https://www.isa-afp.org/entries/Ordinal_Partitions.html</guid>
<dc:creator> Lawrence C. Paulson </dc:creator>
<pubDate>03 Aug 2020 00:00:00 +0000</pubDate>
<description>
The theory of partition relations concerns generalisations of
Ramsey&#39;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&#39;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$.</description>
</item>
<item>
<title>A Formal Proof of The Chandy--Lamport Distributed Snapshot Algorithm</title>
<link>https://www.isa-afp.org/entries/Chandy_Lamport.html</link>
<guid>https://www.isa-afp.org/entries/Chandy_Lamport.html</guid>
<dc:creator> Ben Fiedler, Dmitriy Traytel </dc:creator>
<pubDate>21 Jul 2020 00:00:00 +0000</pubDate>
<description>
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.</description>
</item>
<item>
<title>Relational Characterisations of Paths</title>
<link>https://www.isa-afp.org/entries/Relational_Paths.html</link>
<guid>https://www.isa-afp.org/entries/Relational_Paths.html</guid>
<dc:creator> Walter Guttmann, Peter Höfner </dc:creator>
<pubDate>13 Jul 2020 00:00:00 +0000</pubDate>
<description>
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.</description>
</item>
<item>
<title>A Formally Verified Checker of the Safe Distance Traffic Rules for Autonomous Vehicles</title>
<link>https://www.isa-afp.org/entries/Safe_Distance.html</link>
<guid>https://www.isa-afp.org/entries/Safe_Distance.html</guid>
<dc:creator> Albert Rizaldi, Fabian Immler </dc:creator>
<pubDate>01 Jun 2020 00:00:00 +0000</pubDate>
<description>
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.</description>
</item>
<item>
<title>A verified algorithm for computing the Smith normal form of a matrix</title>
<link>https://www.isa-afp.org/entries/Smith_Normal_Form.html</link>
<guid>https://www.isa-afp.org/entries/Smith_Normal_Form.html</guid>
<dc:creator> Jose Divasón </dc:creator>
<pubDate>23 May 2020 00:00:00 +0000</pubDate>
<description>
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.</description>
</item>
<item>
<title>The Nash-Williams Partition Theorem</title>
<link>https://www.isa-afp.org/entries/Nash_Williams.html</link>
<guid>https://www.isa-afp.org/entries/Nash_Williams.html</guid>
<dc:creator> Lawrence C. Paulson </dc:creator>
<pubDate>16 May 2020 00:00:00 +0000</pubDate>
<description>
In 1965, Nash-Williams discovered a generalisation of the infinite
form of Ramsey&#39;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ć.</description>
</item>
<item>
<title>A Formalization of Knuth–Bendix Orders</title>
<link>https://www.isa-afp.org/entries/Knuth_Bendix_Order.html</link>
<guid>https://www.isa-afp.org/entries/Knuth_Bendix_Order.html</guid>
<dc:creator> Christian Sternagel, René Thiemann </dc:creator>
<pubDate>13 May 2020 00:00:00 +0000</pubDate>
<description>
We define a generalized version of Knuth&amp;ndash;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.</description>
</item>
<item>
<title>Irrationality Criteria for Series by Erdős and Straus</title>
<link>https://www.isa-afp.org/entries/Irrational_Series_Erdos_Straus.html</link>
<guid>https://www.isa-afp.org/entries/Irrational_Series_Erdos_Straus.html</guid>
<dc:creator> Angeliki Koutsoukou-Argyraki, Wenda Li </dc:creator>
<pubDate>12 May 2020 00:00:00 +0000</pubDate>
<description>
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 &gt;1$ for all large n. The results are due to P. Erdős and E. G. Straus
&lt;a href=&#34;https://projecteuclid.org/euclid.pjm/1102911140&#34;&gt;[1]&lt;/a&gt;.
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.</description>
</item>
<item>
<title>Recursion Theorem in ZF</title>
<link>https://www.isa-afp.org/entries/Recursion-Addition.html</link>
<guid>https://www.isa-afp.org/entries/Recursion-Addition.html</guid>
<dc:creator> Georgy Dunaev </dc:creator>
<pubDate>11 May 2020 00:00:00 +0000</pubDate>
<description>
This document contains a proof of the recursion theorem. This is a
mechanization of the proof of the recursion theorem from the text &lt;i&gt;Introduction to
Set Theory&lt;/i&gt;, 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.</description>
</item>
<item>
<title>An Efficient Normalisation Procedure for Linear Temporal Logic: Isabelle/HOL Formalisation</title>
<link>https://www.isa-afp.org/entries/LTL_Normal_Form.html</link>
<guid>https://www.isa-afp.org/entries/LTL_Normal_Form.html</guid>
<dc:creator> Salomon Sickert </dc:creator>
<pubDate>08 May 2020 00:00:00 +0000</pubDate>
<description>
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.</description>
</item>
<item>
<title>Formalization of Forcing in Isabelle/ZF</title>
<link>https://www.isa-afp.org/entries/Forcing.html</link>
<guid>https://www.isa-afp.org/entries/Forcing.html</guid>
<dc:creator> Emmanuel Gunther, Miguel Pagano, Pedro Sánchez Terraf </dc:creator>
<pubDate>06 May 2020 00:00:00 +0000</pubDate>
<description>
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.</description>
</item>
- <item>
- <title>Banach-Steinhaus Theorem</title>
- <link>https://www.isa-afp.org/entries/Banach_Steinhaus.html</link>
- <guid>https://www.isa-afp.org/entries/Banach_Steinhaus.html</guid>
- <dc:creator> Dominique Unruh, Jose Manuel Rodriguez Caballero </dc:creator>
- <pubDate>02 May 2020 00:00:00 +0000</pubDate>
- <description>
-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.</description>
- </item>
- <item>
- <title>Attack Trees in Isabelle for GDPR compliance of IoT healthcare systems</title>
- <link>https://www.isa-afp.org/entries/Attack_Trees.html</link>
- <guid>https://www.isa-afp.org/entries/Attack_Trees.html</guid>
- <dc:creator> Florian Kammueller </dc:creator>
- <pubDate>27 Apr 2020 00:00:00 +0000</pubDate>
- <description>
-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.</description>
- </item>
- <item>
- <title>Power Sum Polynomials</title>
- <link>https://www.isa-afp.org/entries/Power_Sum_Polynomials.html</link>
- <guid>https://www.isa-afp.org/entries/Power_Sum_Polynomials.html</guid>
- <dc:creator> Manuel Eberl </dc:creator>
- <pubDate>24 Apr 2020 00:00:00 +0000</pubDate>
- <description>
-&lt;p&gt;This article provides a formalisation of the symmetric
-multivariate polynomials known as &lt;em&gt;power sum
-polynomials&lt;/em&gt;. These are of the form
-p&lt;sub&gt;n&lt;/sub&gt;(&lt;em&gt;X&lt;/em&gt;&lt;sub&gt;1&lt;/sub&gt;,&amp;hellip;,
-&lt;em&gt;X&lt;/em&gt;&lt;sub&gt;&lt;em&gt;k&lt;/em&gt;&lt;/sub&gt;) =
-&lt;em&gt;X&lt;/em&gt;&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;n&lt;/sup&gt;
-+ &amp;hellip; +
-X&lt;sub&gt;&lt;em&gt;k&lt;/em&gt;&lt;/sub&gt;&lt;sup&gt;n&lt;/sup&gt;.
-A formal proof of the Girard–Newton Theorem is also given. This
-theorem relates the power sum polynomials to the elementary symmetric
-polynomials s&lt;sub&gt;&lt;em&gt;k&lt;/em&gt;&lt;/sub&gt; in the form
-of a recurrence relation
-(-1)&lt;sup&gt;&lt;em&gt;k&lt;/em&gt;&lt;/sup&gt;
-&lt;em&gt;k&lt;/em&gt; s&lt;sub&gt;&lt;em&gt;k&lt;/em&gt;&lt;/sub&gt;
-=
-&amp;sum;&lt;sub&gt;i&amp;isinv;[0,&lt;em&gt;k&lt;/em&gt;)&lt;/sub&gt;
-(-1)&lt;sup&gt;i&lt;/sup&gt; s&lt;sub&gt;i&lt;/sub&gt;
-p&lt;sub&gt;&lt;em&gt;k&lt;/em&gt;-&lt;em&gt;i&lt;/em&gt;&lt;/sub&gt;&amp;thinsp;.&lt;/p&gt;
-&lt;p&gt;As an application, this is then used to solve a generalised
-form of a puzzle given as an exercise in Dummit and Foote&#39;s
-&lt;em&gt;Abstract Algebra&lt;/em&gt;: For &lt;em&gt;k&lt;/em&gt;
-complex unknowns &lt;em&gt;x&lt;/em&gt;&lt;sub&gt;1&lt;/sub&gt;,
-&amp;hellip;,
-&lt;em&gt;x&lt;/em&gt;&lt;sub&gt;&lt;em&gt;k&lt;/em&gt;&lt;/sub&gt;,
-define p&lt;sub&gt;&lt;em&gt;j&lt;/em&gt;&lt;/sub&gt; :=
-&lt;em&gt;x&lt;/em&gt;&lt;sub&gt;1&lt;/sub&gt;&lt;sup&gt;&lt;em&gt;j&lt;/em&gt;&lt;/sup&gt;
-+ &amp;hellip; +
-&lt;em&gt;x&lt;/em&gt;&lt;sub&gt;&lt;em&gt;k&lt;/em&gt;&lt;/sub&gt;&lt;sup&gt;&lt;em&gt;j&lt;/em&gt;&lt;/sup&gt;.
-Then for each vector &lt;em&gt;a&lt;/em&gt; &amp;isinv;
-&amp;#x2102;&lt;sup&gt;&lt;em&gt;k&lt;/em&gt;&lt;/sup&gt;, show that
-there is exactly one solution to the system p&lt;sub&gt;1&lt;/sub&gt;
-= a&lt;sub&gt;1&lt;/sub&gt;, &amp;hellip;,
-p&lt;sub&gt;&lt;em&gt;k&lt;/em&gt;&lt;/sub&gt; =
-a&lt;sub&gt;&lt;em&gt;k&lt;/em&gt;&lt;/sub&gt; up to permutation of
-the
-&lt;em&gt;x&lt;/em&gt;&lt;sub&gt;&lt;em&gt;i&lt;/em&gt;&lt;/sub&gt;
-and determine the value of
-p&lt;sub&gt;&lt;em&gt;i&lt;/em&gt;&lt;/sub&gt; for
-i&amp;gt;k.&lt;/p&gt;</description>
- </item>
- <item>
- <title>The Lambert W Function on the Reals</title>
- <link>https://www.isa-afp.org/entries/Lambert_W.html</link>
- <guid>https://www.isa-afp.org/entries/Lambert_W.html</guid>
- <dc:creator> Manuel Eberl </dc:creator>
- <pubDate>24 Apr 2020 00:00:00 +0000</pubDate>
- <description>
-&lt;p&gt;The Lambert &lt;em&gt;W&lt;/em&gt; function is a multi-valued
-function defined as the inverse function of &lt;em&gt;x&lt;/em&gt;
-&amp;#x21A6; &lt;em&gt;x&lt;/em&gt;
-e&lt;sup&gt;&lt;em&gt;x&lt;/em&gt;&lt;/sup&gt;. Besides numerous
-applications in combinatorics, physics, and engineering, it also
-frequently occurs when solving equations containing both
-e&lt;sup&gt;&lt;em&gt;x&lt;/em&gt;&lt;/sup&gt; and
-&lt;em&gt;x&lt;/em&gt;, or both &lt;em&gt;x&lt;/em&gt; and log
-&lt;em&gt;x&lt;/em&gt;.&lt;/p&gt; &lt;p&gt;This article provides a
-definition of the two real-valued branches
-&lt;em&gt;W&lt;/em&gt;&lt;sub&gt;0&lt;/sub&gt;(&lt;em&gt;x&lt;/em&gt;)
-and
-&lt;em&gt;W&lt;/em&gt;&lt;sub&gt;-1&lt;/sub&gt;(&lt;em&gt;x&lt;/em&gt;)
-and proves various properties such as basic identities and
-inequalities, monotonicity, differentiability, asymptotic expansions,
-and the MacLaurin series of
-&lt;em&gt;W&lt;/em&gt;&lt;sub&gt;0&lt;/sub&gt;(&lt;em&gt;x&lt;/em&gt;)
-at &lt;em&gt;x&lt;/em&gt; = 0.&lt;/p&gt;</description>
- </item>
- <item>
- <title>Gaussian Integers</title>
- <link>https://www.isa-afp.org/entries/Gaussian_Integers.html</link>
- <guid>https://www.isa-afp.org/entries/Gaussian_Integers.html</guid>
- <dc:creator> Manuel Eberl </dc:creator>
- <pubDate>24 Apr 2020 00:00:00 +0000</pubDate>
- <description>
-&lt;p&gt;The Gaussian integers are the subring &amp;#8484;[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.&lt;/p&gt; &lt;p&gt;Lastly, this Gaussian integer
-formalisation is used in two short applications:&lt;/p&gt; &lt;ol&gt;
-&lt;li&gt; The characterisation of all positive integers that can be
-written as sums of two squares&lt;/li&gt; &lt;li&gt; Euclid&#39;s
-formula for primitive Pythagorean triples&lt;/li&gt; &lt;/ol&gt;
-&lt;p&gt;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.&lt;/p&gt;</description>
- </item>
- <item>
- <title>Matrices for ODEs</title>
- <link>https://www.isa-afp.org/entries/Matrices_for_ODEs.html</link>
- <guid>https://www.isa-afp.org/entries/Matrices_for_ODEs.html</guid>
- <dc:creator> Jonathan Julian Huerta y Munive </dc:creator>
- <pubDate>19 Apr 2020 00:00:00 +0000</pubDate>
- <description>
-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.</description>
- </item>
</channel>
</rss>
diff --git a/web/statistics.html b/web/statistics.html
--- a/web/statistics.html
+++ b/web/statistics.html
@@ -1,307 +1,307 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Archive of Formal Proofs</title>
<link rel="stylesheet" type="text/css" href="front.css">
<link rel="icon" href="images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="rss.xml">
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1><font class="first">S</font>tatistics
</h1>
<p>&nbsp;</p>
<table width="80%" class="descr">
<tbody>
<tr><td>
<h2>Statistics</h2>
<table>
-<tr><td>Number of Articles:</td><td class="statsnumber">561</td></tr>
+<tr><td>Number of Articles:</td><td class="statsnumber">567</td></tr>
<tr><td>Number of Authors:</td><td class="statsnumber">366</td></tr>
-<tr><td>Number of lemmas:</td><td class="statsnumber">~153,600</td></tr>
-<tr><td>Lines of Code:</td><td class="statsnumber">~2,667,800</td></tr>
+<tr><td>Number of lemmas:</td><td class="statsnumber">~157,200</td></tr>
+<tr><td>Lines of Code:</td><td class="statsnumber">~2,748,300</td></tr>
</table>
<h4>Most used AFP articles:</h4>
<table id="most_used">
<tr>
<th></th><th>Name</th><th>Used by ? articles</th>
</tr>
<tr><td>1.</td>
<td><a href="entries/List-Index.html">List-Index</a></td>
- <td>15</td>
+ <td>16</td>
</tr>
<tr><td>2.</td>
<td><a href="entries/Coinductive.html">Coinductive</a></td>
<td>12</td>
</tr>
<td></td>
<td><a href="entries/Collections.html">Collections</a></td>
<td>12</td>
</tr>
<td></td>
<td><a href="entries/Regular-Sets.html">Regular-Sets</a></td>
<td>12</td>
</tr>
<tr><td>3.</td>
<td><a href="entries/Landau_Symbols.html">Landau_Symbols</a></td>
<td>11</td>
</tr>
+ <td></td>
+ <td><a href="entries/Show.html">Show</a></td>
+ <td>11</td>
+ </tr>
<tr><td>4.</td>
<td><a href="entries/Polynomial_Factorization.html">Polynomial_Factorization</a></td>
<td>10</td>
</tr>
- <td></td>
- <td><a href="entries/Show.html">Show</a></td>
- <td>10</td>
- </tr>
<tr><td>5.</td>
<td><a href="entries/Abstract-Rewriting.html">Abstract-Rewriting</a></td>
<td>9</td>
</tr>
<td></td>
<td><a href="entries/Automatic_Refinement.html">Automatic_Refinement</a></td>
<td>9</td>
</tr>
<td></td>
<td><a href="entries/Deriving.html">Deriving</a></td>
<td>9</td>
</tr>
<tr><td>6.</td>
<td><a href="entries/Jordan_Normal_Form.html">Jordan_Normal_Form</a></td>
<td>8</td>
</tr>
<td></td>
<td><a href="entries/Native_Word.html">Native_Word</a></td>
<td>8</td>
</tr>
</table>
<script>
// DATA
var years = [2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020];
-var no_articles = [14, 22, 29, 37, 52, 64, 86, 103, 128, 151, 208, 253, 326, 396, 455, 511, 561];
-var no_loc = [61000.0, 96800.0, 131300.0, 238800.0, 353700.0, 435800.0, 517000.0, 568000.0, 740400.0, 828500.0, 1038600.0, 1217000.0, 1588900.0, 1839100.0, 2114400.0, 2409800.0, 2667800.0 ];
+var no_articles = [14, 22, 29, 37, 52, 64, 86, 103, 128, 151, 208, 253, 326, 396, 455, 511, 567];
+var no_loc = [60900.0, 96700.0, 131300.0, 238800.0, 353700.0, 435800.0, 517000.0, 568100.0, 740400.0, 828500.0, 1038800.0, 1217100.0, 1594500.0, 1846500.0, 2119000.0, 2414300.0, 2748300.0 ];
var no_authors = [14, 11, 6, 6, 10, 6, 24, 11, 17, 16, 36, 20, 63, 31, 28, 38, 29];
var no_authors_series = [14, 25, 31, 37, 47, 53, 77, 88, 105, 121, 157, 177, 240, 271, 299, 337, 366];
-var all_articles = [ "MiniML","AVL-Trees","Functional-Automata","BinarySearchTree","Lazy-Lists-II","Topology","Group-Ring-Module","Depth-First-Search","Compiling-Exceptions-Correctly","Completeness","Ramsey-Infinite","Verified-Prover","Integration","FileRefinement","Category","RSAPSS","Jinja","JiveDataStoreModel","DiskPaxos","GenClock","FFT","Ordinal","Cauchy","ClockSynchInst","FeatherweightJava","CoreC++","Flyspeck-Tame","Abstract-Hoare-Logics","HotelKeyCards","FOL-Fitting","POPLmark-deBruijn","Valuation","SumSquares","Fermat3_4","MuchAdoAboutTwo","JinjaThreads","Program-Conflict-Analysis","LinearQuantifierElim","NormByEval","Simpl","BDD","Recursion-Theory-I","SATSolverVerification","FunWithFunctions","ArrowImpossibilityGS","VolpanoSmith","Slicing","Huffman","FunWithTilings","SenSocialChoice","SIFPL","BytecodeLogicJmlTypes","Stream-Fusion","FinFun","CofGroups","SequentInvertibility","Ordinals_and_Cardinals","WorkerWrapper","HRB-Slicing","Perfect-Number-Thm","Collections","Tree-Automata","Presburger-Automata","DPT-SAT-Solver","Coinductive","List-Index","InformationFlowSlicing","InformationFlowSlicing_Inter","Free-Boolean-Algebra","Locally-Nameless-Sigma","Regular-Sets","Robbins-Conjecture","DataRefinementIBP","GraphMarkingIBP","Abstract-Rewriting","Matrix","Category2","Free-Groups","Statecharts","Polynomials","Lam-ml-Normalization","Binomial-Queues","Binomial-Heaps","Finger-Trees","Shivers-CFA","Marriage","Lower_Semicontinuous","RIPEMD-160-SPARK","LightweightJava","List-Infinite","AutoFocus-Stream","Nat-Interval-Logic","Transitive-Closure","General-Triangle","KBPs","Max-Card-Matching","Gauss-Jordan-Elim-Fun","Myhill-Nerode","LatticeProperties","MonoBoolTranAlgebra","PseudoHoops","Efficient-Mergesort","TLA","Markov_Models","Dijkstra_Shortest_Path","Refine_Monadic","Girth_Chromatic","Transitive-Closure-II","Abortable_Linearizable_Modules","Well_Quasi_Orders","Ordinary_Differential_Equations","Inductive_Confidentiality","Stuttering_Equivalence","Separation_Algebra","Circus","Psi_Calculi","CCS","Pi_Calculus","Tycon","PCF","Heard_Of","Impossible_Geometry","Datatype_Order_Generator","Possibilistic_Noninterference","Bondy","Tarskis_Geometry","Open_Induction","Separation_Logic_Imperative_HOL","Sqrt_Babylonian","Kleene_Algebra","Rank_Nullity_Theorem","Ribbon_Proofs","Launchbury","Nominal2","Containers","Graph_Theory","ShortestPath","Sort_Encodings","Koenigsberg_Friendship","Lehmer","Pratt_Certificate","IEEE_Floating_Point","Native_Word","Automatic_Refinement","Decreasing-Diagrams","GoedelGod","FocusStreamsCaseStudies","Coinductive_Languages","Incompleteness","HereditarilyFinite","Tail_Recursive_Functions","CryptoBasedCompositionalProperties","Sturm_Sequences","Featherweight_OCL","KAT_and_DRA","Relation_Algebra","Secondary_Sylow","Regex_Equivalence","Real_Impl","Affine_Arithmetic","Selection_Heap_Sort","Random_Graph_Subgraph_Threshold","Partial_Function_MR","AWN","Probabilistic_Noninterference","GPU_Kernel_PL","Discrete_Summation","HyperCTL","Abstract_Completeness","Bounded_Deducibility_Security","SIFUM_Type_Systems","WHATandWHERE_Security","Strong_Security","ComponentDependencies","Regular_Algebras","Noninterference_CSP","Roy_Floyd_Warshall","Gabow_SCC","CAVA_Automata","CAVA_LTL_Modelchecker","LTL_to_GBA","Promela","Boolean_Expression_Checkers","MSO_Regex_Equivalence","Pop_Refinement","Network_Security_Policy_Verification","Amortized_Complexity","pGCL","CISC-Kernel","Show","Splay_Tree","Skew_Heap","VectorSpace","Special_Function_Bounds","Gauss_Jordan","Priority_Queue_Braun","Jordan_Hoelder","Cayley_Hamilton","Sturm_Tarski","Imperative_Insertion_Sort","Certification_Monads","XML","RefinementReactive","Density_Compiler","Stream_Fusion_Code","Lifting_Definition_Option","AODV","UPF","UpDown_Scheme","Finite_Automata_HF","QR_Decomposition","Echelon_Form","Call_Arity","Deriving","Consensus_Refined","Trie","ConcurrentIMP","ConcurrentGC","Residuated_Lattices","Vickrey_Clarke_Groves","Probabilistic_System_Zoo","Formula_Derivatives","Dynamic_Tables","Noninterference_Ipurge_Unwinding","Noninterference_Generic_Unwinding","List_Interleaving","Multirelations","Derangements","Hermite","Akra_Bazzi","Landau_Symbols","Case_Labeling","Encodability_Process_Calculi","Rep_Fin_Groups","Noninterference_Inductive_Unwinding","Decreasing-Diagrams-II","Jordan_Normal_Form","LTL_to_DRA","Isabelle_Meta_Model","Parity_Game","Planarity_Certificates","TortoiseHare","Euler_Partition","Ergodic_Theory","Latin_Square","Card_Partitions","Applicative_Lifting","Algebraic_Numbers","Stern_Brocot","Liouville_Numbers","Triangle","Prime_Harmonic_Series","Descartes_Sign_Rule","Card_Number_Partitions","Matrix_Tensor","Knot_Theory","Polynomial_Factorization","Polynomial_Interpolation","Formal_SSA","List_Update","LTL","Cartan_FP","Timed_Automata","PropResPI","KAD","Noninterference_Sequential_Composition","ROBDD","CYK","No_FTL_observers","Groebner_Bases","Bell_Numbers_Spivey","SDS_Impossibility","Randomised_Social_Choice","MFMC_Countable","FLP","Perron_Frobenius","Incredible_Proof_Machine","Posix-Lexing","Card_Equiv_Relations","Tree_Decomposition","Word_Lib","Noninterference_Concurrent_Composition","Algebraic_VCs","Catalan_Numbers","Dependent_SIFUM_Type_Systems","Card_Multisets","Category3","Dependent_SIFUM_Refinement","IP_Addresses","Rewriting_Z","Resolution_FOL","Buildings","DFS_Framework","Pairing_Heap","Surprise_Paradox","Ptolemys_Theorem","Refine_Imperative_HOL","EdmondsKarp_Maxflow","InfPathElimination","Simple_Firewall","Routing","Stirling_Formula","Stone_Algebras","SuperCalc","Iptables_Semantics","Lambda_Free_RPOs","Allen_Calculus","Fisher_Yates","Lp","Chord_Segments","Berlekamp_Zassenhaus","Source_Coding_Theorem","SPARCv8","LOFT","Stable_Matching","Modal_Logics_for_NTS","Deep_Learning","Lambda_Free_KBOs","Nested_Multisets_Ordinals","Separata","Abs_Int_ITP2012","Complx","Paraconsistency","Proof_Strategy_Language","Twelvefold_Way","Concurrent_Ref_Alg","FOL_Harrison","Password_Authentication_Protocol","UPF_Firewall","E_Transcendental","Bertrands_Postulate","Minimal_SSA","Bernoulli","Key_Agreement_Strong_Adversaries","Stone_Relation_Algebras","Abstract_Soundness","Differential_Dynamic_Logic","Menger","Elliptic_Curves_Group_Law","Euler_MacLaurin","Quick_Sort_Cost","Comparison_Sort_Lower_Bound","Random_BSTs","Subresultants","Lazy_Case","Constructor_Funs","LocalLexing","Types_Tableaus_and_Goedels_God","MonoidalCategory","Game_Based_Crypto","Monomorphic_Monad","Probabilistic_While","Monad_Normalisation","CryptHOL","Floyd_Warshall","Security_Protocol_Refinement","Dict_Construction","Optics","Flow_Networks","Prpu_Maxflow","Buffons_Needle","PSemigroupsConvolution","Propositional_Proof_Systems","Stone_Kleene_Relation_Algebras","CRDT","Name_Carrying_Type_Inference","Minkowskis_Theorem","HOLCF-Prelude","Decl_Sem_Fun_PL","DynamicArchitectures","Stewart_Apollonius","LambdaMu","Orbit_Stabiliser","Root_Balanced_Tree","First_Welfare_Theorem","AnselmGod","PLM","Lowe_Ontological_Argument","Dirichlet_Series","Zeta_Function","Linear_Recurrences","Diophantine_Eqns_Lin_Hom","Winding_Number_Eval","Count_Complex_Roots","Buchi_Complementation","Transition_Systems_and_Automata","Kuratowski_Closure_Complement","Hybrid_Multi_Lane_Spatial_Logic","IMAP-CRDT","Stochastic_Matrices","Knuth_Morris_Pratt","BNF_Operations","Dirichlet_L","Mason_Stothers","Median_Of_Medians_Selection","Falling_Factorial_Sum","Taylor_Models","Green","Gromov_Hyperbolicity","Ordered_Resolution_Prover","LLL_Basis_Reduction","Treaps","First_Order_Terms","Error_Function","LLL_Factorization","Hoare_Time","Architectural_Design_Patterns","CakeML","Weight_Balanced_Trees","Fishburn_Impossibility","BNF_CC","VerifyThis2018","WebAssembly","Modular_Assembly_Kit_Security","OpSets","Monad_Memo_DP","AxiomaticCategoryTheory","Irrationality_J_Hancl","Probabilistic_Timed_Automata","Hidden_Markov_Models","Optimal_BST","Partial_Order_Reduction","Projective_Geometry","Localization_Ring","Pell","Neumann_Morgenstern_Utility","DiscretePricing","Minsky_Machines","Simplex","Budan_Fourier","Quaternions","Octonions","Aggregation_Algebras","Prime_Number_Theorem","Signature_Groebner","Symmetric_Polynomials","Pi_Transcendental","Factored_Transition_System_Bounding","Randomised_BSTs","Lambda_Free_EPO","Smooth_Manifolds","Epistemic_Logic","GewirthPGCProof","Generic_Deriving","Matroids","Auto2_HOL","Functional_Ordered_Resolution_Prover","Graph_Saturation","Transformer_Semantics","Order_Lattice_Props","Quantales","Constructive_Cryptography","Auto2_Imperative_HOL","Concurrent_Revisions","Core_DOM","Store_Buffer_Reduction","Higher_Order_Terms","IMP2","Farkas","List_Inversions","UTP","Universal_Turing_Machine","Probabilistic_Prime_Tests","Kruskal","Prime_Distribution_Elementary","Safe_OCL","QHLProver","Transcendence_Series_Hancl_Rucki","Binding_Syntax_Theory","LTL_Master_Theorem","HOL-CSP","Multi_Party_Computation","LambdaAuth","KD_Tree","Differential_Game_Logic","IMP2_Binary_Heap","Groebner_Macaulay","Nullstellensatz","Linear_Inequalities","Priority_Search_Trees","Prim_Dijkstra_Simple","Complete_Non_Orders","MFOTL_Monitor","CakeML_Codegen","FOL_Seq_Calc1","Szpilrajn","TESL_Language","Stellar_Quorums","IMO2019","C2KA_DistributedSystems","Linear_Programming","Laplace_Transform","Adaptive_State_Counting","Jacobson_Basic_Algebra","Fourier","Hybrid_Systems_VCs","Generic_Join","Clean","Sigma_Commit_Crypto","Aristotles_Assertoric_Syllogistic","VerifyThis2019","Isabelle_C","ZFC_in_HOL","Interval_Arithmetic_Word32","Generalized_Counting_Sort","Gauss_Sums","Poincare_Disc","Complex_Geometry","Poincare_Bendixson","Hybrid_Logic","Zeta_3_Irrational","Bicategory","Skip_Lists","Closest_Pair_Points","Approximation_Algorithms","Mersenne_Primes","Subset_Boolean_Algebras","Arith_Prog_Rel_Primes","VeriComp","Goodstein_Lambda","Hello_World","Relational-Incorrectness-Logic","Furstenberg_Topology","WOOT_Strong_Eventual_Consistency","Lucas_Theorem","Automated_Stateful_Protocol_Verification","Stateful_Protocol_Composition_and_Typing","MFODL_Monitor_Optimized","Saturation_Framework","Sliding_Window_Algorithm","ADS_Functor","Matrices_for_ODEs","Power_Sum_Polynomials","Lambert_W","Gaussian_Integers","Attack_Trees","Banach_Steinhaus","Forcing","LTL_Normal_Form","Recursion-Addition","Irrational_Series_Erdos_Straus","Knuth_Bendix_Order","Nash_Williams","Smith_Normal_Form","Safe_Distance","Relational_Paths","Chandy_Lamport","Ordinal_Partitions","Amicable_Numbers","BirdKMP","Saturation_Framework_Extensions","Relational_Disjoint_Set_Forests","PAC_Checker","Inductive_Inference","Extended_Finite_State_Machines","Extended_Finite_State_Machine_Inference","Goedel_HFSet_Semanticless","Syntax_Independent_Logic","Goedel_HFSet_Semantic","Goedel_Incompleteness","Robinson_Arithmetic"];
-var years_loc_articles = [ 2004 , , , , , , , , , , , , , ,2005 , , , , , , , ,2006 , , , , , , ,2007 , , , , , , , ,2008 , , , , , , , , , , , , , , ,2009 , , , , , , , , , , , ,2010 , , , , , , , , , , , , , , , , , , , , , ,2011 , , , , , , , , , , , , , , , , ,2012 , , , , , , , , , , , , , , , , , , , , , , , , ,2013 , , , , , , , , , , , , , , , , , , , , , , ,2014 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2015 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2016 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2017 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2018 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2019 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2020 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,];
-var loc_articles = [ "1825","839","1544","1096","1058","2419","44227","205","142","1994","209","1110","3792","506","1141","3769","17206","3119","6430","1145","447","2537","1275","1583","1838","12832","13126","2685","1228","3556","4238","9649","970","2847","1741","79742","4738","3396","2185","31176","10664","6723","30332","180","793","1047","14413","2080","254","2221","5959","3463","799","1540","684","6654","8","2627","27490","330","32399","5025","4380","210","9533","447","2380","3399","611","6311","2042","840","713","1024","5632","1427","4078","2230","6061","22617","1602","1587","3370","2451","2591","260","1617","16","2937","7805","6557","6381","992","125","10134","332","235","1828","1039","1784","4425","303","4461","11857","2835","8583","1043","408","2940","2613","38087","3243","1480","2612","3154","27588","2580","25274","2266","4107","7701","1245","260","5309","73","9729","719","6673","1511","4354","1249","1908","6215","4974","10129","7894","538","3830","4591","202","848","1777","5580","10319","1524","150","5292","706","10776","2248","1463","1958","3067","11485","1860","1190","1219","2175","1144","14861","2215","1964","166","10685","6420","572","590","1698","465","883","4133","2138","1403","2280","1959","2467","220","5429","4433","9386","3999","4463","406","5935","1829","12828","2973","9486","4560","931","645","104","2338","1653","9143","752","2113","875","1727","627","931","1201","1296","7880","1922","90","28055","2879","2796","1116","4863","5259","8842","1169","6178","527","1601","6207","1782","5327","1085","4103","952","2446","1089","1064","2362","468","2074","3761","2148","710","16080","8267","908","1063","21109","9679","8653","3142","9161","695","435","13711","478","898","2716","10158","1162","401","498","495","741","843","3622","4616","6228","4123","8166","12108","3178","518","17583","2876","2411","5496","2453","885","1162","17386","509","702","5036","9700","4287","5331","3811","656","329","1057","8753","3257","2593","553","8478","206","25104","8773","3267","398","2960","12833","9483","373","173","384","18976","2545","6119","3779","1017","2608","4338","9356","20044","4053","3420","319","3208","169","19558","541","14635","2648","7058","7590","3898","3244","4546","855","2289","5008","1349","276","4339","1475","3482","7119","9662","601","1722","852","2194","12222","4116","590","13558","1695","4484","1640","835","694","737","3346","105","68","10492","1127","8513","4135","4711","1200","378","9435","2078","14059","639","2015","3930","4869","398","1531","5554","5614","1993","4205","478","4121","3146","3471","88","480","1261","1877","2193","250","10669","854","7463","5301","3079","2784","8849","5261","2325","6164","945","6514","992","489","810","8891","3133","338","854","493","4585","9457","15962","6326","11079","1818","2288","785","3389","8438","3278","12951","592","841","3383","3641","11559","13548","3734","5742","530","1044","7674","1042","1259","5297","2754","1390","1622","2173","13358","805","10046","2667","541","1271","3949","5318","9770","2765","934","11918","1743","2355","7917","1490","449","685","1811","1132","3540","3578","1644","2983","2218","7223","4968","2767","17369","34365","3259","6022","1900","372","10305","16866","3018","3298","5304","4576","10486","1000","15843","4437","9487","5543","3301","1264","2973","805","10253","2606","5262","472","3365","1869","3199","13348","945","192","4455","527","713","782","2335","2134","9934","2089","3736","3105","2350","3195","3812","176","1726","8509","6892","5077","5730","4561","10314","14530","6402","4470","1907","51959","2450","3936","2758","1699","3154","944","906","596","375","691","764","2564","332","14517","21769","10948","3127","744","2353","1559","1239","1609","2537","1939","1341","12003","1034","1444","1935","2670","832","12970","3025","5074","9796","6779","1261","2908","2003","1560","9116","12872","4746","4268","11476","8100","426","3546","1294"];
+var all_articles = [ "MiniML","AVL-Trees","Functional-Automata","BinarySearchTree","Lazy-Lists-II","Topology","Group-Ring-Module","Depth-First-Search","Compiling-Exceptions-Correctly","Completeness","Ramsey-Infinite","Verified-Prover","Integration","FileRefinement","Category","RSAPSS","Jinja","JiveDataStoreModel","DiskPaxos","GenClock","FFT","Ordinal","Cauchy","ClockSynchInst","FeatherweightJava","CoreC++","Flyspeck-Tame","Abstract-Hoare-Logics","HotelKeyCards","FOL-Fitting","POPLmark-deBruijn","Valuation","SumSquares","Fermat3_4","MuchAdoAboutTwo","JinjaThreads","Program-Conflict-Analysis","LinearQuantifierElim","NormByEval","Simpl","BDD","Recursion-Theory-I","SATSolverVerification","FunWithFunctions","ArrowImpossibilityGS","VolpanoSmith","Slicing","Huffman","FunWithTilings","SenSocialChoice","SIFPL","BytecodeLogicJmlTypes","Stream-Fusion","FinFun","CofGroups","SequentInvertibility","Ordinals_and_Cardinals","WorkerWrapper","HRB-Slicing","Perfect-Number-Thm","Collections","Tree-Automata","Presburger-Automata","DPT-SAT-Solver","Coinductive","List-Index","InformationFlowSlicing","InformationFlowSlicing_Inter","Free-Boolean-Algebra","Locally-Nameless-Sigma","Regular-Sets","Robbins-Conjecture","DataRefinementIBP","GraphMarkingIBP","Abstract-Rewriting","Matrix","Category2","Free-Groups","Statecharts","Polynomials","Lam-ml-Normalization","Binomial-Queues","Binomial-Heaps","Finger-Trees","Shivers-CFA","Marriage","Lower_Semicontinuous","RIPEMD-160-SPARK","LightweightJava","List-Infinite","AutoFocus-Stream","Nat-Interval-Logic","Transitive-Closure","General-Triangle","KBPs","Max-Card-Matching","Gauss-Jordan-Elim-Fun","Myhill-Nerode","LatticeProperties","MonoBoolTranAlgebra","PseudoHoops","Efficient-Mergesort","TLA","Markov_Models","Dijkstra_Shortest_Path","Refine_Monadic","Girth_Chromatic","Transitive-Closure-II","Abortable_Linearizable_Modules","Well_Quasi_Orders","Ordinary_Differential_Equations","Inductive_Confidentiality","Stuttering_Equivalence","Separation_Algebra","Circus","Psi_Calculi","CCS","Pi_Calculus","Tycon","PCF","Heard_Of","Impossible_Geometry","Datatype_Order_Generator","Possibilistic_Noninterference","Bondy","Tarskis_Geometry","Open_Induction","Separation_Logic_Imperative_HOL","Sqrt_Babylonian","Kleene_Algebra","Rank_Nullity_Theorem","Ribbon_Proofs","Launchbury","Nominal2","Containers","Graph_Theory","ShortestPath","Sort_Encodings","Koenigsberg_Friendship","Lehmer","Pratt_Certificate","IEEE_Floating_Point","Native_Word","Automatic_Refinement","Decreasing-Diagrams","GoedelGod","FocusStreamsCaseStudies","Coinductive_Languages","Incompleteness","HereditarilyFinite","Tail_Recursive_Functions","CryptoBasedCompositionalProperties","Sturm_Sequences","Featherweight_OCL","KAT_and_DRA","Relation_Algebra","Secondary_Sylow","Regex_Equivalence","Real_Impl","Affine_Arithmetic","Selection_Heap_Sort","Random_Graph_Subgraph_Threshold","Partial_Function_MR","AWN","Probabilistic_Noninterference","GPU_Kernel_PL","Discrete_Summation","HyperCTL","Abstract_Completeness","Bounded_Deducibility_Security","SIFUM_Type_Systems","WHATandWHERE_Security","Strong_Security","ComponentDependencies","Regular_Algebras","Noninterference_CSP","Roy_Floyd_Warshall","Gabow_SCC","CAVA_Automata","CAVA_LTL_Modelchecker","LTL_to_GBA","Promela","Boolean_Expression_Checkers","MSO_Regex_Equivalence","Pop_Refinement","Network_Security_Policy_Verification","Amortized_Complexity","pGCL","CISC-Kernel","Show","Splay_Tree","Skew_Heap","VectorSpace","Special_Function_Bounds","Gauss_Jordan","Priority_Queue_Braun","Jordan_Hoelder","Cayley_Hamilton","Sturm_Tarski","Imperative_Insertion_Sort","Certification_Monads","XML","RefinementReactive","Density_Compiler","Stream_Fusion_Code","Lifting_Definition_Option","AODV","UPF","UpDown_Scheme","Finite_Automata_HF","QR_Decomposition","Echelon_Form","Call_Arity","Deriving","Consensus_Refined","Trie","ConcurrentIMP","ConcurrentGC","Residuated_Lattices","Vickrey_Clarke_Groves","Probabilistic_System_Zoo","Formula_Derivatives","Dynamic_Tables","Noninterference_Ipurge_Unwinding","Noninterference_Generic_Unwinding","List_Interleaving","Multirelations","Derangements","Hermite","Akra_Bazzi","Landau_Symbols","Case_Labeling","Encodability_Process_Calculi","Rep_Fin_Groups","Noninterference_Inductive_Unwinding","Decreasing-Diagrams-II","Jordan_Normal_Form","LTL_to_DRA","Isabelle_Meta_Model","Parity_Game","Planarity_Certificates","TortoiseHare","Euler_Partition","Ergodic_Theory","Latin_Square","Card_Partitions","Applicative_Lifting","Algebraic_Numbers","Stern_Brocot","Liouville_Numbers","Triangle","Prime_Harmonic_Series","Descartes_Sign_Rule","Card_Number_Partitions","Matrix_Tensor","Knot_Theory","Polynomial_Factorization","Polynomial_Interpolation","Formal_SSA","List_Update","LTL","Cartan_FP","Timed_Automata","PropResPI","KAD","Noninterference_Sequential_Composition","ROBDD","CYK","No_FTL_observers","Groebner_Bases","Bell_Numbers_Spivey","SDS_Impossibility","Randomised_Social_Choice","MFMC_Countable","FLP","Perron_Frobenius","Incredible_Proof_Machine","Posix-Lexing","Card_Equiv_Relations","Tree_Decomposition","Word_Lib","Noninterference_Concurrent_Composition","Algebraic_VCs","Catalan_Numbers","Dependent_SIFUM_Type_Systems","Card_Multisets","Category3","Dependent_SIFUM_Refinement","IP_Addresses","Rewriting_Z","Resolution_FOL","Buildings","DFS_Framework","Pairing_Heap","Surprise_Paradox","Ptolemys_Theorem","Refine_Imperative_HOL","EdmondsKarp_Maxflow","InfPathElimination","Simple_Firewall","Routing","Stirling_Formula","Stone_Algebras","SuperCalc","Iptables_Semantics","Lambda_Free_RPOs","Allen_Calculus","Fisher_Yates","Lp","Chord_Segments","Berlekamp_Zassenhaus","Source_Coding_Theorem","SPARCv8","LOFT","Stable_Matching","Modal_Logics_for_NTS","Deep_Learning","Lambda_Free_KBOs","Nested_Multisets_Ordinals","Separata","Abs_Int_ITP2012","Complx","Paraconsistency","Proof_Strategy_Language","Twelvefold_Way","Concurrent_Ref_Alg","FOL_Harrison","Password_Authentication_Protocol","UPF_Firewall","E_Transcendental","Bertrands_Postulate","Minimal_SSA","Bernoulli","Key_Agreement_Strong_Adversaries","Stone_Relation_Algebras","Abstract_Soundness","Differential_Dynamic_Logic","Menger","Elliptic_Curves_Group_Law","Euler_MacLaurin","Quick_Sort_Cost","Comparison_Sort_Lower_Bound","Random_BSTs","Subresultants","Lazy_Case","Constructor_Funs","LocalLexing","Types_Tableaus_and_Goedels_God","MonoidalCategory","Game_Based_Crypto","Monomorphic_Monad","Probabilistic_While","Monad_Normalisation","CryptHOL","Floyd_Warshall","Security_Protocol_Refinement","Dict_Construction","Optics","Flow_Networks","Prpu_Maxflow","Buffons_Needle","PSemigroupsConvolution","Propositional_Proof_Systems","Stone_Kleene_Relation_Algebras","CRDT","Name_Carrying_Type_Inference","Minkowskis_Theorem","HOLCF-Prelude","Decl_Sem_Fun_PL","DynamicArchitectures","Stewart_Apollonius","LambdaMu","Orbit_Stabiliser","Root_Balanced_Tree","First_Welfare_Theorem","AnselmGod","PLM","Lowe_Ontological_Argument","Dirichlet_Series","Zeta_Function","Linear_Recurrences","Diophantine_Eqns_Lin_Hom","Winding_Number_Eval","Count_Complex_Roots","Buchi_Complementation","Transition_Systems_and_Automata","Kuratowski_Closure_Complement","Hybrid_Multi_Lane_Spatial_Logic","IMAP-CRDT","Stochastic_Matrices","Knuth_Morris_Pratt","BNF_Operations","Dirichlet_L","Mason_Stothers","Median_Of_Medians_Selection","Falling_Factorial_Sum","Taylor_Models","Green","Gromov_Hyperbolicity","Ordered_Resolution_Prover","LLL_Basis_Reduction","Treaps","First_Order_Terms","Error_Function","LLL_Factorization","Hoare_Time","Architectural_Design_Patterns","CakeML","Weight_Balanced_Trees","Fishburn_Impossibility","BNF_CC","VerifyThis2018","WebAssembly","Modular_Assembly_Kit_Security","OpSets","Monad_Memo_DP","AxiomaticCategoryTheory","Irrationality_J_Hancl","Probabilistic_Timed_Automata","Hidden_Markov_Models","Optimal_BST","Partial_Order_Reduction","Projective_Geometry","Localization_Ring","Pell","Neumann_Morgenstern_Utility","DiscretePricing","Minsky_Machines","Simplex","Budan_Fourier","Quaternions","Octonions","Aggregation_Algebras","Prime_Number_Theorem","Signature_Groebner","Symmetric_Polynomials","Pi_Transcendental","Factored_Transition_System_Bounding","Randomised_BSTs","Lambda_Free_EPO","Smooth_Manifolds","Epistemic_Logic","GewirthPGCProof","Generic_Deriving","Matroids","Auto2_HOL","Functional_Ordered_Resolution_Prover","Graph_Saturation","Transformer_Semantics","Order_Lattice_Props","Quantales","Constructive_Cryptography","Auto2_Imperative_HOL","Concurrent_Revisions","Core_DOM","Store_Buffer_Reduction","Higher_Order_Terms","IMP2","Farkas","List_Inversions","UTP","Universal_Turing_Machine","Probabilistic_Prime_Tests","Kruskal","Prime_Distribution_Elementary","Safe_OCL","QHLProver","Transcendence_Series_Hancl_Rucki","Binding_Syntax_Theory","LTL_Master_Theorem","HOL-CSP","Multi_Party_Computation","LambdaAuth","KD_Tree","Differential_Game_Logic","IMP2_Binary_Heap","Groebner_Macaulay","Nullstellensatz","Linear_Inequalities","Priority_Search_Trees","Prim_Dijkstra_Simple","Complete_Non_Orders","MFOTL_Monitor","CakeML_Codegen","FOL_Seq_Calc1","Szpilrajn","TESL_Language","Stellar_Quorums","IMO2019","C2KA_DistributedSystems","Linear_Programming","Laplace_Transform","Adaptive_State_Counting","Jacobson_Basic_Algebra","Fourier","Hybrid_Systems_VCs","Generic_Join","Clean","Sigma_Commit_Crypto","Aristotles_Assertoric_Syllogistic","VerifyThis2019","Isabelle_C","ZFC_in_HOL","Interval_Arithmetic_Word32","Generalized_Counting_Sort","Gauss_Sums","Poincare_Disc","Complex_Geometry","Poincare_Bendixson","Hybrid_Logic","Zeta_3_Irrational","Bicategory","Skip_Lists","Closest_Pair_Points","Approximation_Algorithms","Mersenne_Primes","Subset_Boolean_Algebras","Arith_Prog_Rel_Primes","VeriComp","Goodstein_Lambda","Hello_World","Relational-Incorrectness-Logic","Furstenberg_Topology","WOOT_Strong_Eventual_Consistency","Lucas_Theorem","Automated_Stateful_Protocol_Verification","Stateful_Protocol_Composition_and_Typing","MFODL_Monitor_Optimized","Saturation_Framework","Sliding_Window_Algorithm","ADS_Functor","Matrices_for_ODEs","Power_Sum_Polynomials","Lambert_W","Gaussian_Integers","Attack_Trees","Banach_Steinhaus","Forcing","LTL_Normal_Form","Recursion-Addition","Irrational_Series_Erdos_Straus","Knuth_Bendix_Order","Nash_Williams","Smith_Normal_Form","Safe_Distance","Relational_Paths","Chandy_Lamport","Ordinal_Partitions","Amicable_Numbers","BirdKMP","Saturation_Framework_Extensions","Relational_Disjoint_Set_Forests","PAC_Checker","Inductive_Inference","Extended_Finite_State_Machine_Inference","Extended_Finite_State_Machines","Goedel_HFSet_Semanticless","Syntax_Independent_Logic","Goedel_HFSet_Semantic","Goedel_Incompleteness","Robinson_Arithmetic","Shadow_SC_DOM","Core_SC_DOM","SC_DOM_Components","Physical_Quantities","Verified_SAT_Based_AI_Planning","AI_Planning_Languages_Semantics"];
+var years_loc_articles = [ 2004 , , , , , , , , , , , , , ,2005 , , , , , , , ,2006 , , , , , , ,2007 , , , , , , , ,2008 , , , , , , , , , , , , , , ,2009 , , , , , , , , , , , ,2010 , , , , , , , , , , , , , , , , , , , , , ,2011 , , , , , , , , , , , , , , , , ,2012 , , , , , , , , , , , , , , , , , , , , , , , , ,2013 , , , , , , , , , , , , , , , , , , , , , , ,2014 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2015 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2016 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2017 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2018 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2019 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,2020 , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ,];
+var loc_articles = [ "1798","839","1544","1096","1058","2419","44227","205","142","1994","209","1110","3792","506","1141","3769","17206","3119","6430","1145","447","2537","1275","1583","1838","12832","13126","2685","1228","3556","4238","9649","970","2847","1741","79746","4738","3396","2185","31176","10664","6723","30332","180","793","1047","14413","2080","254","2221","5959","3463","799","1540","684","6654","8","2627","27490","330","32399","5025","4380","208","9533","447","2380","3399","611","6311","2042","840","713","1024","5632","1427","4078","2230","6002","22617","1602","1587","3370","2451","2591","260","1617","16","2937","7805","6557","6381","992","125","10134","332","235","1828","1039","1784","4425","434","4461","11857","2835","8583","1043","408","2940","2613","38084","3243","1480","2612","3157","27588","2580","25274","2266","4107","7701","1245","260","5309","73","9729","719","6673","1511","4354","1249","1908","6214","4979","10129","7894","538","3830","4591","202","848","1777","5519","10319","1524","150","5292","706","10776","2248","1463","1958","3067","11485","1860","1190","1219","2175","1144","14861","2215","1964","166","10685","6420","572","590","1698","465","883","4133","2138","1403","2280","1959","2467","220","5429","4433","9390","3999","4463","406","5935","1829","12828","3198","9486","4560","931","659","63","2338","1653","9143","753","2113","875","1727","627","931","1201","1296","7880","1922","90","28055","2879","2796","1116","4863","5259","8842","1169","6178","527","1601","6207","1782","5327","1085","4103","952","2446","1089","1064","2362","468","2074","3761","2148","710","16080","8267","908","1063","21109","9679","8653","3142","9161","695","435","13711","478","898","2724","10063","1162","401","498","495","741","843","3622","4616","6228","4123","8166","12108","3178","518","17583","2876","2411","5496","2453","885","1162","17386","509","702","5036","9700","4287","5331","3811","656","329","1057","13861","3257","2593","553","8478","206","25451","8773","3277","398","2960","12833","9483","370","173","384","18976","2545","6119","3779","1017","2608","4338","9356","20044","4053","3420","319","3208","169","19575","541","14634","2648","7058","7590","3898","3244","4546","855","2289","5008","1349","276","4339","1475","3482","7119","9662","601","1722","852","2194","12222","4116","590","13558","1695","4484","1640","835","694","737","3346","105","68","10492","1127","8513","4135","4711","1200","378","11280","2078","14059","639","2015","3930","4869","398","1531","5554","5614","1993","4205","478","4121","3146","3471","88","480","1261","1877","2193","250","10669","854","7463","5301","3083","2784","8849","5261","2325","6164","945","6514","992","489","810","8891","3133","338","854","493","4585","9457","15962","6326","10345","1818","2288","785","3260","8438","3278","12951","592","841","3383","3638","11570","13548","3734","5742","530","1044","7674","1042","1259","5297","2754","1390","1622","2173","13358","805","10026","2667","541","1271","3949","5318","9770","2765","934","11918","1743","2355","7917","1490","449","685","1811","1132","3540","3578","1644","2983","2218","5182","4968","2767","17369","34365","3259","6022","1900","372","10305","16866","3018","3298","5304","4576","10485","1000","15843","4437","9487","5543","3301","1264","2973","805","10253","2606","5262","472","3365","1869","3199","13339","945","192","4455","527","713","782","2335","2134","9934","2089","3736","3105","2350","3195","3809","176","1726","8509","6892","5069","5730","4561","10314","14530","6402","4470","1907","67700","2450","3936","2758","1699","3154","944","933","596","370","691","764","2564","332","14517","21775","10948","3058","744","2353","1559","1239","1609","2537","1939","1341","12003","1034","1444","1935","2670","832","12970","3028","5074","9796","6679","1261","2908","1929","2201","9116","12872","4265","4747","11477","8100","426","3546","1295","15453","16385","7798","1761","16434","1967"];
</script>
<h4>Growth in number of articles:</h4>
<script src="Chart.js"></script>
<div class="chart">
<canvas id="NumberOfArticles" width="400" height="400"></canvas>
</div>
<script>
var ctx = document.getElementById("NumberOfArticles");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: years,
datasets: [{
label: 'size of the AFP in # of articles',
data: no_articles,
backgroundColor: "rgba(46, 45, 78, 1)"
}],
},
options: {
responsive: true,
maintainAspectRatio: true,
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
}
});
</script>
<h4>Growth in lines of code:</h4>
<div class="chart">
<canvas id="NumberOfLoc" width="400" height="400"></canvas>
</div>
<script>
var ctx = document.getElementById("NumberOfLoc");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: years,
datasets: [{
label: 'size of the AFP in lines of code',
data: no_loc,
backgroundColor: "rgba(101, 99, 136, 1)"
}],
},
options: {
responsive: true,
maintainAspectRatio: true,
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
}
});
</script>
<h4>Growth in number of authors:</h4>
<div class="chart">
<canvas id="NumberOfAuthors" width="400" height="400"></canvas>
</div>
<script>
var ctx = document.getElementById("NumberOfAuthors");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: years,
datasets: [{
label: 'new authors per year',
data: no_authors,
backgroundColor: "rgba(101, 99, 136, 1)"
},
{
label: 'number of authors contributing (cumulative)',
data: no_authors_series,
backgroundColor: "rgba(0, 15, 48, 1)"
}],
},
options: {
responsive: true,
maintainAspectRatio: true,
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
}
});
</script>
<h4>Size of articles:</h4>
<div style="width: 800px" class="chart">
<canvas id="LocArticles" width="800" height="400"></canvas>
</div>
<script>
var ctx = document.getElementById("LocArticles");
var myChart = new Chart(ctx, {
type: 'bar',
data: {
labels: years_loc_articles,
datasets: [{
label: 'loc per article',
data: loc_articles,
backgroundColor: "rgba(101, 99, 136, 1)"
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
scales: {
xAxes: [{
categoryPercentage: 1,
barPercentage: 0.9,
ticks: {
autoSkip: false
}
}],
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
tooltips: {
callbacks: {
title: function(tooltipItem, data) {
return all_articles[tooltipItem[0].index];
}
}
}
}
});
</script>
</td></tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
<script src="Chart.js"></script>
</body>
</html>
\ 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,910 +1,920 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Archive of Formal Proofs</title>
<link rel="stylesheet" type="text/css" href="front.css">
<link rel="icon" href="images/favicon.ico" type="image/icon">
<link rel="alternate" type="application/rss+xml" title="RSS" href="rss.xml">
</head>
<body class="mathjax_ignore">
<table width="100%">
<tbody>
<tr>
<!-- Navigation -->
<td width="20%" align="center" valign="top">
<p>&nbsp;</p>
<a href="https://www.isa-afp.org/">
<img src="images/isabelle.png" width="100" height="88" border=0>
</a>
<p>&nbsp;</p>
<p>&nbsp;</p>
<table class="nav" width="80%">
<tr>
<td class="nav" width="100%"><a href="index.html">Home</a></td>
</tr>
<tr>
<td class="nav"><a href="about.html">About</a></td>
</tr>
<tr>
<td class="nav"><a href="submitting.html">Submission</a></td>
</tr>
<tr>
<td class="nav"><a href="updating.html">Updating Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="using.html">Using Entries</a></td>
</tr>
<tr>
<td class="nav"><a href="search.html">Search</a></td>
</tr>
<tr>
<td class="nav"><a href="statistics.html">Statistics</a></td>
</tr>
<tr>
<td class="nav"><a href="topics.html">Index</a></td>
</tr>
<tr>
<td class="nav"><a href="download.html">Download</a></td>
</tr>
</table>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<!-- Content -->
<td width="80%" valign="top">
<div align="center">
<p>&nbsp;</p>
<h1><font class="first">I</font>ndex by <font class="first">T</font>opic
</h1>
<p>&nbsp;</p>
<table width="80%" class="descr">
<tbody>
<tr>
<td>
<h2>Computer science</h2>
<div class="list">
</div>
- <h3>Automata and formal languages</h3>
+ <h3>Artificial intelligence</h3>
+ <div class="list">
+ <a href="entries/AI_Planning_Languages_Semantics.html">AI_Planning_Languages_Semantics</a> &nbsp;
+ <a href="entries/Verified_SAT_Based_AI_Planning.html">Verified_SAT_Based_AI_Planning</a> &nbsp;
+ </div>
+ <h3>Automata and formal languages</h3>
<div class="list">
<a href="entries/Partial_Order_Reduction.html">Partial_Order_Reduction</a> &nbsp;
<a href="entries/C2KA_DistributedSystems.html">C2KA_DistributedSystems</a> &nbsp;
<a href="entries/Posix-Lexing.html">Posix-Lexing</a> &nbsp;
<a href="entries/LocalLexing.html">LocalLexing</a> &nbsp;
<a href="entries/KBPs.html">KBPs</a> &nbsp;
<a href="entries/Regular-Sets.html">Regular-Sets</a> &nbsp;
<a href="entries/Regex_Equivalence.html">Regex_Equivalence</a> &nbsp;
<a href="entries/MSO_Regex_Equivalence.html">MSO_Regex_Equivalence</a> &nbsp;
<a href="entries/Formula_Derivatives.html">Formula_Derivatives</a> &nbsp;
<a href="entries/Myhill-Nerode.html">Myhill-Nerode</a> &nbsp;
<a href="entries/Universal_Turing_Machine.html">Universal_Turing_Machine</a> &nbsp;
<a href="entries/CYK.html">CYK</a> &nbsp;
<a href="entries/Presburger-Automata.html">Presburger-Automata</a> &nbsp;
<a href="entries/Functional-Automata.html">Functional-Automata</a> &nbsp;
<a href="entries/Statecharts.html">Statecharts</a> &nbsp;
<a href="entries/Stuttering_Equivalence.html">Stuttering_Equivalence</a> &nbsp;
<a href="entries/Coinductive_Languages.html">Coinductive_Languages</a> &nbsp;
<a href="entries/Tree-Automata.html">Tree-Automata</a> &nbsp;
<a href="entries/Kleene_Algebra.html">Kleene_Algebra</a> &nbsp;
<a href="entries/KAT_and_DRA.html">KAT_and_DRA</a> &nbsp;
<a href="entries/KAD.html">KAD</a> &nbsp;
<a href="entries/Regular_Algebras.html">Regular_Algebras</a> &nbsp;
<a href="entries/Markov_Models.html">Markov_Models</a> &nbsp;
<a href="entries/Probabilistic_System_Zoo.html">Probabilistic_System_Zoo</a> &nbsp;
<a href="entries/CAVA_Automata.html">CAVA_Automata</a> &nbsp;
<a href="entries/LTL.html">LTL</a> &nbsp;
<a href="entries/LTL_to_GBA.html">LTL_to_GBA</a> &nbsp;
<a href="entries/CAVA_LTL_Modelchecker.html">CAVA_LTL_Modelchecker</a> &nbsp;
<a href="entries/Probabilistic_Timed_Automata.html">Probabilistic_Timed_Automata</a> &nbsp;
<a href="entries/Finite_Automata_HF.html">Finite_Automata_HF</a> &nbsp;
<a href="entries/LTL_to_DRA.html">LTL_to_DRA</a> &nbsp;
<a href="entries/Timed_Automata.html">Timed_Automata</a> &nbsp;
<a href="entries/Stochastic_Matrices.html">Stochastic_Matrices</a> &nbsp;
<a href="entries/Buchi_Complementation.html">Buchi_Complementation</a> &nbsp;
<a href="entries/Transition_Systems_and_Automata.html">Transition_Systems_and_Automata</a> &nbsp;
<a href="entries/Factored_Transition_System_Bounding.html">Factored_Transition_System_Bounding</a> &nbsp;
<a href="entries/LTL_Master_Theorem.html">LTL_Master_Theorem</a> &nbsp;
<a href="entries/MFOTL_Monitor.html">MFOTL_Monitor</a> &nbsp;
<a href="entries/Adaptive_State_Counting.html">Adaptive_State_Counting</a> &nbsp;
<a href="entries/MFODL_Monitor_Optimized.html">MFODL_Monitor_Optimized</a> &nbsp;
<a href="entries/LTL_Normal_Form.html">LTL_Normal_Form</a> &nbsp;
<a href="entries/Extended_Finite_State_Machines.html">Extended_Finite_State_Machines</a> &nbsp;
<a href="entries/Extended_Finite_State_Machine_Inference.html">Extended_Finite_State_Machine_Inference</a> &nbsp;
</div>
<h3>Algorithms</h3>
<div class="list">
<a href="entries/Knuth_Morris_Pratt.html">Knuth_Morris_Pratt</a> &nbsp;
<a href="entries/Probabilistic_While.html">Probabilistic_While</a> &nbsp;
<a href="entries/Comparison_Sort_Lower_Bound.html">Comparison_Sort_Lower_Bound</a> &nbsp;
<a href="entries/Quick_Sort_Cost.html">Quick_Sort_Cost</a> &nbsp;
<a href="entries/TortoiseHare.html">TortoiseHare</a> &nbsp;
<a href="entries/Selection_Heap_Sort.html">Selection_Heap_Sort</a> &nbsp;
<a href="entries/VerifyThis2018.html">VerifyThis2018</a> &nbsp;
<a href="entries/CYK.html">CYK</a> &nbsp;
<a href="entries/Boolean_Expression_Checkers.html">Boolean_Expression_Checkers</a> &nbsp;
<a href="entries/Efficient-Mergesort.html">Efficient-Mergesort</a> &nbsp;
<a href="entries/SATSolverVerification.html">SATSolverVerification</a> &nbsp;
<a href="entries/MuchAdoAboutTwo.html">MuchAdoAboutTwo</a> &nbsp;
<a href="entries/First_Order_Terms.html">First_Order_Terms</a> &nbsp;
<a href="entries/Monad_Memo_DP.html">Monad_Memo_DP</a> &nbsp;
<a href="entries/Hidden_Markov_Models.html">Hidden_Markov_Models</a> &nbsp;
<a href="entries/Imperative_Insertion_Sort.html">Imperative_Insertion_Sort</a> &nbsp;
<a href="entries/Formal_SSA.html">Formal_SSA</a> &nbsp;
<a href="entries/ROBDD.html">ROBDD</a> &nbsp;
<a href="entries/Median_Of_Medians_Selection.html">Median_Of_Medians_Selection</a> &nbsp;
<a href="entries/Fisher_Yates.html">Fisher_Yates</a> &nbsp;
<a href="entries/Optimal_BST.html">Optimal_BST</a> &nbsp;
<a href="entries/IMP2.html">IMP2</a> &nbsp;
<a href="entries/Auto2_Imperative_HOL.html">Auto2_Imperative_HOL</a> &nbsp;
<a href="entries/List_Inversions.html">List_Inversions</a> &nbsp;
<a href="entries/IMP2_Binary_Heap.html">IMP2_Binary_Heap</a> &nbsp;
<a href="entries/MFOTL_Monitor.html">MFOTL_Monitor</a> &nbsp;
<a href="entries/Adaptive_State_Counting.html">Adaptive_State_Counting</a> &nbsp;
<a href="entries/Generic_Join.html">Generic_Join</a> &nbsp;
<a href="entries/VerifyThis2019.html">VerifyThis2019</a> &nbsp;
<a href="entries/Generalized_Counting_Sort.html">Generalized_Counting_Sort</a> &nbsp;
<a href="entries/MFODL_Monitor_Optimized.html">MFODL_Monitor_Optimized</a> &nbsp;
<a href="entries/Sliding_Window_Algorithm.html">Sliding_Window_Algorithm</a> &nbsp;
<a href="entries/PAC_Checker.html">PAC_Checker</a> &nbsp;
<strong>Graph:</strong>
<a href="entries/DFS_Framework.html">DFS_Framework</a> &nbsp;
<a href="entries/Prpu_Maxflow.html">Prpu_Maxflow</a> &nbsp;
<a href="entries/Floyd_Warshall.html">Floyd_Warshall</a> &nbsp;
<a href="entries/Roy_Floyd_Warshall.html">Roy_Floyd_Warshall</a> &nbsp;
<a href="entries/Dijkstra_Shortest_Path.html">Dijkstra_Shortest_Path</a> &nbsp;
<a href="entries/EdmondsKarp_Maxflow.html">EdmondsKarp_Maxflow</a> &nbsp;
<a href="entries/Depth-First-Search.html">Depth-First-Search</a> &nbsp;
<a href="entries/GraphMarkingIBP.html">GraphMarkingIBP</a> &nbsp;
<a href="entries/Transitive-Closure.html">Transitive-Closure</a> &nbsp;
<a href="entries/Transitive-Closure-II.html">Transitive-Closure-II</a> &nbsp;
<a href="entries/Gabow_SCC.html">Gabow_SCC</a> &nbsp;
<a href="entries/Kruskal.html">Kruskal</a> &nbsp;
<a href="entries/Prim_Dijkstra_Simple.html">Prim_Dijkstra_Simple</a> &nbsp;
<strong>Distributed:</strong>
<a href="entries/DiskPaxos.html">DiskPaxos</a> &nbsp;
<a href="entries/GenClock.html">GenClock</a> &nbsp;
<a href="entries/ClockSynchInst.html">ClockSynchInst</a> &nbsp;
<a href="entries/Heard_Of.html">Heard_Of</a> &nbsp;
<a href="entries/Consensus_Refined.html">Consensus_Refined</a> &nbsp;
<a href="entries/Abortable_Linearizable_Modules.html">Abortable_Linearizable_Modules</a> &nbsp;
<a href="entries/IMAP-CRDT.html">IMAP-CRDT</a> &nbsp;
<a href="entries/CRDT.html">CRDT</a> &nbsp;
<a href="entries/Chandy_Lamport.html">Chandy_Lamport</a> &nbsp;
<a href="entries/OpSets.html">OpSets</a> &nbsp;
<a href="entries/Stellar_Quorums.html">Stellar_Quorums</a> &nbsp;
<a href="entries/WOOT_Strong_Eventual_Consistency.html">WOOT_Strong_Eventual_Consistency</a> &nbsp;
<strong>Concurrent:</strong>
<a href="entries/ConcurrentGC.html">ConcurrentGC</a> &nbsp;
<strong>Online:</strong>
<a href="entries/List_Update.html">List_Update</a> &nbsp;
<strong>Geometry:</strong>
<a href="entries/Closest_Pair_Points.html">Closest_Pair_Points</a> &nbsp;
<strong>Approximation:</strong>
<a href="entries/Approximation_Algorithms.html">Approximation_Algorithms</a> &nbsp;
<strong>Mathematical:</strong>
<a href="entries/FFT.html">FFT</a> &nbsp;
<a href="entries/Gauss-Jordan-Elim-Fun.html">Gauss-Jordan-Elim-Fun</a> &nbsp;
<a href="entries/UpDown_Scheme.html">UpDown_Scheme</a> &nbsp;
<a href="entries/Polynomials.html">Polynomials</a> &nbsp;
<a href="entries/Gauss_Jordan.html">Gauss_Jordan</a> &nbsp;
<a href="entries/Echelon_Form.html">Echelon_Form</a> &nbsp;
<a href="entries/QR_Decomposition.html">QR_Decomposition</a> &nbsp;
<a href="entries/Hermite.html">Hermite</a> &nbsp;
<a href="entries/Groebner_Bases.html">Groebner_Bases</a> &nbsp;
<a href="entries/Diophantine_Eqns_Lin_Hom.html">Diophantine_Eqns_Lin_Hom</a> &nbsp;
<a href="entries/Taylor_Models.html">Taylor_Models</a> &nbsp;
<a href="entries/LLL_Basis_Reduction.html">LLL_Basis_Reduction</a> &nbsp;
<a href="entries/Signature_Groebner.html">Signature_Groebner</a> &nbsp;
<a href="entries/Smith_Normal_Form.html">Smith_Normal_Form</a> &nbsp;
<a href="entries/Safe_Distance.html">Safe_Distance</a> &nbsp;
<strong>Optimization:</strong>
<a href="entries/Simplex.html">Simplex</a> &nbsp;
</div>
<h3>Concurrency</h3>
<div class="list">
<a href="entries/FLP.html">FLP</a> &nbsp;
<a href="entries/Concurrent_Ref_Alg.html">Concurrent_Ref_Alg</a> &nbsp;
<a href="entries/Concurrent_Revisions.html">Concurrent_Revisions</a> &nbsp;
<a href="entries/Store_Buffer_Reduction.html">Store_Buffer_Reduction</a> &nbsp;
<a href="entries/TESL_Language.html">TESL_Language</a> &nbsp;
<strong>Process calculi:</strong>
<a href="entries/Noninterference_Generic_Unwinding.html">Noninterference_Generic_Unwinding</a> &nbsp;
<a href="entries/AODV.html">AODV</a> &nbsp;
<a href="entries/AWN.html">AWN</a> &nbsp;
<a href="entries/CCS.html">CCS</a> &nbsp;
<a href="entries/Pi_Calculus.html">Pi_Calculus</a> &nbsp;
<a href="entries/Psi_Calculi.html">Psi_Calculi</a> &nbsp;
<a href="entries/Encodability_Process_Calculi.html">Encodability_Process_Calculi</a> &nbsp;
<a href="entries/Circus.html">Circus</a> &nbsp;
<a href="entries/Noninterference_Sequential_Composition.html">Noninterference_Sequential_Composition</a> &nbsp;
<a href="entries/Noninterference_Concurrent_Composition.html">Noninterference_Concurrent_Composition</a> &nbsp;
<a href="entries/Modal_Logics_for_NTS.html">Modal_Logics_for_NTS</a> &nbsp;
<a href="entries/HOL-CSP.html">HOL-CSP</a> &nbsp;
</div>
<h3>Data structures</h3>
<div class="list">
<a href="entries/Generic_Deriving.html">Generic_Deriving</a> &nbsp;
<a href="entries/Random_BSTs.html">Random_BSTs</a> &nbsp;
<a href="entries/Randomised_BSTs.html">Randomised_BSTs</a> &nbsp;
<a href="entries/List_Interleaving.html">List_Interleaving</a> &nbsp;
<a href="entries/Refine_Imperative_HOL.html">Refine_Imperative_HOL</a> &nbsp;
<a href="entries/Amortized_Complexity.html">Amortized_Complexity</a> &nbsp;
<a href="entries/Dynamic_Tables.html">Dynamic_Tables</a> &nbsp;
<a href="entries/AVL-Trees.html">AVL-Trees</a> &nbsp;
<a href="entries/BDD.html">BDD</a> &nbsp;
<a href="entries/BinarySearchTree.html">BinarySearchTree</a> &nbsp;
<a href="entries/Splay_Tree.html">Splay_Tree</a> &nbsp;
<a href="entries/Root_Balanced_Tree.html">Root_Balanced_Tree</a> &nbsp;
<a href="entries/Skew_Heap.html">Skew_Heap</a> &nbsp;
<a href="entries/Pairing_Heap.html">Pairing_Heap</a> &nbsp;
<a href="entries/Priority_Queue_Braun.html">Priority_Queue_Braun</a> &nbsp;
<a href="entries/Binomial-Queues.html">Binomial-Queues</a> &nbsp;
<a href="entries/Binomial-Heaps.html">Binomial-Heaps</a> &nbsp;
<a href="entries/Finger-Trees.html">Finger-Trees</a> &nbsp;
<a href="entries/Trie.html">Trie</a> &nbsp;
<a href="entries/FinFun.html">FinFun</a> &nbsp;
<a href="entries/Collections.html">Collections</a> &nbsp;
<a href="entries/Containers.html">Containers</a> &nbsp;
<a href="entries/FileRefinement.html">FileRefinement</a> &nbsp;
<a href="entries/Datatype_Order_Generator.html">Datatype_Order_Generator</a> &nbsp;
<a href="entries/Deriving.html">Deriving</a> &nbsp;
<a href="entries/List-Index.html">List-Index</a> &nbsp;
<a href="entries/List-Infinite.html">List-Infinite</a> &nbsp;
<a href="entries/Matrix.html">Matrix</a> &nbsp;
<a href="entries/Matrix_Tensor.html">Matrix_Tensor</a> &nbsp;
<a href="entries/Huffman.html">Huffman</a> &nbsp;
<a href="entries/Lazy-Lists-II.html">Lazy-Lists-II</a> &nbsp;
<a href="entries/IEEE_Floating_Point.html">IEEE_Floating_Point</a> &nbsp;
<a href="entries/Native_Word.html">Native_Word</a> &nbsp;
<a href="entries/XML.html">XML</a> &nbsp;
<a href="entries/ROBDD.html">ROBDD</a> &nbsp;
<a href="entries/IMAP-CRDT.html">IMAP-CRDT</a> &nbsp;
<a href="entries/Word_Lib.html">Word_Lib</a> &nbsp;
<a href="entries/CRDT.html">CRDT</a> &nbsp;
<a href="entries/KD_Tree.html">KD_Tree</a> &nbsp;
<a href="entries/Taylor_Models.html">Taylor_Models</a> &nbsp;
<a href="entries/Treaps.html">Treaps</a> &nbsp;
<a href="entries/Skip_Lists.html">Skip_Lists</a> &nbsp;
<a href="entries/Weight_Balanced_Trees.html">Weight_Balanced_Trees</a> &nbsp;
<a href="entries/OpSets.html">OpSets</a> &nbsp;
<a href="entries/Optimal_BST.html">Optimal_BST</a> &nbsp;
<a href="entries/Core_DOM.html">Core_DOM</a> &nbsp;
+ <a href="entries/Core_SC_DOM.html">Core_SC_DOM</a> &nbsp;
+ <a href="entries/Shadow_SC_DOM.html">Shadow_SC_DOM</a> &nbsp;
+ <a href="entries/SC_DOM_Components.html">SC_DOM_Components</a> &nbsp;
<a href="entries/Auto2_Imperative_HOL.html">Auto2_Imperative_HOL</a> &nbsp;
<a href="entries/IMP2_Binary_Heap.html">IMP2_Binary_Heap</a> &nbsp;
<a href="entries/Priority_Search_Trees.html">Priority_Search_Trees</a> &nbsp;
<a href="entries/Interval_Arithmetic_Word32.html">Interval_Arithmetic_Word32</a> &nbsp;
<a href="entries/ADS_Functor.html">ADS_Functor</a> &nbsp;
<a href="entries/Relational_Disjoint_Set_Forests.html">Relational_Disjoint_Set_Forests</a> &nbsp;
</div>
<h3>Functional programming</h3>
<div class="list">
<a href="entries/Optics.html">Optics</a> &nbsp;
<a href="entries/CryptHOL.html">CryptHOL</a> &nbsp;
<a href="entries/Probabilistic_While.html">Probabilistic_While</a> &nbsp;
<a href="entries/Monad_Normalisation.html">Monad_Normalisation</a> &nbsp;
<a href="entries/Monomorphic_Monad.html">Monomorphic_Monad</a> &nbsp;
<a href="entries/Show.html">Show</a> &nbsp;
<a href="entries/Certification_Monads.html">Certification_Monads</a> &nbsp;
<a href="entries/Partial_Function_MR.html">Partial_Function_MR</a> &nbsp;
<a href="entries/Lifting_Definition_Option.html">Lifting_Definition_Option</a> &nbsp;
<a href="entries/Coinductive.html">Coinductive</a> &nbsp;
<a href="entries/Stream-Fusion.html">Stream-Fusion</a> &nbsp;
<a href="entries/Tycon.html">Tycon</a> &nbsp;
<a href="entries/Monad_Memo_DP.html">Monad_Memo_DP</a> &nbsp;
<a href="entries/XML.html">XML</a> &nbsp;
<a href="entries/Tail_Recursive_Functions.html">Tail_Recursive_Functions</a> &nbsp;
<a href="entries/Stream_Fusion_Code.html">Stream_Fusion_Code</a> &nbsp;
<a href="entries/Applicative_Lifting.html">Applicative_Lifting</a> &nbsp;
<a href="entries/HOLCF-Prelude.html">HOLCF-Prelude</a> &nbsp;
<a href="entries/BNF_CC.html">BNF_CC</a> &nbsp;
<a href="entries/Binding_Syntax_Theory.html">Binding_Syntax_Theory</a> &nbsp;
<a href="entries/Generalized_Counting_Sort.html">Generalized_Counting_Sort</a> &nbsp;
<a href="entries/Hello_World.html">Hello_World</a> &nbsp;
<a href="entries/BirdKMP.html">BirdKMP</a> &nbsp;
</div>
<h3>Hardware</h3>
<div class="list">
<a href="entries/SPARCv8.html">SPARCv8</a> &nbsp;
</div>
<h3>Machine learning</h3>
<div class="list">
<a href="entries/Deep_Learning.html">Deep_Learning</a> &nbsp;
<a href="entries/Inductive_Inference.html">Inductive_Inference</a> &nbsp;
</div>
<h3>Networks</h3>
<div class="list">
<a href="entries/UPF_Firewall.html">UPF_Firewall</a> &nbsp;
<a href="entries/IP_Addresses.html">IP_Addresses</a> &nbsp;
<a href="entries/Simple_Firewall.html">Simple_Firewall</a> &nbsp;
<a href="entries/Iptables_Semantics.html">Iptables_Semantics</a> &nbsp;
<a href="entries/Routing.html">Routing</a> &nbsp;
<a href="entries/LOFT.html">LOFT</a> &nbsp;
</div>
<h3>Programming languages</h3>
<div class="list">
<a href="entries/Clean.html">Clean</a> &nbsp;
<a href="entries/Decl_Sem_Fun_PL.html">Decl_Sem_Fun_PL</a> &nbsp;
<strong>Language definitions:</strong>
<a href="entries/CakeML.html">CakeML</a> &nbsp;
<a href="entries/WebAssembly.html">WebAssembly</a> &nbsp;
<a href="entries/pGCL.html">pGCL</a> &nbsp;
<a href="entries/GPU_Kernel_PL.html">GPU_Kernel_PL</a> &nbsp;
<a href="entries/LightweightJava.html">LightweightJava</a> &nbsp;
<a href="entries/CoreC++.html">CoreC++</a> &nbsp;
<a href="entries/FeatherweightJava.html">FeatherweightJava</a> &nbsp;
<a href="entries/Jinja.html">Jinja</a> &nbsp;
<a href="entries/JinjaThreads.html">JinjaThreads</a> &nbsp;
<a href="entries/Locally-Nameless-Sigma.html">Locally-Nameless-Sigma</a> &nbsp;
<a href="entries/AutoFocus-Stream.html">AutoFocus-Stream</a> &nbsp;
<a href="entries/FocusStreamsCaseStudies.html">FocusStreamsCaseStudies</a> &nbsp;
<a href="entries/Isabelle_Meta_Model.html">Isabelle_Meta_Model</a> &nbsp;
<a href="entries/Simpl.html">Simpl</a> &nbsp;
<a href="entries/Complx.html">Complx</a> &nbsp;
<a href="entries/Safe_OCL.html">Safe_OCL</a> &nbsp;
<a href="entries/Isabelle_C.html">Isabelle_C</a> &nbsp;
<strong>Lambda calculi:</strong>
<a href="entries/Higher_Order_Terms.html">Higher_Order_Terms</a> &nbsp;
<a href="entries/Launchbury.html">Launchbury</a> &nbsp;
<a href="entries/PCF.html">PCF</a> &nbsp;
<a href="entries/POPLmark-deBruijn.html">POPLmark-deBruijn</a> &nbsp;
<a href="entries/Lam-ml-Normalization.html">Lam-ml-Normalization</a> &nbsp;
<a href="entries/LambdaMu.html">LambdaMu</a> &nbsp;
<a href="entries/Binding_Syntax_Theory.html">Binding_Syntax_Theory</a> &nbsp;
<a href="entries/LambdaAuth.html">LambdaAuth</a> &nbsp;
<strong>Type systems:</strong>
<a href="entries/Name_Carrying_Type_Inference.html">Name_Carrying_Type_Inference</a> &nbsp;
<a href="entries/MiniML.html">MiniML</a> &nbsp;
<a href="entries/Possibilistic_Noninterference.html">Possibilistic_Noninterference</a> &nbsp;
<a href="entries/SIFUM_Type_Systems.html">SIFUM_Type_Systems</a> &nbsp;
<a href="entries/Dependent_SIFUM_Type_Systems.html">Dependent_SIFUM_Type_Systems</a> &nbsp;
<a href="entries/Strong_Security.html">Strong_Security</a> &nbsp;
<a href="entries/WHATandWHERE_Security.html">WHATandWHERE_Security</a> &nbsp;
<a href="entries/VolpanoSmith.html">VolpanoSmith</a> &nbsp;
+ <a href="entries/Physical_Quantities.html">Physical_Quantities</a> &nbsp;
<strong>Logics:</strong>
<a href="entries/ConcurrentIMP.html">ConcurrentIMP</a> &nbsp;
<a href="entries/Refine_Monadic.html">Refine_Monadic</a> &nbsp;
<a href="entries/Automatic_Refinement.html">Automatic_Refinement</a> &nbsp;
<a href="entries/MonoBoolTranAlgebra.html">MonoBoolTranAlgebra</a> &nbsp;
<a href="entries/Simpl.html">Simpl</a> &nbsp;
<a href="entries/Separation_Algebra.html">Separation_Algebra</a> &nbsp;
<a href="entries/Separation_Logic_Imperative_HOL.html">Separation_Logic_Imperative_HOL</a> &nbsp;
<a href="entries/Relational-Incorrectness-Logic.html">Relational-Incorrectness-Logic</a> &nbsp;
<a href="entries/Abstract-Hoare-Logics.html">Abstract-Hoare-Logics</a> &nbsp;
<a href="entries/Kleene_Algebra.html">Kleene_Algebra</a> &nbsp;
<a href="entries/KAT_and_DRA.html">KAT_and_DRA</a> &nbsp;
<a href="entries/KAD.html">KAD</a> &nbsp;
<a href="entries/BytecodeLogicJmlTypes.html">BytecodeLogicJmlTypes</a> &nbsp;
<a href="entries/DataRefinementIBP.html">DataRefinementIBP</a> &nbsp;
<a href="entries/RefinementReactive.html">RefinementReactive</a> &nbsp;
<a href="entries/SIFPL.html">SIFPL</a> &nbsp;
<a href="entries/TLA.html">TLA</a> &nbsp;
<a href="entries/Ribbon_Proofs.html">Ribbon_Proofs</a> &nbsp;
<a href="entries/Separata.html">Separata</a> &nbsp;
<a href="entries/Complx.html">Complx</a> &nbsp;
<a href="entries/Differential_Dynamic_Logic.html">Differential_Dynamic_Logic</a> &nbsp;
<a href="entries/Hoare_Time.html">Hoare_Time</a> &nbsp;
<a href="entries/IMP2.html">IMP2</a> &nbsp;
<a href="entries/UTP.html">UTP</a> &nbsp;
<a href="entries/QHLProver.html">QHLProver</a> &nbsp;
<a href="entries/Differential_Game_Logic.html">Differential_Game_Logic</a> &nbsp;
<strong>Compiling:</strong>
<a href="entries/CakeML_Codegen.html">CakeML_Codegen</a> &nbsp;
<a href="entries/Compiling-Exceptions-Correctly.html">Compiling-Exceptions-Correctly</a> &nbsp;
<a href="entries/NormByEval.html">NormByEval</a> &nbsp;
<a href="entries/Density_Compiler.html">Density_Compiler</a> &nbsp;
<a href="entries/VeriComp.html">VeriComp</a> &nbsp;
<strong>Static analysis:</strong>
<a href="entries/RIPEMD-160-SPARK.html">RIPEMD-160-SPARK</a> &nbsp;
<a href="entries/Program-Conflict-Analysis.html">Program-Conflict-Analysis</a> &nbsp;
<a href="entries/Shivers-CFA.html">Shivers-CFA</a> &nbsp;
<a href="entries/Slicing.html">Slicing</a> &nbsp;
<a href="entries/HRB-Slicing.html">HRB-Slicing</a> &nbsp;
<a href="entries/InfPathElimination.html">InfPathElimination</a> &nbsp;
<a href="entries/Abs_Int_ITP2012.html">Abs_Int_ITP2012</a> &nbsp;
<strong>Transformations:</strong>
<a href="entries/Call_Arity.html">Call_Arity</a> &nbsp;
<a href="entries/Refine_Imperative_HOL.html">Refine_Imperative_HOL</a> &nbsp;
<a href="entries/WorkerWrapper.html">WorkerWrapper</a> &nbsp;
<a href="entries/Monad_Memo_DP.html">Monad_Memo_DP</a> &nbsp;
<a href="entries/Formal_SSA.html">Formal_SSA</a> &nbsp;
<a href="entries/Minimal_SSA.html">Minimal_SSA</a> &nbsp;
<strong>Misc:</strong>
<a href="entries/JiveDataStoreModel.html">JiveDataStoreModel</a> &nbsp;
<a href="entries/Pop_Refinement.html">Pop_Refinement</a> &nbsp;
<a href="entries/Case_Labeling.html">Case_Labeling</a> &nbsp;
</div>
<h3>Security</h3>
<div class="list">
<a href="entries/Multi_Party_Computation.html">Multi_Party_Computation</a> &nbsp;
<a href="entries/Noninterference_Generic_Unwinding.html">Noninterference_Generic_Unwinding</a> &nbsp;
<a href="entries/Noninterference_Ipurge_Unwinding.html">Noninterference_Ipurge_Unwinding</a> &nbsp;
<a href="entries/UPF.html">UPF</a> &nbsp;
<a href="entries/UPF_Firewall.html">UPF_Firewall</a> &nbsp;
<a href="entries/CISC-Kernel.html">CISC-Kernel</a> &nbsp;
<a href="entries/Noninterference_CSP.html">Noninterference_CSP</a> &nbsp;
<a href="entries/Key_Agreement_Strong_Adversaries.html">Key_Agreement_Strong_Adversaries</a> &nbsp;
<a href="entries/Security_Protocol_Refinement.html">Security_Protocol_Refinement</a> &nbsp;
<a href="entries/Attack_Trees.html">Attack_Trees</a> &nbsp;
<a href="entries/Inductive_Confidentiality.html">Inductive_Confidentiality</a> &nbsp;
<a href="entries/Possibilistic_Noninterference.html">Possibilistic_Noninterference</a> &nbsp;
<a href="entries/SIFUM_Type_Systems.html">SIFUM_Type_Systems</a> &nbsp;
<a href="entries/Dependent_SIFUM_Type_Systems.html">Dependent_SIFUM_Type_Systems</a> &nbsp;
<a href="entries/Dependent_SIFUM_Refinement.html">Dependent_SIFUM_Refinement</a> &nbsp;
<a href="entries/Relational-Incorrectness-Logic.html">Relational-Incorrectness-Logic</a> &nbsp;
<a href="entries/Strong_Security.html">Strong_Security</a> &nbsp;
<a href="entries/WHATandWHERE_Security.html">WHATandWHERE_Security</a> &nbsp;
<a href="entries/VolpanoSmith.html">VolpanoSmith</a> &nbsp;
<a href="entries/SIFPL.html">SIFPL</a> &nbsp;
<a href="entries/HotelKeyCards.html">HotelKeyCards</a> &nbsp;
<a href="entries/InformationFlowSlicing.html">InformationFlowSlicing</a> &nbsp;
<a href="entries/InformationFlowSlicing_Inter.html">InformationFlowSlicing_Inter</a> &nbsp;
<a href="entries/CryptoBasedCompositionalProperties.html">CryptoBasedCompositionalProperties</a> &nbsp;
<a href="entries/Probabilistic_Noninterference.html">Probabilistic_Noninterference</a> &nbsp;
<a href="entries/HyperCTL.html">HyperCTL</a> &nbsp;
<a href="entries/Bounded_Deducibility_Security.html">Bounded_Deducibility_Security</a> &nbsp;
<a href="entries/Network_Security_Policy_Verification.html">Network_Security_Policy_Verification</a> &nbsp;
<a href="entries/Noninterference_Inductive_Unwinding.html">Noninterference_Inductive_Unwinding</a> &nbsp;
<a href="entries/Password_Authentication_Protocol.html">Password_Authentication_Protocol</a> &nbsp;
<a href="entries/Noninterference_Sequential_Composition.html">Noninterference_Sequential_Composition</a> &nbsp;
<a href="entries/Noninterference_Concurrent_Composition.html">Noninterference_Concurrent_Composition</a> &nbsp;
<a href="entries/SPARCv8.html">SPARCv8</a> &nbsp;
<a href="entries/Modular_Assembly_Kit_Security.html">Modular_Assembly_Kit_Security</a> &nbsp;
<a href="entries/LambdaAuth.html">LambdaAuth</a> &nbsp;
<a href="entries/Stateful_Protocol_Composition_and_Typing.html">Stateful_Protocol_Composition_and_Typing</a> &nbsp;
<a href="entries/Automated_Stateful_Protocol_Verification.html">Automated_Stateful_Protocol_Verification</a> &nbsp;
<strong>Cryptography:</strong>
<a href="entries/Game_Based_Crypto.html">Game_Based_Crypto</a> &nbsp;
<a href="entries/Sigma_Commit_Crypto.html">Sigma_Commit_Crypto</a> &nbsp;
<a href="entries/CryptHOL.html">CryptHOL</a> &nbsp;
<a href="entries/Constructive_Cryptography.html">Constructive_Cryptography</a> &nbsp;
<a href="entries/RSAPSS.html">RSAPSS</a> &nbsp;
<a href="entries/Elliptic_Curves_Group_Law.html">Elliptic_Curves_Group_Law</a> &nbsp;
</div>
<h3>Semantics</h3>
<div class="list">
<a href="entries/Launchbury.html">Launchbury</a> &nbsp;
<a href="entries/Clean.html">Clean</a> &nbsp;
<a href="entries/Transformer_Semantics.html">Transformer_Semantics</a> &nbsp;
<a href="entries/HOL-CSP.html">HOL-CSP</a> &nbsp;
<a href="entries/QHLProver.html">QHLProver</a> &nbsp;
<a href="entries/TESL_Language.html">TESL_Language</a> &nbsp;
<a href="entries/Isabelle_C.html">Isabelle_C</a> &nbsp;
</div>
<h3>System description languages</h3>
<div class="list">
<a href="entries/Circus.html">Circus</a> &nbsp;
<a href="entries/ComponentDependencies.html">ComponentDependencies</a> &nbsp;
<a href="entries/Promela.html">Promela</a> &nbsp;
<a href="entries/Featherweight_OCL.html">Featherweight_OCL</a> &nbsp;
<a href="entries/DynamicArchitectures.html">DynamicArchitectures</a> &nbsp;
<a href="entries/Architectural_Design_Patterns.html">Architectural_Design_Patterns</a> &nbsp;
<a href="entries/TESL_Language.html">TESL_Language</a> &nbsp;
</div>
<h2>Logic</h2>
<div class="list">
</div>
<h3>Philosophical aspects</h3>
<div class="list">
<a href="entries/GoedelGod.html">GoedelGod</a> &nbsp;
<a href="entries/Types_Tableaus_and_Goedels_God.html">Types_Tableaus_and_Goedels_God</a> &nbsp;
<a href="entries/GewirthPGCProof.html">GewirthPGCProof</a> &nbsp;
<a href="entries/Lowe_Ontological_Argument.html">Lowe_Ontological_Argument</a> &nbsp;
<a href="entries/AnselmGod.html">AnselmGod</a> &nbsp;
<a href="entries/PLM.html">PLM</a> &nbsp;
<a href="entries/Aristotles_Assertoric_Syllogistic.html">Aristotles_Assertoric_Syllogistic</a> &nbsp;
</div>
<h3>General logic</h3>
<div class="list">
<strong>Classical propositional logic:</strong>
<a href="entries/Free-Boolean-Algebra.html">Free-Boolean-Algebra</a> &nbsp;
<strong>Classical first-order logic:</strong>
<a href="entries/FOL-Fitting.html">FOL-Fitting</a> &nbsp;
<strong>Decidability of theories:</strong>
<a href="entries/MSO_Regex_Equivalence.html">MSO_Regex_Equivalence</a> &nbsp;
<a href="entries/Formula_Derivatives.html">Formula_Derivatives</a> &nbsp;
<a href="entries/Presburger-Automata.html">Presburger-Automata</a> &nbsp;
<a href="entries/LinearQuantifierElim.html">LinearQuantifierElim</a> &nbsp;
<strong>Mechanization of proofs:</strong>
<a href="entries/Boolean_Expression_Checkers.html">Boolean_Expression_Checkers</a> &nbsp;
<a href="entries/Verified-Prover.html">Verified-Prover</a> &nbsp;
<a href="entries/Sort_Encodings.html">Sort_Encodings</a> &nbsp;
<a href="entries/PropResPI.html">PropResPI</a> &nbsp;
<a href="entries/Resolution_FOL.html">Resolution_FOL</a> &nbsp;
<a href="entries/FOL_Harrison.html">FOL_Harrison</a> &nbsp;
<a href="entries/Ordered_Resolution_Prover.html">Ordered_Resolution_Prover</a> &nbsp;
<a href="entries/Functional_Ordered_Resolution_Prover.html">Functional_Ordered_Resolution_Prover</a> &nbsp;
<a href="entries/Binding_Syntax_Theory.html">Binding_Syntax_Theory</a> &nbsp;
<a href="entries/Saturation_Framework.html">Saturation_Framework</a> &nbsp;
<a href="entries/Saturation_Framework_Extensions.html">Saturation_Framework_Extensions</a> &nbsp;
<strong>Lambda calculus:</strong>
<a href="entries/LambdaMu.html">LambdaMu</a> &nbsp;
<strong>Logics of knowledge and belief:</strong>
<a href="entries/Epistemic_Logic.html">Epistemic_Logic</a> &nbsp;
<strong>Temporal logic:</strong>
<a href="entries/Nat-Interval-Logic.html">Nat-Interval-Logic</a> &nbsp;
<a href="entries/LTL.html">LTL</a> &nbsp;
<a href="entries/HyperCTL.html">HyperCTL</a> &nbsp;
<a href="entries/Allen_Calculus.html">Allen_Calculus</a> &nbsp;
<a href="entries/MFOTL_Monitor.html">MFOTL_Monitor</a> &nbsp;
<a href="entries/LTL_Normal_Form.html">LTL_Normal_Form</a> &nbsp;
<strong>Modal logic:</strong>
<a href="entries/Modal_Logics_for_NTS.html">Modal_Logics_for_NTS</a> &nbsp;
<a href="entries/Differential_Dynamic_Logic.html">Differential_Dynamic_Logic</a> &nbsp;
<a href="entries/Hybrid_Multi_Lane_Spatial_Logic.html">Hybrid_Multi_Lane_Spatial_Logic</a> &nbsp;
<a href="entries/Hybrid_Logic.html">Hybrid_Logic</a> &nbsp;
<a href="entries/MFODL_Monitor_Optimized.html">MFODL_Monitor_Optimized</a> &nbsp;
<strong>Paraconsistent logics:</strong>
<a href="entries/Paraconsistency.html">Paraconsistency</a> &nbsp;
</div>
<h3>Computability</h3>
<div class="list">
<a href="entries/Universal_Turing_Machine.html">Universal_Turing_Machine</a> &nbsp;
<a href="entries/Recursion-Theory-I.html">Recursion-Theory-I</a> &nbsp;
<a href="entries/Inductive_Inference.html">Inductive_Inference</a> &nbsp;
<a href="entries/Minsky_Machines.html">Minsky_Machines</a> &nbsp;
</div>
<h3>Set theory</h3>
<div class="list">
<a href="entries/Ordinal.html">Ordinal</a> &nbsp;
<a href="entries/Ordinals_and_Cardinals.html">Ordinals_and_Cardinals</a> &nbsp;
<a href="entries/HereditarilyFinite.html">HereditarilyFinite</a> &nbsp;
<a href="entries/ZFC_in_HOL.html">ZFC_in_HOL</a> &nbsp;
<a href="entries/Forcing.html">Forcing</a> &nbsp;
<a href="entries/Recursion-Addition.html">Recursion-Addition</a> &nbsp;
<a href="entries/Ordinal_Partitions.html">Ordinal_Partitions</a> &nbsp;
</div>
<h3>Proof theory</h3>
<div class="list">
<a href="entries/Propositional_Proof_Systems.html">Propositional_Proof_Systems</a> &nbsp;
<a href="entries/Completeness.html">Completeness</a> &nbsp;
<a href="entries/SequentInvertibility.html">SequentInvertibility</a> &nbsp;
<a href="entries/Incompleteness.html">Incompleteness</a> &nbsp;
<a href="entries/Abstract_Completeness.html">Abstract_Completeness</a> &nbsp;
<a href="entries/SuperCalc.html">SuperCalc</a> &nbsp;
<a href="entries/Incredible_Proof_Machine.html">Incredible_Proof_Machine</a> &nbsp;
<a href="entries/Surprise_Paradox.html">Surprise_Paradox</a> &nbsp;
<a href="entries/Abstract_Soundness.html">Abstract_Soundness</a> &nbsp;
<a href="entries/Syntax_Independent_Logic.html">Syntax_Independent_Logic</a> &nbsp;
<a href="entries/Goedel_Incompleteness.html">Goedel_Incompleteness</a> &nbsp;
<a href="entries/Goedel_HFSet_Semantic.html">Goedel_HFSet_Semantic</a> &nbsp;
<a href="entries/Goedel_HFSet_Semanticless.html">Goedel_HFSet_Semanticless</a> &nbsp;
<a href="entries/Robinson_Arithmetic.html">Robinson_Arithmetic</a> &nbsp;
<a href="entries/FOL_Seq_Calc1.html">FOL_Seq_Calc1</a> &nbsp;
</div>
<h3>Rewriting</h3>
<div class="list">
<a href="entries/CakeML_Codegen.html">CakeML_Codegen</a> &nbsp;
<a href="entries/Monad_Normalisation.html">Monad_Normalisation</a> &nbsp;
<a href="entries/Lambda_Free_RPOs.html">Lambda_Free_RPOs</a> &nbsp;
<a href="entries/Lambda_Free_KBOs.html">Lambda_Free_KBOs</a> &nbsp;
<a href="entries/Lambda_Free_EPO.html">Lambda_Free_EPO</a> &nbsp;
<a href="entries/Nested_Multisets_Ordinals.html">Nested_Multisets_Ordinals</a> &nbsp;
<a href="entries/Abstract-Rewriting.html">Abstract-Rewriting</a> &nbsp;
<a href="entries/First_Order_Terms.html">First_Order_Terms</a> &nbsp;
<a href="entries/Decreasing-Diagrams.html">Decreasing-Diagrams</a> &nbsp;
<a href="entries/Decreasing-Diagrams-II.html">Decreasing-Diagrams-II</a> &nbsp;
<a href="entries/Rewriting_Z.html">Rewriting_Z</a> &nbsp;
<a href="entries/Graph_Saturation.html">Graph_Saturation</a> &nbsp;
<a href="entries/Goodstein_Lambda.html">Goodstein_Lambda</a> &nbsp;
<a href="entries/Knuth_Bendix_Order.html">Knuth_Bendix_Order</a> &nbsp;
</div>
<h2>Mathematics</h2>
<div class="list">
</div>
<h3>Order</h3>
<div class="list">
<a href="entries/LatticeProperties.html">LatticeProperties</a> &nbsp;
<a href="entries/Stone_Algebras.html">Stone_Algebras</a> &nbsp;
<a href="entries/Allen_Calculus.html">Allen_Calculus</a> &nbsp;
<a href="entries/Order_Lattice_Props.html">Order_Lattice_Props</a> &nbsp;
<a href="entries/Complete_Non_Orders.html">Complete_Non_Orders</a> &nbsp;
<a href="entries/Szpilrajn.html">Szpilrajn</a> &nbsp;
</div>
<h3>Algebra</h3>
<div class="list">
<a href="entries/Optics.html">Optics</a> &nbsp;
<a href="entries/Subresultants.html">Subresultants</a> &nbsp;
<a href="entries/Buildings.html">Buildings</a> &nbsp;
<a href="entries/Algebraic_VCs.html">Algebraic_VCs</a> &nbsp;
<a href="entries/C2KA_DistributedSystems.html">C2KA_DistributedSystems</a> &nbsp;
<a href="entries/Multirelations.html">Multirelations</a> &nbsp;
<a href="entries/Residuated_Lattices.html">Residuated_Lattices</a> &nbsp;
<a href="entries/PseudoHoops.html">PseudoHoops</a> &nbsp;
<a href="entries/Impossible_Geometry.html">Impossible_Geometry</a> &nbsp;
<a href="entries/Gauss-Jordan-Elim-Fun.html">Gauss-Jordan-Elim-Fun</a> &nbsp;
<a href="entries/Matrix_Tensor.html">Matrix_Tensor</a> &nbsp;
<a href="entries/Kleene_Algebra.html">Kleene_Algebra</a> &nbsp;
<a href="entries/KAT_and_DRA.html">KAT_and_DRA</a> &nbsp;
<a href="entries/KAD.html">KAD</a> &nbsp;
<a href="entries/Regular_Algebras.html">Regular_Algebras</a> &nbsp;
<a href="entries/Free-Groups.html">Free-Groups</a> &nbsp;
<a href="entries/CofGroups.html">CofGroups</a> &nbsp;
<a href="entries/Group-Ring-Module.html">Group-Ring-Module</a> &nbsp;
<a href="entries/Robbins-Conjecture.html">Robbins-Conjecture</a> &nbsp;
<a href="entries/Valuation.html">Valuation</a> &nbsp;
<a href="entries/Rank_Nullity_Theorem.html">Rank_Nullity_Theorem</a> &nbsp;
<a href="entries/Polynomials.html">Polynomials</a> &nbsp;
<a href="entries/Relation_Algebra.html">Relation_Algebra</a> &nbsp;
<a href="entries/PSemigroupsConvolution.html">PSemigroupsConvolution</a> &nbsp;
<a href="entries/Secondary_Sylow.html">Secondary_Sylow</a> &nbsp;
<a href="entries/Jordan_Hoelder.html">Jordan_Hoelder</a> &nbsp;
<a href="entries/Cayley_Hamilton.html">Cayley_Hamilton</a> &nbsp;
<a href="entries/VectorSpace.html">VectorSpace</a> &nbsp;
<a href="entries/Echelon_Form.html">Echelon_Form</a> &nbsp;
<a href="entries/QR_Decomposition.html">QR_Decomposition</a> &nbsp;
<a href="entries/Hermite.html">Hermite</a> &nbsp;
<a href="entries/Rep_Fin_Groups.html">Rep_Fin_Groups</a> &nbsp;
<a href="entries/Jordan_Normal_Form.html">Jordan_Normal_Form</a> &nbsp;
<a href="entries/Algebraic_Numbers.html">Algebraic_Numbers</a> &nbsp;
<a href="entries/Polynomial_Interpolation.html">Polynomial_Interpolation</a> &nbsp;
<a href="entries/Polynomial_Factorization.html">Polynomial_Factorization</a> &nbsp;
<a href="entries/Perron_Frobenius.html">Perron_Frobenius</a> &nbsp;
<a href="entries/Stochastic_Matrices.html">Stochastic_Matrices</a> &nbsp;
<a href="entries/Groebner_Bases.html">Groebner_Bases</a> &nbsp;
<a href="entries/Nullstellensatz.html">Nullstellensatz</a> &nbsp;
<a href="entries/Mason_Stothers.html">Mason_Stothers</a> &nbsp;
<a href="entries/Berlekamp_Zassenhaus.html">Berlekamp_Zassenhaus</a> &nbsp;
<a href="entries/Stone_Relation_Algebras.html">Stone_Relation_Algebras</a> &nbsp;
<a href="entries/Stone_Kleene_Relation_Algebras.html">Stone_Kleene_Relation_Algebras</a> &nbsp;
<a href="entries/Orbit_Stabiliser.html">Orbit_Stabiliser</a> &nbsp;
<a href="entries/Dirichlet_L.html">Dirichlet_L</a> &nbsp;
<a href="entries/Symmetric_Polynomials.html">Symmetric_Polynomials</a> &nbsp;
<a href="entries/Taylor_Models.html">Taylor_Models</a> &nbsp;
<a href="entries/LLL_Basis_Reduction.html">LLL_Basis_Reduction</a> &nbsp;
<a href="entries/LLL_Factorization.html">LLL_Factorization</a> &nbsp;
<a href="entries/Localization_Ring.html">Localization_Ring</a> &nbsp;
<a href="entries/Quaternions.html">Quaternions</a> &nbsp;
<a href="entries/Octonions.html">Octonions</a> &nbsp;
<a href="entries/Aggregation_Algebras.html">Aggregation_Algebras</a> &nbsp;
<a href="entries/Signature_Groebner.html">Signature_Groebner</a> &nbsp;
<a href="entries/Quantales.html">Quantales</a> &nbsp;
<a href="entries/Transformer_Semantics.html">Transformer_Semantics</a> &nbsp;
<a href="entries/Farkas.html">Farkas</a> &nbsp;
<a href="entries/Groebner_Macaulay.html">Groebner_Macaulay</a> &nbsp;
<a href="entries/Linear_Inequalities.html">Linear_Inequalities</a> &nbsp;
<a href="entries/Linear_Programming.html">Linear_Programming</a> &nbsp;
<a href="entries/Jacobson_Basic_Algebra.html">Jacobson_Basic_Algebra</a> &nbsp;
<a href="entries/Hybrid_Systems_VCs.html">Hybrid_Systems_VCs</a> &nbsp;
<a href="entries/Subset_Boolean_Algebras.html">Subset_Boolean_Algebras</a> &nbsp;
<a href="entries/Power_Sum_Polynomials.html">Power_Sum_Polynomials</a> &nbsp;
<a href="entries/Matrices_for_ODEs.html">Matrices_for_ODEs</a> &nbsp;
<a href="entries/Smith_Normal_Form.html">Smith_Normal_Form</a> &nbsp;
</div>
<h3>Analysis</h3>
<div class="list">
<a href="entries/Banach_Steinhaus.html">Banach_Steinhaus</a> &nbsp;
<a href="entries/Fourier.html">Fourier</a> &nbsp;
<a href="entries/E_Transcendental.html">E_Transcendental</a> &nbsp;
<a href="entries/Liouville_Numbers.html">Liouville_Numbers</a> &nbsp;
<a href="entries/Descartes_Sign_Rule.html">Descartes_Sign_Rule</a> &nbsp;
<a href="entries/Euler_MacLaurin.html">Euler_MacLaurin</a> &nbsp;
<a href="entries/Real_Impl.html">Real_Impl</a> &nbsp;
<a href="entries/Lower_Semicontinuous.html">Lower_Semicontinuous</a> &nbsp;
<a href="entries/Affine_Arithmetic.html">Affine_Arithmetic</a> &nbsp;
<a href="entries/Laplace_Transform.html">Laplace_Transform</a> &nbsp;
<a href="entries/Cauchy.html">Cauchy</a> &nbsp;
<a href="entries/Integration.html">Integration</a> &nbsp;
<a href="entries/Ordinary_Differential_Equations.html">Ordinary_Differential_Equations</a> &nbsp;
<a href="entries/Polynomials.html">Polynomials</a> &nbsp;
<a href="entries/Sqrt_Babylonian.html">Sqrt_Babylonian</a> &nbsp;
<a href="entries/Sturm_Sequences.html">Sturm_Sequences</a> &nbsp;
<a href="entries/Sturm_Tarski.html">Sturm_Tarski</a> &nbsp;
<a href="entries/Special_Function_Bounds.html">Special_Function_Bounds</a> &nbsp;
<a href="entries/Landau_Symbols.html">Landau_Symbols</a> &nbsp;
<a href="entries/Error_Function.html">Error_Function</a> &nbsp;
<a href="entries/Akra_Bazzi.html">Akra_Bazzi</a> &nbsp;
<a href="entries/Zeta_Function.html">Zeta_Function</a> &nbsp;
<a href="entries/Linear_Recurrences.html">Linear_Recurrences</a> &nbsp;
<a href="entries/Lambert_W.html">Lambert_W</a> &nbsp;
<a href="entries/Cartan_FP.html">Cartan_FP</a> &nbsp;
<a href="entries/Deep_Learning.html">Deep_Learning</a> &nbsp;
<a href="entries/Stirling_Formula.html">Stirling_Formula</a> &nbsp;
<a href="entries/Lp.html">Lp</a> &nbsp;
<a href="entries/Bernoulli.html">Bernoulli</a> &nbsp;
<a href="entries/Winding_Number_Eval.html">Winding_Number_Eval</a> &nbsp;
<a href="entries/Count_Complex_Roots.html">Count_Complex_Roots</a> &nbsp;
<a href="entries/Taylor_Models.html">Taylor_Models</a> &nbsp;
<a href="entries/Green.html">Green</a> &nbsp;
<a href="entries/Irrationality_J_Hancl.html">Irrationality_J_Hancl</a> &nbsp;
<a href="entries/Budan_Fourier.html">Budan_Fourier</a> &nbsp;
<a href="entries/Smooth_Manifolds.html">Smooth_Manifolds</a> &nbsp;
<a href="entries/Transcendence_Series_Hancl_Rucki.html">Transcendence_Series_Hancl_Rucki</a> &nbsp;
<a href="entries/Hybrid_Systems_VCs.html">Hybrid_Systems_VCs</a> &nbsp;
<a href="entries/Poincare_Bendixson.html">Poincare_Bendixson</a> &nbsp;
<a href="entries/Matrices_for_ODEs.html">Matrices_for_ODEs</a> &nbsp;
<a href="entries/Irrational_Series_Erdos_Straus.html">Irrational_Series_Erdos_Straus</a> &nbsp;
</div>
<h3>Probability theory</h3>
<div class="list">
<a href="entries/DiscretePricing.html">DiscretePricing</a> &nbsp;
<a href="entries/CryptHOL.html">CryptHOL</a> &nbsp;
<a href="entries/Constructive_Cryptography.html">Constructive_Cryptography</a> &nbsp;
<a href="entries/Probabilistic_While.html">Probabilistic_While</a> &nbsp;
<a href="entries/Markov_Models.html">Markov_Models</a> &nbsp;
<a href="entries/Density_Compiler.html">Density_Compiler</a> &nbsp;
<a href="entries/Probabilistic_Timed_Automata.html">Probabilistic_Timed_Automata</a> &nbsp;
<a href="entries/Hidden_Markov_Models.html">Hidden_Markov_Models</a> &nbsp;
<a href="entries/Random_Graph_Subgraph_Threshold.html">Random_Graph_Subgraph_Threshold</a> &nbsp;
<a href="entries/Ergodic_Theory.html">Ergodic_Theory</a> &nbsp;
<a href="entries/Source_Coding_Theorem.html">Source_Coding_Theorem</a> &nbsp;
<a href="entries/Buffons_Needle.html">Buffons_Needle</a> &nbsp;
</div>
<h3>Number theory</h3>
<div class="list">
<a href="entries/Arith_Prog_Rel_Primes.html">Arith_Prog_Rel_Primes</a> &nbsp;
<a href="entries/Pell.html">Pell</a> &nbsp;
<a href="entries/Minkowskis_Theorem.html">Minkowskis_Theorem</a> &nbsp;
<a href="entries/E_Transcendental.html">E_Transcendental</a> &nbsp;
<a href="entries/Pi_Transcendental.html">Pi_Transcendental</a> &nbsp;
<a href="entries/Liouville_Numbers.html">Liouville_Numbers</a> &nbsp;
<a href="entries/Prime_Harmonic_Series.html">Prime_Harmonic_Series</a> &nbsp;
<a href="entries/Fermat3_4.html">Fermat3_4</a> &nbsp;
<a href="entries/Perfect-Number-Thm.html">Perfect-Number-Thm</a> &nbsp;
<a href="entries/SumSquares.html">SumSquares</a> &nbsp;
<a href="entries/Lehmer.html">Lehmer</a> &nbsp;
<a href="entries/Pratt_Certificate.html">Pratt_Certificate</a> &nbsp;
<a href="entries/Dirichlet_Series.html">Dirichlet_Series</a> &nbsp;
<a href="entries/Gauss_Sums.html">Gauss_Sums</a> &nbsp;
<a href="entries/Zeta_Function.html">Zeta_Function</a> &nbsp;
<a href="entries/Stern_Brocot.html">Stern_Brocot</a> &nbsp;
<a href="entries/Bertrands_Postulate.html">Bertrands_Postulate</a> &nbsp;
<a href="entries/Bernoulli.html">Bernoulli</a> &nbsp;
<a href="entries/Diophantine_Eqns_Lin_Hom.html">Diophantine_Eqns_Lin_Hom</a> &nbsp;
<a href="entries/Dirichlet_L.html">Dirichlet_L</a> &nbsp;
<a href="entries/Mersenne_Primes.html">Mersenne_Primes</a> &nbsp;
<a href="entries/Irrationality_J_Hancl.html">Irrationality_J_Hancl</a> &nbsp;
<a href="entries/Prime_Number_Theorem.html">Prime_Number_Theorem</a> &nbsp;
<a href="entries/Probabilistic_Prime_Tests.html">Probabilistic_Prime_Tests</a> &nbsp;
<a href="entries/Prime_Distribution_Elementary.html">Prime_Distribution_Elementary</a> &nbsp;
<a href="entries/Transcendence_Series_Hancl_Rucki.html">Transcendence_Series_Hancl_Rucki</a> &nbsp;
<a href="entries/Zeta_3_Irrational.html">Zeta_3_Irrational</a> &nbsp;
<a href="entries/Furstenberg_Topology.html">Furstenberg_Topology</a> &nbsp;
<a href="entries/Lucas_Theorem.html">Lucas_Theorem</a> &nbsp;
<a href="entries/Gaussian_Integers.html">Gaussian_Integers</a> &nbsp;
<a href="entries/Irrational_Series_Erdos_Straus.html">Irrational_Series_Erdos_Straus</a> &nbsp;
<a href="entries/Amicable_Numbers.html">Amicable_Numbers</a> &nbsp;
</div>
<h3>Games and economics</h3>
<div class="list">
<a href="entries/DiscretePricing.html">DiscretePricing</a> &nbsp;
<a href="entries/ArrowImpossibilityGS.html">ArrowImpossibilityGS</a> &nbsp;
<a href="entries/SenSocialChoice.html">SenSocialChoice</a> &nbsp;
<a href="entries/Vickrey_Clarke_Groves.html">Vickrey_Clarke_Groves</a> &nbsp;
<a href="entries/Parity_Game.html">Parity_Game</a> &nbsp;
<a href="entries/First_Welfare_Theorem.html">First_Welfare_Theorem</a> &nbsp;
<a href="entries/Randomised_Social_Choice.html">Randomised_Social_Choice</a> &nbsp;
<a href="entries/SDS_Impossibility.html">SDS_Impossibility</a> &nbsp;
<a href="entries/Stable_Matching.html">Stable_Matching</a> &nbsp;
<a href="entries/Fishburn_Impossibility.html">Fishburn_Impossibility</a> &nbsp;
<a href="entries/Neumann_Morgenstern_Utility.html">Neumann_Morgenstern_Utility</a> &nbsp;
</div>
<h3>Geometry</h3>
<div class="list">
<a href="entries/Complex_Geometry.html">Complex_Geometry</a> &nbsp;
<a href="entries/Poincare_Disc.html">Poincare_Disc</a> &nbsp;
<a href="entries/Minkowskis_Theorem.html">Minkowskis_Theorem</a> &nbsp;
<a href="entries/Buildings.html">Buildings</a> &nbsp;
<a href="entries/Chord_Segments.html">Chord_Segments</a> &nbsp;
<a href="entries/Triangle.html">Triangle</a> &nbsp;
<a href="entries/Impossible_Geometry.html">Impossible_Geometry</a> &nbsp;
<a href="entries/Tarskis_Geometry.html">Tarskis_Geometry</a> &nbsp;
<a href="entries/General-Triangle.html">General-Triangle</a> &nbsp;
<a href="entries/Nullstellensatz.html">Nullstellensatz</a> &nbsp;
<a href="entries/Ptolemys_Theorem.html">Ptolemys_Theorem</a> &nbsp;
<a href="entries/Buffons_Needle.html">Buffons_Needle</a> &nbsp;
<a href="entries/Stewart_Apollonius.html">Stewart_Apollonius</a> &nbsp;
<a href="entries/Gromov_Hyperbolicity.html">Gromov_Hyperbolicity</a> &nbsp;
<a href="entries/Projective_Geometry.html">Projective_Geometry</a> &nbsp;
<a href="entries/Quaternions.html">Quaternions</a> &nbsp;
<a href="entries/Octonions.html">Octonions</a> &nbsp;
</div>
<h3>Topology</h3>
<div class="list">
<a href="entries/Topology.html">Topology</a> &nbsp;
<a href="entries/Knot_Theory.html">Knot_Theory</a> &nbsp;
<a href="entries/Kuratowski_Closure_Complement.html">Kuratowski_Closure_Complement</a> &nbsp;
<a href="entries/Smooth_Manifolds.html">Smooth_Manifolds</a> &nbsp;
</div>
<h3>Graph theory</h3>
<div class="list">
<a href="entries/Flow_Networks.html">Flow_Networks</a> &nbsp;
<a href="entries/Prpu_Maxflow.html">Prpu_Maxflow</a> &nbsp;
<a href="entries/MFMC_Countable.html">MFMC_Countable</a> &nbsp;
<a href="entries/ShortestPath.html">ShortestPath</a> &nbsp;
<a href="entries/Gabow_SCC.html">Gabow_SCC</a> &nbsp;
<a href="entries/Graph_Theory.html">Graph_Theory</a> &nbsp;
<a href="entries/Planarity_Certificates.html">Planarity_Certificates</a> &nbsp;
<a href="entries/Max-Card-Matching.html">Max-Card-Matching</a> &nbsp;
<a href="entries/Girth_Chromatic.html">Girth_Chromatic</a> &nbsp;
<a href="entries/Random_Graph_Subgraph_Threshold.html">Random_Graph_Subgraph_Threshold</a> &nbsp;
<a href="entries/Flyspeck-Tame.html">Flyspeck-Tame</a> &nbsp;
<a href="entries/Koenigsberg_Friendship.html">Koenigsberg_Friendship</a> &nbsp;
<a href="entries/Tree_Decomposition.html">Tree_Decomposition</a> &nbsp;
<a href="entries/Menger.html">Menger</a> &nbsp;
<a href="entries/Parity_Game.html">Parity_Game</a> &nbsp;
<a href="entries/Factored_Transition_System_Bounding.html">Factored_Transition_System_Bounding</a> &nbsp;
<a href="entries/Graph_Saturation.html">Graph_Saturation</a> &nbsp;
<a href="entries/Relational_Paths.html">Relational_Paths</a> &nbsp;
</div>
<h3>Combinatorics</h3>
<div class="list">
<a href="entries/Card_Equiv_Relations.html">Card_Equiv_Relations</a> &nbsp;
<a href="entries/Twelvefold_Way.html">Twelvefold_Way</a> &nbsp;
<a href="entries/Card_Multisets.html">Card_Multisets</a> &nbsp;
<a href="entries/Card_Partitions.html">Card_Partitions</a> &nbsp;
<a href="entries/Card_Number_Partitions.html">Card_Number_Partitions</a> &nbsp;
<a href="entries/Well_Quasi_Orders.html">Well_Quasi_Orders</a> &nbsp;
<a href="entries/Marriage.html">Marriage</a> &nbsp;
<a href="entries/Bondy.html">Bondy</a> &nbsp;
<a href="entries/Ramsey-Infinite.html">Ramsey-Infinite</a> &nbsp;
<a href="entries/Derangements.html">Derangements</a> &nbsp;
<a href="entries/Euler_Partition.html">Euler_Partition</a> &nbsp;
<a href="entries/Discrete_Summation.html">Discrete_Summation</a> &nbsp;
<a href="entries/Open_Induction.html">Open_Induction</a> &nbsp;
<a href="entries/Latin_Square.html">Latin_Square</a> &nbsp;
<a href="entries/Bell_Numbers_Spivey.html">Bell_Numbers_Spivey</a> &nbsp;
<a href="entries/Catalan_Numbers.html">Catalan_Numbers</a> &nbsp;
<a href="entries/Falling_Factorial_Sum.html">Falling_Factorial_Sum</a> &nbsp;
<a href="entries/Matroids.html">Matroids</a> &nbsp;
<a href="entries/Nash_Williams.html">Nash_Williams</a> &nbsp;
<a href="entries/Ordinal_Partitions.html">Ordinal_Partitions</a> &nbsp;
</div>
<h3>Category theory</h3>
<div class="list">
<a href="entries/Category3.html">Category3</a> &nbsp;
<a href="entries/MonoidalCategory.html">MonoidalCategory</a> &nbsp;
<a href="entries/Category.html">Category</a> &nbsp;
<a href="entries/Category2.html">Category2</a> &nbsp;
<a href="entries/AxiomaticCategoryTheory.html">AxiomaticCategoryTheory</a> &nbsp;
<a href="entries/Bicategory.html">Bicategory</a> &nbsp;
</div>
<h3>Physics</h3>
<div class="list">
<a href="entries/No_FTL_observers.html">No_FTL_observers</a> &nbsp;
<a href="entries/Safe_Distance.html">Safe_Distance</a> &nbsp;
+ <a href="entries/Physical_Quantities.html">Physical_Quantities</a> &nbsp;
</div>
<h3>Misc</h3>
<div class="list">
<a href="entries/FunWithFunctions.html">FunWithFunctions</a> &nbsp;
<a href="entries/FunWithTilings.html">FunWithTilings</a> &nbsp;
<a href="entries/IMO2019.html">IMO2019</a> &nbsp;
</div>
<h2>Tools</h2>
<div class="list">
<a href="entries/Monad_Normalisation.html">Monad_Normalisation</a> &nbsp;
<a href="entries/Constructor_Funs.html">Constructor_Funs</a> &nbsp;
<a href="entries/Lazy_Case.html">Lazy_Case</a> &nbsp;
<a href="entries/Dict_Construction.html">Dict_Construction</a> &nbsp;
<a href="entries/Case_Labeling.html">Case_Labeling</a> &nbsp;
<a href="entries/DPT-SAT-Solver.html">DPT-SAT-Solver</a> &nbsp;
<a href="entries/Nominal2.html">Nominal2</a> &nbsp;
<a href="entries/Separata.html">Separata</a> &nbsp;
<a href="entries/Proof_Strategy_Language.html">Proof_Strategy_Language</a> &nbsp;
<a href="entries/Diophantine_Eqns_Lin_Hom.html">Diophantine_Eqns_Lin_Hom</a> &nbsp;
<a href="entries/BNF_Operations.html">BNF_Operations</a> &nbsp;
<a href="entries/BNF_CC.html">BNF_CC</a> &nbsp;
<a href="entries/Auto2_HOL.html">Auto2_HOL</a> &nbsp;
<a href="entries/Isabelle_C.html">Isabelle_C</a> &nbsp;
<a href="entries/Automated_Stateful_Protocol_Verification.html">Automated_Stateful_Protocol_Verification</a> &nbsp;
</div>
</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>
\ No newline at end of file

File Metadata

Mime Type
application/octet-stream
Expires
Sun, Apr 28, 3:07 AM (1 d, 23 h)
Storage Engine
chunks
Storage Format
Chunks
Storage Handle
MLm3aiKn9z1b
Default Alt Text
(5 MB)

Event Timeline