0

Let's define a type representing sets:

Inductive mySet :=
| funSet   : mySet -> mySet -> mySet
| prod     : mySet -> mySet -> mySet.

We have two type constructors:

  • funSet A B - a set of functions from A to B
  • prod A B - a set of pairs A B.

I would like to define type representing elements of these sets in the following way

Inductive el (X : mySet) :=
  | eval  : forall {Y : mySet}, el (funSet Y X) -> el Y -> el X
  | proj1 : forall {Y : mySet}, el (prod X Y) -> el X
  | proj2 : forall {Y : mySet}, el (prod Y X) -> el X
  | compose : forall {A B C : mySet}, el (funSet A B) -> el (funSet B C) -> el (funSet A C).

Where we have a constructor eval which can evaluate a function, an element of funSet X Y or other constructors proj1 and proj2 which extract corresponding element of a pair.

However, the definition of compose is not valid as it is. I get an error:

Error: Last occurrence of "el" must have "X" as 1st argument in 
 "forall A B C : mySet, el (funSet A B) -> el (funSet B C) -> el (funSet A C)".

Ok, that is understandable, but is there a way to enable the constructor compose when X matches the pattern funSet A C ?

I really want to have compose as a constructor. Later on, I want to do pattern matching on expression composed of eval proj1 proj2 compose.

tom
  • 1,520
  • 1
  • 12
  • 26

1 Answers1

3

The solution is simple enough: make X into an index rather than a parameter.

Inductive mySet :=
| funSet   : mySet -> mySet -> mySet
| prod     : mySet -> mySet -> mySet.

Inductive el: mySet -> Type :=
  | eval  : forall {X Y : mySet}, el (funSet Y X) -> el Y -> el X
  | proj1 : forall {X Y : mySet}, el (prod X Y) -> el X
  | proj2 : forall {X Y : mySet}, el (prod Y X) -> el X
  | compose : forall {A B C : mySet}, el (funSet A B) -> el (funSet B C) -> el (funSet A C).

Intuitively, the difference is that for some inductive type IndType X, when X is a parameter, each IndType X has essentially the same shape. For example, with list X, regardless of what X is, the elements of the type look like nil, cons a nil, cons a (cons b nil) etc. In contrast, for el X, if X happens to be some funSet A C, it gets some extra constructors of the form compose f g. The actual shape of the inductive type depends on what X is.

See also:

SCappella
  • 9,534
  • 1
  • 26
  • 35