【发布时间】:2015-04-02 02:31:08
【问题描述】:
我正在考虑编写一个 Coq 程序来验证 relational algebra 的某些属性。我有一些基本的数据类型可以工作,但是连接元组给我带来了一些麻烦。
这是相关的代码部分:
Require Import List.
Require Import String.
(* An enum representing SQL types *)
Inductive sqlType : Set := Nat | Bool.
(* Defines a map from SQL types (which are just enum values) to Coq types. *)
Fixpoint toType (t : sqlType) : Set :=
match t with
| Nat => nat
| Bool => bool
end.
(* A column consists of a name and a type. *)
Inductive column : Set :=
| Col : string -> sqlType -> column.
(* A schema is a list of columns. *)
Definition schema : Set := list column.
(* Concatenates two schema together. *)
Definition concatSchema (r : schema) (s : schema) : schema := app r s.
(* Sends a schema to the corresponding Coq type. *)
Fixpoint tuple (s : schema) : Set :=
match s with
| nil => unit
| cons (Col str t) sch => prod (toType t) (tuple sch)
end.
Fixpoint concatTuples {r : schema} {s : schema} (a : tuple r) (b : tuple s) : tuple (concatSchema r s) :=
match r with
| nil => b
| cons _ _ => (fst a , concatTuples (snd a) b)
end.
在函数 concatTuples 中,在 nil 的情况下,CoqIDE 给我一个错误:
"The term "b" has type "tuple s" while it is expected to have type "tuple (concatSchema ?8 s)"."
我想我明白那里发生了什么;类型检查器无法确定 s 和 concatSchema nil s 是否相等。但我发现更奇怪的是,当我添加以下行时:
Definition stupid {s : schema} (b : tuple s) : tuple (concatSchema nil s) := b .
并将大小写更改为nil => stupid b,它可以工作。 (好吧,它仍然抱怨 cons 案例,但我认为这意味着它正在接受 nil 案例。)
我对此有三个问题:
- 有没有办法消除
stupid?看起来 Coq 知道类型是相等的,它只需要某种提示。 - 我到底该怎么做呢?我在编写类似
stupid的函数时遇到了很多麻烦。 - 这甚至是异构列表的正确方法吗?对我来说,这似乎是最直接的一个,但我对 Curry-Howard 以及 Coq 代码的实际含义了解得非常松散。
【问题讨论】:
-
我会尽量避免这么多,呃,“类型变化”。
-
你到底是什么意思?
标签: coq convoy-pattern