TCSLib

37 Boolean Analysis — Canonical D Tree

37.1 Overview

This module builds the canonical decision tree for a restricted DNF \(f|_\rho \), following Razborov’s construction: at each stage one selects the first term not killed by the current restriction \(\rho \), branches on all of that term’s free variables, and recurses. The bulk of the file establishes that this tree correctly computes \(f|_\rho \), is independent of the recursion fuel, and that its depth bounds the decision-tree depth of \(f|_\rho \).

37.2 Declarations

Lemma 37.1 Updating a free variable decreases the free count

If \(v\) is a free variable of a restriction \(\rho \), then fixing \(v\) to a value \(b\) strictly decreases the number of free variables: \(\mathrm{numFree}(\rho [v \mapsto b]) \lt \mathrm{numFree}(\rho )\).

Lemma 37.2 A free variable exists when neither killed nor fixed

For a DNF \(f\) and restriction \(\rho \), if not every term is killed by \(\rho \) and no term is fixed by \(\rho \), then \(\rho \) has at least one free variable \(v \in \rho .\mathrm{freeVars}\).

Definition 37.3 Branch variable selection

Given a DNF \(f\) and restriction \(\rho \), returns an optional variable in \(\mathrm{Fin}\, n\): the variable on which the canonical tree should next branch, drawn from the free variables of the first term not killed by \(\rho \).

When not every term of \(f\) is killed by \(\rho \) and no term is fixed by \(\rho \), the function \(\mathrm{selectBranchVar}\, f\, \rho \) returns some variable \(v\), and that \(v\) is free in \(\rho \).

Definition 37.5 Sub-tree for a term

Builds a complete sub-tree for a term, queried as a list of literals: it branches on each free variable of the term in order, and at every leaf invokes a continuation \(\mathrm{cont} : \mathrm{Restriction}\, n \to \mathrm{DecisionTree}\, n\) with the restriction updated along that root-to-leaf path. Non-free literals are skipped.

Definition 37.6 Canonical decision tree

The canonical decision tree for \(f|_\rho \), following Razborov’s construction. It is defined through a fuel-driven helper \(\mathrm{canonicalDTree.go}\) initialized with fuel \(\rho .\mathrm{numFree} + \text{(positive)}\), repeatedly selecting the first non-killed term and expanding its free variables.

Lemma 37.7 Extending an updated restriction agrees with the original

If \(v\) is free in \(\rho \) and the input \(x\) satisfies \(x(v) = b\), then extending the updated restriction \(\rho [v \mapsto b]\) by \(x\) yields the same total assignment as extending \(\rho \) by \(x\).

Lemma 37.8 termSubTree preserves semantics

Evaluating \(\mathrm{termSubTree}\, \mathit{lits}\, \rho \, \mathrm{cont}\) at \(x\) equals evaluating the continuation at \(x\), applied to the restriction obtained by folding \(x\)’s values into \(\rho \) along the free literals of \(\mathit{lits}\).

Lemma 37.9 termSubTree fold preserves extension

After \(\mathrm{termSubTree}\) assigns all free variables of \(\mathit{lits}\) from \(x\), the resulting restriction extends by \(x\) to the same total assignment as \(\rho \) does: \((\mathrm{fold}\, \mathit{lits}\, \rho ).\mathrm{extend}\, x = \rho .\mathrm{extend}\, x\).

Lemma 37.10 Fold preserves non-none entries

If \(\rho (v) \neq \mathrm{none}\), then after the \(\mathrm{termSubTree}\) fold over \(\mathit{lits}\) the entry at \(v\) remains non-none; that is, the fold never unsets an already-fixed variable.

Lemma 37.11 Fold sets free literal variables

If a literal \(l \in \mathit{lits}\) has variable free in \(\rho \), then after the \(\mathrm{termSubTree}\) fold the entry at \(l.\mathrm{var}\) is no longer none (it has been set to some value).

Lemma 37.12 Fold strictly decreases the free count

When at least one literal of \(\mathit{lits}\) has a variable free in \(\rho \), the \(\mathrm{termSubTree}\) fold strictly decreases \(\mathrm{numFree}\).

