Documentation

DescriptiveComplexity.OrderWalk

Walking a finite linear order, first-order #

Shared machinery for constructions that traverse a finite linear order – or the lexicographic order on tuples – one step at a time, with each step described by a first-order guard over the ordered expansion L.sum Language.order.

Two clients, one technique. The SO-Horn definition of HORN-SAT (DescriptiveComplexity.Problems.HornSat.Definability) assembles the unbounded body of an input clause by walking the order of its elements; the translation of FO(LFP) into SO-Horn (DescriptiveComplexity.FixedPointHorn) walks the lexicographic order of stage and valuation tuples to derive the complement of a fixed point. Both need the same three ingredients, provided here:

Finally DescriptiveComplexity.orank – the rank of an element of a finite linear order, the number of its strict predecessors – converts that walk into arithmetic: rank 0 at the bottom (DescriptiveComplexity.orank_eq_zero), +1 along a cover (DescriptiveComplexity.orank_covBy), Nat.card - 1 at the top (DescriptiveComplexity.orank_isTop). This is how a fixed-point stage indexed by a tuple is matched with the ℕ-indexed stages of DescriptiveComplexity.derivesIn.

Order guards #

x ≤ y, as a formula over the ordered expansion.

Equations
Instances For
    Dependency graph

    x < y, as a formula over the ordered expansion.

    Equations
    Instances For
      Dependency graph

      The variable x holds a minimum.

      Equations
      Instances For
        Dependency graph

        The variable x holds a maximum.

        Equations
        Instances For
          Dependency graph

          w holds the immediate predecessor of z.

          Equations
          • One or more equations did not get rendered due to their size.
          Instances For
            Dependency graph
            @[simp]
            theorem DescriptiveComplexity.realize_leF {L : FirstOrder.Language} {α A : Type} [L.Structure A] [LinearOrder A] {v : α → A} (x y : α) :
            (leF x y).Realize v ↔ v x ≤ v y
            Dependency graph
            @[simp]
            theorem DescriptiveComplexity.realize_ltF {L : FirstOrder.Language} {α A : Type} [L.Structure A] [LinearOrder A] {v : α → A} (x y : α) :
            (ltF x y).Realize v ↔ v x < v y
            Dependency graph
            @[simp]
            theorem DescriptiveComplexity.realize_minF {L : FirstOrder.Language} {α A : Type} [L.Structure A] [LinearOrder A] {v : α → A} (x : α) :
            (minF x).Realize v ↔ ∀ (a : A), v x ≤ a
            Dependency graph
            @[simp]
            theorem DescriptiveComplexity.realize_maxF {L : FirstOrder.Language} {α A : Type} [L.Structure A] [LinearOrder A] {v : α → A} (x : α) :
            (maxF x).Realize v ↔ ∀ (a : A), a ≤ v x
            Dependency graph
            @[simp]
            theorem DescriptiveComplexity.realize_succF {L : FirstOrder.Language} {α A : Type} [L.Structure A] [LinearOrder A] {v : α → A} (w z : α) :
            (succF w z).Realize v ↔ v w < v z ∧ ∀ (a : A), ¬(v w < a ∧ a < v z)
            Dependency graph

            Immediate predecessors, and induction along a finite linear order #

            theorem DescriptiveComplexity.order_induction {A : Type} [LinearOrder A] [Finite A] {P : A → Prop} (hmin : ∀ (z : A), (∀ (a : A), z ≤ a) → P z) (hstep : ∀ (w z : A), w < z → (∀ (a : A), ¬(w < a ∧ a < z)) → P w → P z) (z : A) :
            P z

            Induction along a finite linear order: from the minimum, one immediate successor at a time.

            Dependency graph
            theorem DescriptiveComplexity.order_induction_down {A : Type} [LinearOrder A] [Finite A] {P : A → Prop} (hmax : ∀ (z : A), (∀ (a : A), a ≤ z) → P z) (hstep : ∀ (w z : A), w < z → (∀ (a : A), ¬(w < a ∧ a < z)) → P z → P w) (z : A) :
            P z

            Induction along a finite linear order, downwards: from the maximum, one immediate predecessor at a time. This is the direction a scan is proved correct in – a walk that stops at the greatest element knows about the elements above the one it stands on.

            Dependency graph

            The lexicographic successor of a tuple, coordinatewise #

            def DescriptiveComplexity.TupSucc {D : ℕ} {A : Type} [LinearOrder A] (t t' : Fin D → A) :

            The tuple t' is the immediate successor of t in the lexicographic order (most significant coordinate first), stated coordinatewise: the two tuples agree before some position p, at p the second covers the first, and after p the first is all maxima and the second all minima. This is the condition the guard DescriptiveComplexity.succTupF realizes; DescriptiveComplexity.tupSucc_iff_covBy identifies it with covering in Lex (Fin D → A).

            Equations
            • One or more equations did not get rendered due to their size.
            Instances For
              Dependency graph

              Tuple guards, for the lexicographic order #

              noncomputable def DescriptiveComplexity.minTupF {D : ℕ} {L : FirstOrder.Language} {γ : Type} (sel : Fin D → γ) :

              The variables sel hold a lexicographically minimal tuple: every coordinate is minimal.

              Equations
              Instances For
                Dependency graph
                noncomputable def DescriptiveComplexity.maxTupF {D : ℕ} {L : FirstOrder.Language} {γ : Type} (sel : Fin D → γ) :

                The variables sel hold a lexicographically maximal tuple.

                Equations
                Instances For
                  Dependency graph
                  noncomputable def DescriptiveComplexity.succTupF {D : ℕ} {L : FirstOrder.Language} {γ : Type} (sel sel' : Fin D → γ) :

                  The tuple held by sel' is the immediate lexicographic successor of the one held by sel.

                  Equations
                  • One or more equations did not get rendered due to their size.
                  Instances For
                    Dependency graph
                    @[simp]
                    theorem DescriptiveComplexity.realize_minTupF {D : ℕ} {L : FirstOrder.Language} {γ A : Type} [L.Structure A] [LinearOrder A] {v : γ → A} (sel : Fin D → γ) :
                    (minTupF sel).Realize v ↔ ∀ (p : Fin D) (a : A), v (sel p) ≤ a
                    Dependency graph
                    @[simp]
                    theorem DescriptiveComplexity.realize_maxTupF {D : ℕ} {L : FirstOrder.Language} {γ A : Type} [L.Structure A] [LinearOrder A] {v : γ → A} (sel : Fin D → γ) :
                    (maxTupF sel).Realize v ↔ ∀ (p : Fin D) (a : A), a ≤ v (sel p)
                    Dependency graph

                    The bridge to Lex: bottom, top and covering, coordinatewise #

                    The tuple guards above speak coordinatewise; the walk they describe is along the finite linear order Lex (Fin D → A). These lemmas identify the two languages. (Lex is a type synonym, so Finite and Nonempty instances are provided for it here.)

                    Dependency graph
                    Dependency graph
                    theorem DescriptiveComplexity.tupSucc_iff_covBy {D : ℕ} {A : Type} [LinearOrder A] {t t' : Fin D → A} :

                    Coordinatewise successors are lexicographic covers: the condition of the guard DescriptiveComplexity.succTupF says exactly that the second tuple covers the first in Lex (Fin D → A).

                    Dependency graph

                    The lexicographic product with a static head #

                    theorem DescriptiveComplexity.prodLex_le_iff {J B : Type} [LinearOrder J] [LinearOrder B] {a a' : J} {b b' : B} :
                    toLex (a, b) ≤ toLex (a', b') ↔ a < a' ∨ a = a' ∧ b ≤ b'
                    Dependency graph
                    theorem DescriptiveComplexity.prodLex_covBy_iff {J B : Type} [LinearOrder J] [LinearOrder B] [Nonempty B] {a a' : J} {b b' : B} :
                    toLex (a, b) ⋖ toLex (a', b') ↔ a = a' ∧ b ⋖ b' ∨ a ⋖ a' ∧ (∀ (y : B), y ≤ b) ∧ ∀ (y : B), b' ≤ y

                    Covering in a lexicographic product: either the heads agree and the tails cover, or the heads cover, the first tail is a top and the second a bottom.

                    Dependency graph
                    theorem DescriptiveComplexity.finCovBy_iff {n : ℕ} {j j' : Fin n} :
                    j ⋖ j' ↔ ↑j + 1 = ↑j'

                    Covering in Fin n is incrementing the value.

                    Dependency graph

                    Deciding the lexicographic order of two tuples #

                    DescriptiveComplexity.succTupF walks the lexicographic order; the two guards below decide it, which is what a reduction defining the order of its image has to do. They are stated at arbitrary selectors sel, sel' into a shared variable type, rather than at the fixed layout Fin 2 × Fin D of DescriptiveComplexity.lexTupleLeF, because their consumers compare tuples sitting at arbitrary positions among the free variables.

                    noncomputable def DescriptiveComplexity.lexSelLtF {D : ℕ} {L : FirstOrder.Language} {γ : Type} (sel sel' : Fin D → γ) :

                    The tuple held by sel is lexicographically strictly below the one held by sel': the two agree before some coordinate, at which the first is strictly smaller.

                    Equations
                    • One or more equations did not get rendered due to their size.
                    Instances For
                      Dependency graph
                      noncomputable def DescriptiveComplexity.lexSelLeF {D : ℕ} {L : FirstOrder.Language} {γ : Type} (sel sel' : Fin D → γ) :

                      The tuple held by sel is lexicographically below or equal to the one held by sel'.

                      Equations
                      • One or more equations did not get rendered due to their size.
                      Instances For
                        Dependency graph
                        @[simp]
                        theorem DescriptiveComplexity.realize_lexSelLtF {D : ℕ} {L : FirstOrder.Language} {γ A : Type} [L.Structure A] [LinearOrder A] {v : γ → A} (sel sel' : Fin D → γ) :
                        (lexSelLtF sel sel').Realize v ↔ toLex (v ∘ sel) < toLex (v ∘ sel')
                        Dependency graph
                        @[simp]
                        theorem DescriptiveComplexity.realize_lexSelLeF {D : ℕ} {L : FirstOrder.Language} {γ A : Type} [L.Structure A] [LinearOrder A] {v : γ → A} (sel sel' : Fin D → γ) :
                        (lexSelLeF sel sel').Realize v ↔ toLex (v ∘ sel) ≤ toLex (v ∘ sel')
                        Dependency graph

                        Reaching an element from below a cover #

                        The rank of an element of a finite linear order #

                        noncomputable def DescriptiveComplexity.orank {A : Type} [LinearOrder A] (z : A) :

                        The rank of an element of a finite linear order: the number of its strict predecessors. This converts a walk along covers into arithmetic, matching tuple-indexed fixed-point stages with the ℕ-indexed DescriptiveComplexity.derivesIn.

                        Equations
                        Instances For
                          Dependency graph
                          theorem DescriptiveComplexity.orank_eq_zero {A : Type} [LinearOrder A] {z : A} (hz : ∀ (a : A), z ≤ a) :
                          orank z = 0

                          A minimum has rank 0.

                          Dependency graph
                          theorem DescriptiveComplexity.orank_covBy {A : Type} [LinearOrder A] [Finite A] {w z : A} (h : w ⋖ z) :
                          orank z = orank w + 1

                          Rank increases by one along a cover.

                          Dependency graph
                          theorem DescriptiveComplexity.orank_isTop {A : Type} [LinearOrder A] [Finite A] {z : A} (hz : ∀ (a : A), a ≤ z) :

                          A maximum has rank Nat.card A - 1.

                          Dependency graph