@cite{kuhlmann-nivre-2006} @cite{kuhlmann-2013} Projection theory for dependency trees: BFS-based projection computation, interval/gap/block analysis, Prop-level Dominance (reflexive-transitive closure), and the bridge theorems connecting BFS membership to dominance.
Also contains the isProjective / isWellFormed predicates, which
depend on projection infrastructure.
References: @cite{kuhlmann-nivre-2006}, @cite{kuhlmann-2013}.
Parent edge predicate: there is a head→dep dependency (v → w) in deps.
The atomic relation whose reflexive-transitive closure is Dominates
(defined below). Sites that need to express "v is a head with dep w"
should use this rather than re-spelling the existential.
Equations
- DepGrammar.parentEdge deps v w = ∃ d ∈ deps, d.headIdx = v ∧ d.depIdx = w
Instances For
Projection π(i): the yield of node i — all nodes it transitively dominates, including itself — sorted in ascending order.
The projection is the central primitive of @cite{kuhlmann-nivre-2006} and @cite{kuhlmann-2013}. Projectivity, gap degree, block-degree, edge degree, and well-nestedness are all defined in terms of projections.
A dependency graph is projective iff every projection is an interval (@cite{kuhlmann-nivre-2006}, Definition 3).
Equations
- DepGrammar.projection deps root = (DepGrammar.projection.go deps [root] [] (deps.length * (deps.length + 1) + 2)).mergeSort fun (x1 x2 : ℕ) => decide (x1 ≤ x2)
Instances For
Equations
- One or more equations did not get rendered due to their size.
- DepGrammar.projection.go deps queue visited 0 = visited
- DepGrammar.projection.go deps [] visited fuel = visited
Instances For
Whether a sorted list of positions forms an interval [min.max] with no internal gaps. A projection is an interval iff its node has gap degree 0.
Equations
- DepGrammar.isInterval [] = true
- DepGrammar.isInterval [head] = true
- DepGrammar.isInterval sorted = (sorted.getLast! - sorted.head! + 1 == sorted.length)
Instances For
The gaps in a sorted projection: pairs (jₖ, jₖ₊₁) adjacent in the projection where jₖ₊₁ − jₖ > 1. (@cite{kuhlmann-nivre-2006}, Definition 6; @cite{kuhlmann-2013}, §7.1)
Equations
- DepGrammar.gaps sorted = List.filter (fun (x : ℕ × ℕ) => match x with | (a, b) => decide (b - a > 1)) (sorted.zip (List.drop 1 sorted))
Instances For
The blocks of a sorted projection: maximal contiguous segments.
Example: projection [1, 2, 5, 6, 7] → blocks [[1, 2], [5, 6, 7]]
The number of blocks equals gap degree + 1 and corresponds to the fan-out of the LCFRS rule extracted for that node.
Equations
- One or more equations did not get rendered due to their size.
- DepGrammar.blocks [] = []
- DepGrammar.blocks [a] = [[a]]
Instances For
Gap degree of a node: number of gaps in its projection. (@cite{kuhlmann-nivre-2006}, Definition 6)
Equations
- DepGrammar.gapDegreeAt deps root = (DepGrammar.gaps (DepGrammar.projection deps root)).length
Instances For
Gap degree of a tree: max gap degree over all nodes. (@cite{kuhlmann-nivre-2006}, Definition 7) Gap degree 0 ⟺ projective.
Equations
- t.gapDegree = List.foldl max 0 (List.map (DepGrammar.gapDegreeAt t.deps) (List.range t.words.length))
Instances For
Block-degree of a node: number of blocks in its projection. Block-degree = gap degree + 1 = fan-out of extracted LCFRS rule.
Equations
- DepGrammar.blockDegreeAt deps root = (DepGrammar.blocks (DepGrammar.projection deps root)).length
Instances For
Block-degree of a tree: max block-degree over all nodes. Block-degree 1 ⟺ projective. Bounded block-degree + well-nestedness ⟺ polynomial parsing (@cite{kuhlmann-2013}, Lemma 10).
Equations
- t.blockDegree = List.foldl max 0 (List.map (DepGrammar.blockDegreeAt t.deps) (List.range t.words.length))
Instances For
The output of projection is strictly increasing (sorted, no duplicates).
Proof: BFS visits each node at most once (visited check), then
mergeSort produces a sorted list. Since visited prevents duplicates,
the sorted list is strictly increasing.
root is always in its own projection.
The output of projection is non-empty (root is always included).
Projection of a node with no outgoing edges is just [root].
Key step: BFS from root finds no children, so only root is visited.
Used by leaf_no_subtree_members in HarmonicOrder.lean.
The output of projection is a list with no duplicates.
Follows from BFS visiting each node at most once (go_nodup), composed
with the fact that mergeSort preserves the multiset (hence Nodup).
If (v, w) is a dependency edge, then w ∈ projection deps v. Proof: BFS from v processes v first (adding children to queue), w is a child of v (by the edge), so w enters the queue and is processed.
A strictly increasing list of Nats with all elements in (lo, hi)
has length ≤ hi - lo - 1. Proof: the head ≥ lo + 1, the last ≤ hi - 1,
and chain_getLast_ge gives last ≥ head + (length - 1), so
lo + 1 + (length - 1) ≤ hi - 1, giving length ≤ hi - lo - 1.
For IsChain (· < ·) lists, isInterval = true ↔ gaps = [].
For non-empty strictly increasing lists, #blocks = #gaps + 1.
For a strictly increasing interval list, every integer in [head!, getLast!] is a member. Proof by induction: isInterval + chain forces consecutive elements (b = a + 1), so each integer in the range appears.
If a strictly increasing interval list contains a and c with
a < b < c, then it contains b.
Prop-level dominance: Dominates deps v x iff v transitively dominates x
via dependency edges (head → dep). Defined as the reflexive-transitive
closure of parentEdge.
Equations
- DepGrammar.Dominates deps v x = Relation.ReflTransGen (DepGrammar.parentEdge deps) v x
Instances For
Unfolding bridge to mathlib's Relation.ReflTransGen for ad-hoc access to
its lemma corpus (lift, mono, closed, etc.) without manual unfold.
Reflexive case: v dominates itself.
Head-style step: edge (v → w) plus dominance from w gives dominance from v.
Dominance is transitive.
If there is a direct edge (v, w), then v dominates w.
Head-style induction principle for Dominates: prove a property of
Dominates deps v x (target x fixed) by handling the reflexive case
motive x Dominates.refl and the head-step case
parentEdge v w → Dominates w x → motive w → motive v.
Case binders are named refl and step to mirror the prior inductive's
constructor names. The v and w arguments of step are implicit
(use | @step v w hedge h_tail ih to bind, or obtain ⟨..⟩ := hedge).
Backward bridge: BFS membership implies dominance.
Projection is closed under children: if w ∈ projection deps r and
(w, c) is a dependency edge, then c ∈ projection deps r.
Forward bridge: dominance implies BFS membership.
Bridge theorem: BFS projection membership ↔ Prop-level dominance.
foldl max init ls ≥ init.
foldl max init ls ≥ x for any x ∈ ls.
List.foldl max 0 ls = 0 iff every element of ls is 0.
If some element of ls is positive, then List.foldl max 0 ls > 0.
foldl max init ls ≤ bound when init ≤ bound and all elements ≤ bound.
foldl max 0 ls = k when all elements are k and the list is non-empty.
Check projectivity: every node's projection is an interval. (@cite{kuhlmann-nivre-2006}, Definition 3)
Equivalent to: no two dependency arcs cross. Equivalent to: gap degree = 0. Equivalent to: block-degree = 1.
Equations
- DepGrammar.isProjective t = (List.range t.words.length).all fun (i : ℕ) => DepGrammar.isInterval (DepGrammar.projection t.deps i)
Instances For
A dependency tree is well-formed if it satisfies all constraints.
Equations
- One or more equations did not get rendered due to their size.