Zulip Chat Archive

Stream: general

Topic: Avoiding type-level unfolding in functional definitions


Kat Zhuchko (Apr 06 2025 at 20:49):

I am using the following inductive definition of a vector:

inductive Vect (α : Type) : (n : Nat)  Type where
  | nil : Vect α 0
  | cons : α  Vect α n  Vect α n.succ

I want to define the filter function for vectors in a way that does not require explicit unfolding of type-level definitions.

abbrev count : (α  Bool)  Vect α n  Nat
  | p, .nil => 0
  | p, .cons x xs => (if p x then .succ else id) (count p xs)

def filter : (p : α  Bool)  (xs : Vect α n)  Vect α (count p xs)
  | p, .nil       => .nil
  | p, .cons x xs =>
    match cond : p x with
    | true  => by
      simp only [count, cond]
      exact Vect.cons x (filter p xs)
    | false => by
      simp only [count, cond]
      exact Vect.cons x (filter p xs)

Is there a nice way to do this without having to use simp?

Kyle Miller (Apr 06 2025 at 21:02):

I would do something like this:

inductive Vect (α : Type) : (n : Nat)  Type where
  | nil : Vect α 0
  | cons : α  Vect α n  Vect α n.succ

def Vect.cast (h : n = m) (v : Vect α n) : Vect α m :=
  h  v

def count : (α  Bool)  Vect α n  Nat
  | p, .nil => 0
  | p, .cons x xs => (if p x then .succ else id) (count p xs)

def filter : (p : α  Bool)  (xs : Vect α n)  Vect α (count p xs)
  | p, .nil       => .nil
  | p, .cons x xs =>
    if h : p x then
      (Vect.cons x (filter p xs)).cast (by simp [count, h])
    else
      (filter p xs).cast (by simp [count, h])

I don't think it's possible to avoid unfolding count, since you need to rewrite it depending on whether or not p x is true. The only way to avoid this would be if you had some concrete p that could be evaluated by reduction. But, given that p is an unknown predicate, that can't be done.

Notice that I added a Vector.cast function. This is important, because with your version of filter, you get these rewrites of types of values, which makes working with filter much more complicated. With Vector.cast, the rewrites are safely relegated to proofs.


Last updated: May 02 2025 at 03:31 UTC