pattern matching coverage checking with dependent types using set approximations
Definition of functions by pattern matching has proved to be a key feature of functional programming languages. These definitions allow a clear, easy to read, concise expression of functions. Proof assistants - like the the Coq proof assistant - and some programming languages - like the Epigram or Agda systems - introduce types that can depend on values. These dependent types allow to refine the definition of a type by the use of values. This results in a more precise specification of data types and functions. For example, it is possible, in such a system, to define the type of the lists of a given length n . The user can then express the fact that the head function - computing the first element of a list - can only be applied to non empty lists. This refinement reduces the number of run times error and allows to integrate program design and program verification.In presence of dependent types, some cases in a definition by pattern matching can become useless. For example, the case of the empty list is useless in the definition of the function head: the type of this function is specified to prevent the user to apply it to an empty list. For the sake of clarity and expressivity, we do not want the user to have to handle these useless cases. Especially, if the user is using dependent types for programming, handling such useless cases breaks, by introducing pieces of proof, the natural flow of the program. But forgetting a useful case can break the consistency of the system. This creates the need for a method to safely detect and remove useless cases in a definition by pattern matching.Alas, this problem - even restricted to algebraic data types - is undecidable in presence of dependent types. We introduce a new method to detect useless cases based on the computation of over-approximations of the inhabitants of inductive data types and contexts. Not only, this method is proved correct but can also produce - in a systematic way - a complete matching in Coq, ensuring that the logical power of the sysem remains unchanged. Moreover, it is modular over the kind of approximated sets used. We give two example implementations of such approximated sets: one is based on truncated terms, the other one on relations linking the number of occurrences of each constructor.
pattern matching coverage checking set approximation