多类型列表的Coq表示法

时间:2014-11-05 10:58:24

标签: coq

这是一个人为的多类型列表:

Inductive Apple : Set :=.
Inductive Pear : Set :=.

Inductive FruitList : Set := 
| Empty 
| Cons_apple (a : Apple) (p : FruitList) 
| Cons_pear (p : Pear) (p: FruitList).

Variable a : Apple.
Variable p : Pear.

Definition a_fruitList := Cons_apple a (Cons_pear p Empty).

有没有办法为此定义列表表示法,例如,a_fruitList可以由[p,a]定义?

3 个答案:

答案 0 :(得分:3)

问题是你的列表有两个cons构造函数,而递归表示法的通常表示法机制要求你总是使​​用相同的构造函数。强制可以帮助您克服部分问题:

Section ApplesAndPears.

Variable Apple Pear : Set.

Inductive FruitList : Set :=
| Nil
| ConsApple (a : Apple) (l : FruitList)
| ConsPear (p : Pear) (l : FruitList).

Inductive Fruit : Set :=
| IsApple (a : Apple)
| IsPear (p : Pear).

Coercion IsApple : Apple >-> Fruit.
Coercion IsPear : Pear >-> Fruit.

Definition ConsFruit (f : Fruit) (l : FruitList) : FruitList :=
  match f with
  | IsApple a => ConsApple a l
  | IsPear p => ConsPear p l
  end.

Notation "[ ]" := (Nil) (at level 0).
Notation "[ x ; .. ; y ]" := (ConsFruit x .. (ConsFruit y Nil) ..) (at level 0).

Variable a : Apple.
Variable p : Pear.

Definition a_fruitList := [ a ; p ].

End ApplesAndPears.

(顺便说一句,我假设你真的打算写[ a ; p ],而不是[ p ; a ]。如果你的意思是写[ p ; a ],那么你只需要使用而是一个SnocFruit函数,它将元素添加到列表的末尾。但是,这会使后面解释的问题更加严重。)

现在,我们已经定义了一个替换构造函数的新函数,并且可以通过将Fruit的构造函数声明为强制来使用该函数。

当然,这个解决方案并不完全令人满意,因为你的符号产生的术语引用ConsFruit,而理想情况下,选择ConsAppleConsFruit的内容会很好取决于你给出的论点。我怀疑用符号机制没有办法做到这一点,但我可能是错的。

这是我建议您仅使用list类型并声明其他类型(例如Fruit)以保留ApplePear而非使用两个cons构造函数,除非你有充分的理由不这样做。

答案 1 :(得分:3)

正如Arthur Azevedo De Amorim所提到的,问题是Coq的Notation机制没有考虑子表达式的类型来区分Cons_apple和{{1} }。但是,您可以使用Type Classes执行此操作:

Cons_pear

我们在这里定义了一个包含单个函数的类型类Class Cons_fruit(A:Set) := { CONS: A -> FruitList -> FruitList }. Instance Cons_fruit_apple: Cons_fruit Apple:= { CONS := Cons_apple }. Instance Cons_fruit_pear: Cons_fruit Pear := { CONS := Cons_pear }. Notation " [ x ; .. ; y ] " := (CONS x .. (CONS y Empty) .. ). Definition test := [a; p; p; a ]. ,以及两个实例,一个用于处理苹果,一个用于处理梨。然后我们可以在表示法中使用模板化的CONS函数,Coq将在需要时选择适当的实例。

请注意,这可能会导致错误消息的可理解性降低。例如,

Cons_fruit

你会得到

Definition bad:= [ 0; p ].

答案 2 :(得分:-1)

以下是Coq关于lists

的文档摘录
Notation " [ ] " := nil : list_scope.
Notation " [ x ] " := (cons x nil) : list_scope.
Notation " [ x ; .. ; y ] " := (cons x .. (cons y nil) ..) : list_scope.

我会坚持使用;而不是,,因为后者通常用于Coq的语法,因此正确获取符号优先级可能很棘手。

最佳,