Documentation

Starlib.Data.Classes.Slice

Generic Slice Type Classes #

This file defines type classes for slicing operations on collections, inspired by Python's slice notation. The notation provides three operations:

Each notation also supports manual proof syntax with 'h:

The design follows the pattern of GetElem from the standard library, with:

Type Classes #

The type classes are generic and can be implemented for any collection type. This file provides instances for:

Sliceable type classes #

class SliceLT (coll : Type u) (stop : Type v) (valid : outParam (collstopProp)) (subcoll : outParam ((xs : coll) → (stop : stop) → valid xs stopType w)) :
Type (max (max u v) w)

Type class for "take first n elements" operations: v⟦:m⟧

We allow for the final subcollection type subcoll to depend on all prior parameters: the collection type coll, the stop index type stop, the validity predicate valid.

  • sliceLT (xs : coll) (stop : stop) (h : valid xs stop) : subcoll xs stop h
Instances
    class SliceGE (coll : Type u) (start : Type v) (valid : outParam (collstartProp)) (subcoll : outParam ((xs : coll) → (start : start) → valid xs startType w)) :
    Type (max (max u v) w)

    Type class for "drop first n elements" operations: v⟦m:⟧

    We allow for the final subcollection type subcoll to depend on all prior parameters: the collection type coll, the start index type start, the validity predicate valid.

    • sliceGE (xs : coll) (start : start) (h : valid xs start) : subcoll xs start h
    Instances
      class Slice (coll : Type u) (start : Type v) (stop : Type v') (valid : outParam (collstartstopProp)) (subcoll : outParam ((xs : coll) → (start : start) → (stop : stop) → valid xs start stopType w)) :
      Type (max (max (max u v) v') w)

      Type class for "slice range" operations: v⟦m₁:m₂⟧

      We allow for the final subcollection type subcoll to depend on all prior parameters: the collection type coll, the start index type start, the stop index type stop, the validity predicate valid.

      • slice (xs : coll) (start : start) (stop : stop) (h : valid xs start stop) : subcoll xs start stop h
      Instances

        Slice notation #

        Note: currently we use get_elem_tactic to automatically prove the validity of the indices. We should switch to a more tailored tactic in the future.

        Notation v⟦:stop⟧ for taking the first stop elements (indexed from 0 to stop - 1) of a collection, assuming the validity for stop can be automatically proven

        Instances For

          Notation v⟦:stop⟧'h for taking the first stop elements (indexed from 0 to stop - 1) with explicit proof

          Instances For

            Notation v⟦start:⟧ for dropping the first start elements of a collection, assuming the validity for start can be automatically proven

            Instances For

              Notation v⟦start:⟧'h for dropping the first start elements with explicit proof

              Instances For

                Notation v⟦start:stop⟧ for taking elements from index start to stop - 1 (e.g., v⟦1:3⟧ = v[1] ++ v[2]), with range proofs automatically synthesized

                Instances For

                  Notation v⟦start:stop⟧'h for taking elements from index start to stop - 1 (e.g., v⟦1:3⟧ = ![v 1, v 2]), with explicit proof

                  Instances For

                    Unexpander for slice notation #

                    We provide unexpanders to display slice operations in their slice notation form in goal states and error messages, providing a better user experience.

                    Unexpander for SliceLT.sliceLT to display as v⟦:stop⟧

                    Instances For

                      Unexpander for SliceGE.sliceGE to display as v⟦start:⟧

                      Instances For

                        Unexpander for Slice.slice to display as v⟦start:stop⟧

                        Instances For

                          Instances for Array #

                          Arrays support slice notation with no proof obligations since Array operations handle boundary cases gracefully (e.g., taking more elements than exist returns the whole array).

                          @[implicit_reducible]
                          instance instSliceLTArrayNatTrue {α : Type u} :
                          SliceLT (Array α) Nat (fun (x : Array α) (x_1 : Nat) => True) fun (x : Array α) (x_1 : Nat) (x_2 : True) => Array α
                          @[implicit_reducible]
                          instance instSliceGEArrayNatTrue {α : Type u} :
                          SliceGE (Array α) Nat (fun (x : Array α) (x_1 : Nat) => True) fun (x : Array α) (x_1 : Nat) (x_2 : True) => Array α
                          @[implicit_reducible]
                          instance instSliceArrayNatTrue {α : Type u} :
                          Slice (Array α) Nat Nat (fun (x : Array α) (x_1 x_2 : Nat) => True) fun (x : Array α) (x_1 x_2 : Nat) (x_3 : True) => Array α

                          Instances for List #

                          Lists support slice notation with no proof obligations since List operations handle boundary cases gracefully (e.g., taking more elements than exist returns the whole list).

                          @[implicit_reducible]
                          instance instSliceLTListNatTrue {α : Type u} :
                          SliceLT (List α) Nat (fun (x : List α) (x_1 : Nat) => True) fun (x : List α) (x_1 : Nat) (x_2 : True) => List α
                          @[implicit_reducible]
                          instance instSliceGEListNatTrue {α : Type u} :
                          SliceGE (List α) Nat (fun (x : List α) (x_1 : Nat) => True) fun (x : List α) (x_1 : Nat) (x_2 : True) => List α
                          @[implicit_reducible]
                          instance instSliceListNatTrue {α : Type u} :
                          Slice (List α) Nat Nat (fun (x : List α) (x_1 x_2 : Nat) => True) fun (x : List α) (x_1 x_2 : Nat) (x_3 : True) => List α

                          Examples #