8

I would like to be able to define the same Coq notations for different inductive definitions, and distinguish the notations based on the types of their arguments.

Here is a minimal example:

Inductive type : Type :=
| TBool : type.

Inductive term1 : Type :=
| tvar1 : term1.

Inductive term2 : Type :=
| tvar2 : term2.

Definition context := nat -> (option type).

Reserved Notation "G '⊢' t '::' T" (at level 40, t at level 59).

Inductive typing1 : context -> term1 -> type -> Prop :=
 | T_Var1 : forall G T,
      G ⊢ tvar1 :: T
where "G '⊢' t1 '::' T" := (typing1 G t1 T)                            
with typing2 : context -> term2 -> type -> Prop :=
 | T_Var2 : forall G T,
      G ⊢ tvar2 :: T
where "G '⊢' t2 '::' T" := (typing2 G t2 T).

As you see, there is a mutually inductive definition, in which I'd like to be able to use the same notation for different types of terms (term1 and term2).

The error I get when trying to compile this is The term "tvar1" has type "term1" while it is expected to have type "term2"..

Is there a way to get this to work?

amaurremi
  • 777
  • 1
  • 5
  • 11
  • You can use notation scopes, however not sure if that will work with a where clause. – ejgallego May 17 '17 at 21:16
  • I would like to be able to use both meanings of the same notation throughout my proof, without having to specify scopes, if possible. – amaurremi May 17 '17 at 21:31
  • 1
    So how is Coq supposed to disambiguate it? There may be technical workarounds with Coercions and/or type classes, but I would just use a different turn-style for each and I would be done with it. – ejgallego May 18 '17 at 00:30
  • Unless you really have an injection from one to the other, etc... YMMV, it is hard to say more without having a bit more of context. One of the most generic thing you could implement would be in the style of math-comp by hacking unification and Canonicals. – ejgallego May 18 '17 at 00:33
  • You get this error because you try to apply `tvar1` to `x`. This error does not report a notation problem. – eponier May 18 '17 at 08:39
  • @ejgallego I would like Coq to disambiguate the notation based on the type of the second parameter. I was hoping it would be possible to do with type classes, for example, but I couldn't get it to work myself. – amaurremi May 18 '17 at 15:35
  • @amaurremi notation "interpretation" in Coq happens before type information is available. In fact, it is a purely AST to AST transformation, and scopes are the only things that can influence it. After notations are unsugared, placeholder for implicit arguments are inserted and then, only then, type inference will be called. Thus, in order to support this kind of overloading, you could try scopes (which have some amount of power), but usually you'll have to resolve your notation to an intermediate structure, to be disambiguated in type inference. – ejgallego May 18 '17 at 16:19
  • And could the problem be solved by defining a type class that abstracts over term1 and term2 (something like `Class typing (g:context) (X:Type) (t:type) := ...`), then define the notation for the type class, and use that inside of my inductive definition? Then the notation would always refer to the type class, which would take care of the interpretation. – amaurremi May 18 '17 at 17:22
  • @eponier Sorry, you're right, I removed the x and updated the error. – amaurremi May 18 '17 at 18:00

1 Answers1

8

I wrote to the Coq mailing list and received an answer from Gaëtan Gilbert that solved my problem using type classes:

Inductive type : Type :=
| TBool : type.

Inductive term1 : Type :=
| tvar1 : term1.

Inductive term2 : Type :=
| tvar2 : term2.

Definition context := nat -> (option type).

Class VDash (A B C : Type) := vdash : A -> B -> C -> Prop.
Notation "G '⊢' t '::' T" := (vdash G t T) (at level 40, t at level 59).

Inductive typing1 : VDash context term1 type :=
| T_Var1 : forall G T,
    G ⊢ tvar1 :: T

with typing2 : VDash context term2 type :=
| T_Var2 : forall G T,
    G ⊢ tvar2 :: T.
Anton Trunov
  • 15,074
  • 2
  • 23
  • 43
amaurremi
  • 777
  • 1
  • 5
  • 11