Provided the fuel exceeds \(\rho .\mathrm{numFree}\), the tree \(\mathrm{canonicalDTree.go}\, f\, \mathit{fuel}\, \rho \) computes the restricted function: for all \(x\), its evaluation equals \(\mathrm{restrictFn}\, (f.\mathrm{eval})\, \rho \, x\).

Lemma 37.14 Correctness of the canonical decision tree

For every \(x\), the canonical decision tree evaluates correctly: \((\mathrm{canonicalDTree}\, f\, \rho ).\mathrm{eval}\, x = \mathrm{restrictFn}\, (f.\mathrm{eval})\, \rho \, x\).

Lemma 37.15 Updating cannot increase the free count

Fixing a variable \(v\) to a value \(b\) never increases the number of free variables: \(\mathrm{numFree}(\rho [v \mapsto b]) \le \mathrm{numFree}(\rho )\).

Lemma 37.16 termSubTree is extensional in its continuation

If two continuations \(\mathrm{cont}_1, \mathrm{cont}_2\) agree on all restrictions \(\rho '\) with \(\rho '.\mathrm{numFree} \le \rho .\mathrm{numFree}\), then \(\mathrm{termSubTree}\, \mathit{lits}\, \rho \, \mathrm{cont}_1 = \mathrm{termSubTree}\, \mathit{lits}\, \rho \, \mathrm{cont}_2\).

If \(\mathit{lits}\) contains at least one literal free in \(\rho \), then the two continuations need only agree on restrictions \(\rho '\) with \(\rho '.\mathrm{numFree} \lt \rho .\mathrm{numFree}\) for the two \(\mathrm{termSubTree}\) trees to be equal.

Once the fuel exceeds \(\rho .\mathrm{numFree}\), the resulting tree does not depend on the exact fuel: for any \(\mathit{fuel}_1, \mathit{fuel}_2 \gt \rho .\mathrm{numFree}\), \(\mathrm{canonicalDTree.go}\, f\, \mathit{fuel}_1\, \rho = \mathrm{canonicalDTree.go}\, f\, \mathit{fuel}_2\, \rho \).

