Injectivity

Table of Contents

Introduction

If F is injective and the type checker knows that F i = F j it could conclude i = j to solve further constraints.
For examples if F is a name of an inductive family or a constructor, it is injective. If F is defined then it is not injective in general, but in some important cases it is. For instance, define Vectors by recursion.

Vec is an injective function, which can be shown by induction on Nat. I guess in this case injectivity could be statically checked. It would be nice to be able to specify that a function is injective (via a pragma), and this way get more support from the type checker.

Potential problems

Consider the following set of equations:

Vec A ?0 = Vec A ?1
?1 = succ zero

Given the injectivity trick, we could solve these equations by first instantiating ?0 := ?1 and then ?1 := succ zero. Now, suppose we tried to solve the equations is the reverse order. We'd end up with the constraint Vec A ?0 = Prod A Empty which we can't solve with just the injectivity trick. There are two options:

Never solve the constraints. For instance, by requiring that one side is neutral when applying injectivity.

Always solve the constraints. This would be a bit trickier. Faced with the constraint Vec A ?0 = Prod A Empty we would have to figure out that this could only happen in the succ case and instantiate ?0 := succ ?2.

Bigger Example

Here is a bigger example, comparing two implementations of a type, one by induction, one by recursion.