2

I was trying to do a safe get function for list using subset types. I tryied this definition using program

Program Fixpoint get A (l : list A) (n : {x : nat | x < length l} ) : A :=
  match (n, l) with
  | (O, x :: l') => x
  | (S n', x :: l') => get l' n'
  | _ => _
  end.

The problem is that it get the following error

Found a constructor of inductive type nat while a constructor of sig is expected.

Why does coq don't let me do a pattern matching in pair containing the subset type?

Nico Lehmann
  • 177
  • 6

2 Answers2

5

The problem is that the form for pattern-matching on multiple values is special in Coq. You need to write it like this:

Program Fixpoint get A (l : list A) (n : {x : nat | x < length l} ) : A :=
  match n, l with
  | O, x :: l' => x
  | S n', x :: l' => get _ l' n'
  | _, _ => _
  end.

In your previous version, you were actually pattern-matching on the pair (n, l) instead of pattern-matching on the values n and l simultaneously, and Program was probably getting confused because of that.

Arthur Azevedo De Amorim
  • 23,012
  • 3
  • 33
  • 39
0

You have a sig and you're trying to get a nat. A sig is a nat with a witness of a proof: https://coq.inria.fr/library/Coq.Init.Specif.html. You need to match on proj1_sig n, which will unpack the number. You can really think of the notation {x | P x} as a tuple (it's a dependent sum, to get technical):

Notation "{ x | P }" := (sig (fun x => P)) : type_scope.

So whenever you see { x | P } you think of it as (x,P). The problem is that you're expecting an n where you have different type.

Kristopher Micinski
  • 7,572
  • 3
  • 29
  • 34
  • 2
    I know it is internally a sig. But with program coq let do things like "Program Definition foo (n : {x : nat | x > O}) := match n with O => O | S n' => O end." I don't known what is the formal reason why It doesn't let do the same thing when pattern matching a pair. – Nico Lehmann Apr 12 '15 at 16:13