Documentation

Starlib.Data.Fin.Tuple.Defs

Custom Fin tuple operations with better definitional equality #

This file provides custom tuple operations that use pattern matching for better definitional equality, replacing standard library functions that rely on complex constructions like cases, addCases, and conditional statements with casts.

Utility operations: #

Three-Tier Construction System: #

Dependent operations (d*): Work with a unified motive Fin n → Sort* that determines the type at each position. These are the foundational operations.

Homogeneous operations (v*): Specialize the dependent operations to constant-type motives fun _ => α, creating vectors where all elements have the same type.

Functorial operations (f*): Apply a type constructor F uniformly across all positions of a heterogeneous tuple, with the return type constructed using v* operations at the type level. We define versions for both the unary and binary versions of F (arbitrary arity version?)

Heterogeneous operations (h*): Specialize the unary functorial operations to the identity functor, allowing different types at each position without requiring an explicit motive.

Empty tuples: #

def Fin.rtake {n : } {α : Fin nSort u_1} (m : ) (h : m n) (v : (i : Fin n) → α i) (i : Fin m) :
α (Fin.cast (natAdd (n - m) i))

Take the last m elements of a finite vector

Instances For
    def Fin.drop {n : } {α : Fin nSort u_1} (m : ) (h : m n) (v : (i : Fin n) → α i) (i : Fin (n - m)) :
    α (Fin.cast (i.addNat m))

    Drop the first m elements of an n-tuple where m ≤ n, returning an (n - m)-tuple.

    Instances For
      @[reducible, inline]
      abbrev Fin.rdrop {n : } {α : Fin nSort u_1} (m : ) (h : m n) (v : (i : Fin n) → α i) (i : Fin (n - m)) :
      α (Fin.cast (castAdd m i))

      Drop the last m elements of an n-tuple where m ≤ n, returning an (n - m)-tuple.

      This is defined to be taking the first n - m elements of the tuple. Thus, one should not use this and use Fin.take instead.

      Instances For
        def Fin.extract {n : } {α : Fin nSort u_1} (start stop : ) (h1 : start stop) (h2 : stop n) (v : (i : Fin n) → α i) (i : Fin (stop - start)) :
        α i + start,

        Extract a sub-tuple from a Fin-tuple, from index start to stop - 1.

        Instances For
          theorem Fin.extract_start_zero_eq_take {n : } {α : Fin nSort u_1} (stop : ) (h : stop n) (v : (i : Fin n) → α i) :
          extract 0 stop h v = take stop h v

          Extracting with start = 0 is the same as taking the first stop elements.

          theorem Fin.extract_stop_last_eq_drop {n : } {α : Fin nSort u_1} (start : ) (h : start n) (v : (i : Fin n) → α i) :
          extract start n h v = drop start h v

          Extracting with stop = n is the same as dropping the first start elements.

          def Fin.rightpad {m : } {α : Sort u_1} (n : ) (a : α) (v : Fin mα) :
          Fin nα

          Pad a Fin-indexed vector on the right with an element a.

          This becomes truncation if n < m.

          Instances For
            def Fin.leftpad {m : } {α : Sort u_1} (n : ) (a : α) (v : Fin mα) :
            Fin nα

            Pad a Fin-indexed vector on the left with an element a.

            This becomes truncation if n < m.

            Instances For
              def Fin.dcons {n : } {motive : Fin (n + 1)Sort u} (a : motive 0) (b : (i : Fin n) → motive i.succ) (i : Fin (n + 1)) :
              motive i

              Dependent cons with unified motive: prepends a : motive 0 to a dependent tuple (i : Fin n) → motive i.succ using pattern matching for better definitional equality.

              This is meant to replace Fin.cons for dependent tuples with a unified motive.

              Notation: a ::ᵈ b or a ::ᵈ⟨motive⟩ b for explicit motive specification.

              Instances For
                def Fin.dconcat {n : } {motive : Fin (n + 1)Sort u} (u : (i : Fin n) → motive i.castSucc) (a : motive (last n)) (i : Fin (n + 1)) :
                motive i

                Dependent snoc with unified motive: appends a : motive (last n) to the end of a dependent tuple (i : Fin n) → motive i.castSucc using pattern matching for better definitional equality.

                This is meant to replace Fin.snoc for dependent tuples with a unified motive.

                Notation: u :+ᵈ a or u :+ᵈ⟨motive⟩ a for explicit motive specification.

                Instances For
                  def Fin.dappend {m n : } {motive : Fin (m + n)Sort u} (u : (i : Fin m) → motive (castAdd n i)) (v : (i : Fin n) → motive (natAdd m i)) (i : Fin (m + n)) :
                  motive i

                  Dependent append with unified motive: concatenates two dependent tuples under a shared motive using pattern matching for better definitional equality.

                  This is meant to replace Fin.addCases for dependent tuples with a unified motive.

                  Notation: u ++ᵈ v or u ++ᵈ⟨motive⟩ v for explicit motive specification.

                  Instances For
                    @[reducible, inline]
                    abbrev Fin.vempty {α : Sort u_2} :
                    Fin 0α

                    vempty is the empty vector, and a wrapper around Fin.elim0.

                    Notation: !v[] or !v⟨α⟩[] with explicit type ascription.

                    Instances For
                      def Fin.vcons {α : Sort u_1} {n : } (a : α) (v : Fin nα) :
                      Fin (n + 1)α

                      Homogeneous cons: prepends a : α to a vector by specializing dcons to the constant-type motive fun _ => α.

                      Notation: a ::ᵛ v (using standard :: for vectors).

                      Instances For
                        def Fin.vconcat {α : Sort u_1} {n : } (v : Fin nα) (a : α) :
                        Fin (n + 1)α

                        Homogeneous snoc: appends a : α to the end of a vector by specializing dconcat to the constant-type motive fun _ => α.

                        Notation: v :+ᵛ a.

                        Instances For
                          def Fin.vappend {m n : } {α : Sort u_2} (u : Fin mα) (v : Fin nα) :
                          Fin (m + n)α

                          Homogeneous append: concatenates two vectors by specializing dappend to the constant-type motive fun _ => α.

                          Notation: u ++ᵛ v or standard u ++ v.

                          Instances For
                            def Fin.dempty {α : Fin 0Sort u} (i : Fin 0) :
                            α i

                            dempty is the dependent empty tuple.

                            Notation: !d[], !d⟨motive⟩[], or !h[] for heterogeneous usage.

                            Instances For
                              def Fin.fcons {A : Sort u} {F : ASort v} {n : } {α : A} {β : Fin nA} (a : F α) (b : (i : Fin n) → F (β i)) (i : Fin (n + 1)) :
                              F (vcons α β i)

                              Functorial cons: prepends a : F α to a functorial tuple (i : Fin n) → F (β i), with the return type constructed as (i : Fin (n + 1)) → F (vcons α β i) where F is applied to the motive built by vcons at the type level.

                              Unlike dcons which requires an explicit unified motive, fcons uses vcons to automatically construct the motive from the input types and applies functor F uniformly. When F is the identity functor, this reduces to hcons.

                              Notation: a ::ʰ⦃F⦄⟨α; β⟩ b with explicit functor and type ascriptions.

                              Instances For
                                def Fin.fcons₂ {A : Sort u} {B : Sort v} {F : ABSort w} {n : } {α₁ : A} {β₁ : Fin nA} {α₂ : B} {β₂ : Fin nB} (a₁ : F α₁ α₂) (b : (i : Fin n) → F (β₁ i) (β₂ i)) (i : Fin (n + 1)) :
                                F (vcons α₁ β₁ i) (vcons α₂ β₂ i)

                                Functorial cons with two arguments: prepends a : F α₁ α₂ to a functorial tuple (i : Fin n) → F (β₁ i) (β₂ i), with the return type constructed as (i : Fin (n + 1)) → F (vcons α₁ β₁ i) (vcons α₂ β₂ i) where F is applied to the two motives built by vcons at the type level.

                                Notation: a ::ʰ⦃F⦄⟨α₁; β₁⟩⟨α₂; β₂⟩ b with explicit binary functor and type ascriptions.

                                Instances For
                                  def Fin.hcons {n : } {α : Sort u} {β : Fin nSort u} (a : α) (b : (i : Fin n) → β i) (i : Fin (n + 1)) :
                                  vcons α β i

                                  Heterogeneous cons: prepends a : α to a tuple (i : Fin n) → β i, with the return type constructed as (i : Fin (n + 1)) → vcons α β i where vcons builds the motive at the type level.

                                  This is a specialization of fcons to the identity functor, allowing different types at each position without requiring an explicit motive.

                                  Notation: a ::ʰ b.

                                  Instances For
                                    def Fin.fconcat {A : Sort u} {F : ASort v} {n : } {α : Fin nA} {β : A} (u : (i : Fin n) → F (α i)) (a : F β) (i : Fin (n + 1)) :
                                    F (vconcat α β i)

                                    Functorial snoc: appends a : F β to the end of a functorial tuple (i : Fin n) → F (α i), with the return type constructed as (i : Fin (n + 1)) → F (vconcat α β i) where F is applied to the motive built by vconcat at the type level.

                                    Unlike dconcat which requires an explicit unified motive, fconcat uses vconcat to automatically construct the motive from the input types and applies functor F uniformly. When F is the identity functor, this reduces to hconcat.

                                    Notation: u :+ʰ⦃F⦄⟨α; β⟩ a with explicit functor and type ascriptions.

                                    Instances For
                                      def Fin.fconcat₂ {A : Sort u} {B : Sort v} {F : ABSort w} {n : } {α₁ : Fin nA} {β₁ : A} {α₂ : Fin nB} {β₂ : B} (u : (i : Fin n) → F (α₁ i) (α₂ i)) (a : F β₁ β₂) (i : Fin (n + 1)) :
                                      F (vconcat α₁ β₁ i) (vconcat α₂ β₂ i)

                                      Functorial snoc with two arguments: appends a : F β₁ β₂ to the end of a functorial tuple (i : Fin n) → F (α₁ i) (α₂ i), with the return type constructed as (i : Fin (n + 1)) → F (vconcat α₁ β₁ i) (vconcat α₂ β₂ i) where F is applied to the two motives built by vconcat at the type level.

                                      Notation: u :+ʰ⦃F⦄⟨α₁; β₁⟩⟨α₂; β₂⟩ a with explicit binary functor and type ascriptions.

                                      Instances For
                                        def Fin.hconcat {n : } {α : Fin nSort u} {β : Sort u} (u : (i : Fin n) → α i) (a : β) (i : Fin (n + 1)) :
                                        vconcat α β i

                                        Heterogeneous snoc: appends a : β to the end of a tuple (i : Fin n) → α i, with the return type constructed as (i : Fin (n + 1)) → vconcat α β i where vconcat builds the motive at the type level.

                                        This is a specialization of fconcat to the identity functor.

                                        Notation: u :+ʰ a.

                                        Instances For
                                          def Fin.fappend {A : Sort u} {F : ASort v} {m n : } {α : Fin mA} {β : Fin nA} (u : (i : Fin m) → F (α i)) (v : (i : Fin n) → F (β i)) (i : Fin (m + n)) :
                                          F (vappend α β i)

                                          Functorial append: concatenates functorial tuples (i : Fin m) → F (α i) and (i : Fin n) → F (β i), with the return type constructed as (i : Fin (m + n)) → F (vappend α β i) where F is applied to the motive built by vappend at the type level.

                                          Unlike dappend which requires an explicit unified motive, fappend uses vappend to automatically construct the motive from the input types and applies functor F uniformly. When F is the identity functor, this reduces to happend.

                                          Notation: u ++ʰ⦃F⦄⟨α; β⟩ v with explicit functor and type ascriptions.

                                          Instances For
                                            def Fin.fappend₂ {A : Sort u} {B : Sort v} {F : ABSort w} {m n : } {α₁ : Fin mA} {β₁ : Fin nA} {α₂ : Fin mB} {β₂ : Fin nB} (u : (i : Fin m) → F (α₁ i) (α₂ i)) (v : (i : Fin n) → F (β₁ i) (β₂ i)) (i : Fin (m + n)) :
                                            F (vappend α₁ β₁ i) (vappend α₂ β₂ i)

                                            Functorial append with two arguments: concatenates functorial tuples (i : Fin m) → F (α i) and (i : Fin n) → F (β i), with the return type constructed as (i : Fin (m + n)) → F (vappend α₁ β₁ i) (vappend α₂ β₂ i) where F is applied to the two motives built by vappend at the type level.

                                            Notation: u ++ʰ⦃F⦄⟨α₁; β₁⟩⟨α₂; β₂⟩ v with explicit binary functor and type ascriptions.

                                            Instances For
                                              def Fin.happend {m n : } {α : Fin mSort u} {β : Fin nSort u} (u : (i : Fin m) → α i) (v : (i : Fin n) → β i) (i : Fin (m + n)) :
                                              vappend α β i

                                              Heterogeneous append: concatenates tuples (i : Fin m) → α i and (i : Fin n) → β i, with the return type constructed as (i : Fin (m + n)) → vappend α β i where vappend builds the motive at the type level.

                                              This is a specialization of fappend to the identity functor.

                                              Notation: u ++ʰ v.

                                              Instances For
                                                def Fin.dcast {n n' : } {α : Fin nSort u} {α' : Fin n'Sort u} (h : n' = n) ( : ∀ (i : Fin n'), α (Fin.cast h i) = α' i) (v : (i : Fin n) → α i) (i : Fin n') :
                                                α' i

                                                Cast a dependent or heterogeneous vector across an equality n' = n and a family of equalities ∀ i, α (Fin.cast h i) = α' i.

                                                This is meant to replace Fin.cast for our use cases, as this definition offers better definitional equality.

                                                Instances For