Coq:多个构造函数的单个表示法

时间:2016-06-27 17:47:39

标签: constructor coq

是否可以为Coq中的多个构造函数定义单个表示法?如果构造函数的参数类型不同,那么它们可能是可以推断的。一个最小(非)工作的例子:

Inductive A : Set := a | b | c: C -> A | d: D -> A
with C: Set := c1 | c2
with D: Set := d1 | d2.

Notation "' x" := (_ x) (at level 19).
Check 'c1. (*?6 c1 : ?8*)

在这种情况下,构造函数推断不起作用。也许还有另一种方法可以将构造函数指定为变量吗?

3 个答案:

答案 0 :(得分:4)

您可以使用构造函数作为实例创建一个类型类,并让实例解析机制推断出要为您调用的构造函数:

Class A_const (X:Type) : Type :=
  a_const : X -> A.
Instance A_const_c : A_const C := c.
Instance A_const_d : A_const D := d.

Check a_const c1.
Check a_const d2.

顺便说一句,使用Coq 8.5,如果你真的想要一个符号' x来导致应用于x的确切构造函数,而不是@a_const C A_const_c c1,然后您可以使用ltac-terms来实现这一目标:

Notation "' x" := ltac:(match constr:(a_const x) with
                        | @a_const _ ?f _ =>
                          let unfolded := (eval unfold f in f) in
                          exact (unfolded x)
                        end) (at level 0).
Check 'c1. (* c c1 : A *)
Check 'd2. (* d d2 : A *)

答案 1 :(得分:1)

事实上,使用ltac-term的想法导致了与我发布的另一个完全不同的解决方案:

Notation "' x" := ltac:(let T := (type of x) in
                        let T' := (eval hnf in T) in
                        match T' with
                        | C => exact (c x)
                        | D => exact (d x)
                        end) (at level 0).
Check 'c1. (* c c1 : A *)
Check 'd2. (* d d2 : A *)

(这里eval hnf部分允许它工作,即使参数的类型在句法上不等于CD,但它确实减少到其中一个。)

答案 2 :(得分:0)

显然,这很简单:

Notation "' x" := ((_:_->A) x) (at level 19).
Check 'c1. (*' c1 : A*)