Chase Node #
The chase is a pretty simple procedure. From an initial fact set, it creates a new fact set by applying a trigger and it continues to do this until all triggers are obsolete.
In this process, we obtain a (potentially infinite) sequence of fact sets.
It can be very useful to also keep track of the associated triggers and this is why we capture both the fact set and used trigger of individual chase steps in a ChaseNode.
To be able to use ChaseNodes also for the core chase, we develop a general interface in form of a typeclass where the "ingoingFacts" describe all facts that initiate the new chase node, while the "outgoingFacts" describe the facts that are available going further. That is, in the core chase, the outgoingFacts are a core of the ingoingFacts. For other chase variants, ingoingFacts and outgoingFacts are the same.
A ChaseNode corresponds to a chase step. It must contain two FactSets of ingoingFacts and outgoingFacts and optionally an RTrigger and a head disjunct index indicating that the current ChaseNode was obtained by applying the specified trigger and picking the indicated head disjunct. It is optional since the initial fact set does not result from a trigger but on all following nodes, this value will be set (and we will prove that it is). For convenience, the chase node also directly includes a proof that the result of its origin is indeed contained in its fact set.
Instances
The origin_result denotes the facts that have been introduced for the chase node. That is, the mapped head index for the trigger stored in the origin field of the ChaseNode.
Equations
- ChaseNode.origin_result node isSome = ((ChaseNode.origin node).get isSome).fst.val.mapped_head[↑((ChaseNode.origin node).get isSome).snd]
Instances For
An auxiliary theorem showing that the origin result equals the i-th mapped head of a trigger if the trigger and i match the origin.
Two ChaseNodes are in a successor relation if the second one could be created from the first one by adding the origin result of the second one to the outgoign facts of the first one. We do not enforce trigger activeness here since we can easily enforce this in the ChaseDerivation later on.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A list of ChaseNode may follow from another ChaseNode if the list corresponds to a trigger output. Here we directly enforce activeness as this would be convoluted to state afterwards.
Equations
- One or more equations did not get rendered due to their size.
Instances For
A property expressing that the outgoingFacts facts of a chase node form a subset of the ingoingFacts. We require this general property in a couple of proofs and it trivially holds true for both the regular chase node and the core chase node.
Equations
- ChaseNode.out_sub_in = ∀ {n : N}, ChaseNode.outgoingFacts obs rules n ⊆ ChaseNode.ingoingFacts obs rules n
Instances For
The RegularChaseNode is the one we use for most chases (except the core chase). Here ingoingFacts and outgoingFacts are always the same.
- facts : FactSet sig
Instances For
The RegularChaseNode is a ChaseNode where ingoingFacts and outgoingFacts are the same.
Equations
- One or more equations did not get rendered due to their size.
The RegularChaseNode has the ChaseNode.out_sub_in property.