Chase Derivation Skeleton #
It is time to define the chase [BV84].
We are going to introduce slightly different representations and the ChaseDerivationSkeleton is arguably the most basic but also most versatile one.
We only demand a PossiblyInfiniteList of ChaseNodes that is non-empty such that the next ChaseNode always results from a trigger application. However, we do not care so far if the trigger is active or even loaded.
We also do not care here whether the derivation is "fair".
Chase Step #
To define how one chase step follows from the previous, we introduce an auxiliary definitions that capture that the next ChaseNode in a ChaseDerivationSkeleton always follows from the previous from a trigger application, given that a next node still exists.
Equations
- One or more equations did not get rendered due to their size.
Instances For
The ChaseDerivation Structure #
The backbone of the ChaseDerivationSkeleton is a PossiblyInfiniteList of ChaseNodes with two conditions.
- We enforce that there is at least an initial
ChaseNode. - At each step in the derivation, either there exists a trigger that yields the next node or there is no next node.
- branch : PossiblyInfiniteList (ChaseNode obs rules)
Instances For
Basic Definitions #
Here we introduce some auxiliary definitions and theorems and we lift some of the machinery of the underlying PossiblyInfiniteList to ChaseDerivationSkeleton.
Membership of ChaseNodes in the ChaseDerivationSkeleton directly corresponds to membership in the PossiblyInfiniteList.
Equations
- ChaseDerivationSkeleton.instMembershipChaseNode = { mem := fun (cd : ChaseDerivationSkeleton obs rules) (node : ChaseNode obs rules) => node ∈ cd.branch }
An element is a member of the derivation iff it occurs at some index in the underlying branch.
Each suffix of the underlying PossiblyInfiniteList is itself a ChaseDerivationSkeleton as long as its head is not none.
Equations
- cd.derivation_for_branch_suffix l2 suffix l2_head_some = { branch := l2, isSome_head := l2_head_some, triggers_exist := ⋯ }
Instances For
The head of the ChaseDerivationSkeleton is the initial ChaseNode. We know that this is never none.
Instances For
The head is a member.
The "next" ChaseNode #
For a ChaseDerivationSkeleton derivation, its next node is the ChaseNode immediately following the head.
We mainly introduce a couple of theorems here that abstract away the triggers_exist condition from the ChaseDerivationSkeleton definition.
Instances For
The next node is a member.
The fact set of the next ChaseNode consists exactly of the facts from head and the result of the trigger that introduces next.
ChaseDerivationSkeleton Suffixes #
We define a suffix relation on ChaseDerivationSkeleton simply as the suffix relation of the underlying PossiblyInfiniteList.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
Unfolds the definition of the suffix relation.
Members of our suffix are also our members.
Each ChaseNode in the ChaseDerivationSkeleton induces a subderivation.
Tail #
If next exists, we can drop the first element from the ChaseDerivationSkeleton and obtain a new ChaseDerivationSkeleton, which, inspired by the PossiblyInfiniteList, we call the tail.
Equations
- cd.tail next_some = cd.derivation_for_branch_suffix cd.branch.tail ⋯ next_some
Instances For
A node is a member if and only if it is either the head or it is a member of the tail.
A derivation is a suffix of another if and only if both are the same or the first is a suffix of the second's tail.
Induction Principle for Members #
Similar to PossiblyInfiniteList.mem_rec, we define an induction principle to show
properties of ChaseNodes in a ChaseDerivationSkeleton.
For this, we introduce ChaseDerivationSkeleton.Node as the subtype of ChaseNode that features a membership proof.
Instances For
A Node of our suffix can be cast into our Node type.
Equations
- ChaseDerivationSkeleton.Node.cast_suffix suffix node = ⟨node.val, ⋯⟩
Instances For
If we want to show a motive for all nodes in a derivation, it is enough to show the motive for the head and for the next node in each abitrary subderivation where the motive already holds for the head. This can be used with the induction tactic.
A node is a member of the tail if and only if there is a subderivation where the node is in the next position. Part of this proof uses the induction principle defined above.
Subset Monotonicity of Facts in ChaseNodes #
Since ChaseNodes always extend the previous facts, the fact sets can only be growing along the ChaseDerivationSkeleton.
Each member's facts contain the head facts. Note that this extends to arbitrary pairs of members since each member always induces a subderivation where it acts as the head.
A first implication of facts_node_subset_every_mem is that, considering one of our subderivations, each of our members either has all of its facts contained in the head of the subderivation or it is itself a member of the subderivation.
Predecessor Relation #
We can define a predecessor relation (≼) on ChaseDerivation.Node.
At this point, it does not have many properties. On Proper ChaseDerivations it will be a total order.
A node $n$ is a predecessor of a node $m$ if there is a subderivation there $n$ is the head and $m$ is an arbitrary member.
Equations
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
The predecessor relation is stable across suffixes. That is, predecessor in our suffix are also predecessor for us. We only need to cast the nodes.
The predecessor relation is reflexive.
The predecessor relation is total.
The facts of our predecessor are a subset of our facts.
We also define a strict version of the predecessor relation (≺) in the obvious way.
A node is a strict predecessor of another if it is a predecessor but not equal.
Instances For
Equations
- One or more equations did not get rendered due to their size.
Instances For
As for the predecessor relation, we can show that the relation is stable across suffixes given that we cast the nodes.
The strict predecessor relation is irreflexive.
The strict predecessor relation is total.
A predecessor is either equal or a strict predecessor.
Chase Result #
Here, we define the result of a ChaseDerivationSkeleton, which is simply the FactSet that is the union of all facts of all ChaseNodes.
Instances For
Every node's facts occur in the result.
The result of our suffix is the same our result.
For each (finite) list of facts in the result, there is a node that that contains all of them.
If a trigger is loaded for the result, then it is loaded for some node in the derivation.