For \(t \in f\) and a restriction \(\rho '\) with \(\rho _{\mathrm{orig}}.\mathrm{numFree} \ge \rho '.\mathrm{numFree} + 1\), the standard continuation \(\bigl(\text{if } t \text{ fixed by } \rho ' \text{ then } \mathrm{leaf}\ \mathrm{true}\ \text{else}\ \mathrm{canonicalDTree.go}\, f\, \rho _{\mathrm{orig}}.\mathrm{numFree}\, \rho '\bigr)\) equals \(\mathrm{canonicalDTree}\, f\, \rho '\).

Lemma 37.20 Unfolding termSubTree at a free head

When the head literal \(l\) is free in \(\rho \), \(\mathrm{termSubTree}\, (l :: \mathit{rest})\, \rho \, \mathrm{cont}\) is a branch on \(l.\mathrm{var}\) whose two children are the recursive \(\mathrm{termSubTree}\) calls on \(\mathit{rest}\) with \(\rho \) updated to \(\mathrm{some}\ \mathrm{false}\) and \(\mathrm{some}\ \mathrm{true}\).

Lemma 37.21 Unfolding termSubTree at a non-free head

When the head literal \(l\) is not free in \(\rho \), it is skipped: \(\mathrm{termSubTree}\, (l :: \mathit{rest})\, \rho \, \mathrm{cont} = \mathrm{termSubTree}\, \mathit{rest}\, \rho \, \mathrm{cont}\).

When the head literal \(l\) is free in \(\rho \), the deepest root-to-leaf path of \(\mathrm{termSubTree}\, (l :: \mathit{rest})\, \rho \, \mathrm{cont}\) begins with \((l.\mathrm{var}, b)\) for some \(b\) (the direction of the deeper child), followed by the deep path of the recursive call on \(\rho [l.\mathrm{var} \mapsto b]\).

Lemma 37.23 Freeness is unchanged by an unrelated update

If every literal of \(\mathit{rest}\) has variable distinct from \(v\), then filtering \(\mathit{rest}\) by freeness under \(\rho [v \mapsto b]\) gives the same list as filtering by freeness under \(\rho \).

For \(\mathit{lits}\) with pairwise distinct variables, the \(k\)-th variable of the deep path of \(\mathrm{termSubTree}\, \mathit{lits}\, \rho \, \mathrm{cont}\) equals the variable of the \(k\)-th literal in the free-filtered list of \(\mathit{lits}\).

For \(\mathit{lits}\) with pairwise distinct variables there is a restriction \(\rho '\), agreeing with \(\rho \) off the variables of \(\mathit{lits}\), such that the deep-path length of \(\mathrm{termSubTree}\, \mathit{lits}\, \rho \, \mathrm{cont}\) equals the number of free literals of \(\mathit{lits}\) plus the deep-path length of \(\mathrm{cont}\, \rho '\).

For \(\mathit{lits}\) with pairwise distinct variables, the deep path of \(\mathrm{termSubTree}\, \mathit{lits}\, \rho \, \mathrm{cont}\) splits as a prefix (one entry per free literal of \(\mathit{lits}\)) appended with the deep path of \(\mathrm{cont}\, \rho '\), where \(\rho '\) agrees with \(\rho \) off the variables of \(\mathit{lits}\).

When not all terms are killed and none is fixed, and \(t\) is the first non-killed clause, \(\mathrm{canonicalDTree.go}\, f\, (\mathit{fuel}+1)\, \rho \) unfolds to \(\mathrm{termSubTree}\, t\, \rho \, \mathrm{cont}\), where \(\mathrm{cont}\, \rho '\) is \(\mathrm{leaf}\ \mathrm{true}\) if \(t\) is fixed by \(\rho '\) and otherwise \(\mathrm{canonicalDTree.go}\, f\, \mathit{fuel}\, \rho '\).

The top-level analogue of the previous lemma for \(\mathrm{canonicalDTree}\) itself: under the alive-branch hypotheses with first non-killed clause \(t\), \(\mathrm{canonicalDTree}\, f\, \rho \) equals \(\mathrm{termSubTree}\, t\, \rho \, \mathrm{cont}\) with the same fixed-or-recurse continuation running at fuel \(\rho .\mathrm{numFree}\).

Lemma 37.29 Skipping a non-free prefix in termSubTree

If every literal in \(\mathit{prefix}\) has variable not free in \(\rho \), then \(\mathrm{termSubTree}\, (\mathit{prefix} \mathbin {+\! \! +} \mathit{rest})\, \rho \, \mathrm{cont} = \mathrm{termSubTree}\, \mathit{rest}\, \rho \, \mathrm{cont}\).

Lemma 37.30 Skipping an updated head literal

If \(l.\mathrm{var} = v\), then \(\mathrm{termSubTree}\, (l :: \mathit{rest})\, (\rho [v \mapsto b])\, \mathrm{cont} = \mathrm{termSubTree}\, \mathit{rest}\, (\rho [v \mapsto b])\, \mathrm{cont}\), since after the update \(v\) is no longer free and \(l\) is skipped.

Lemma 37.31 Tree depth bounds decision-tree depth

If a decision tree \(T\) computes a function \(f\) (i.e. \(T.\mathrm{eval}\, x = f(x)\) for all \(x\)), then its depth is at least the decision-tree depth of \(f\): \(T.\mathrm{depth} \ge \mathrm{dtDepth}\, f\).

The depth of the canonical decision tree for \(f|_\rho \) is at least the decision-tree depth of the restricted function: \((\mathrm{canonicalDTree}\, f\, \rho ).\mathrm{depth} \ge \mathrm{dtDepth}\, (\mathrm{restrictFn}\, (f.\mathrm{eval})\, \rho )\).

For any function \(f\) and restriction \(\rho \), the decision-tree depth of the restricted function is at most the number of free variables: \(\mathrm{dtDepth}\, (\mathrm{restrictFn}\, f\, \rho ) \le \rho .\mathrm{numFree}\).