Coq中的异构列表

Coq中的异构列表,coq,convoy-pattern,Coq,Convoy Pattern,我正在考虑编写一个Coq程序来验证的某些属性。我已经有了一些基本的数据类型,但是连接元组给我带来了一些麻烦 以下是代码的相关部分: 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) t

我正在考虑编写一个Coq程序来验证的某些属性。我已经有了一些基本的数据类型,但是连接元组给我带来了一些麻烦

以下是代码的相关部分:

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 .
如果将case改为
nil=>dumby b
,它就可以工作了。(好吧,它仍在投诉cons案,但我认为这意味着它接受了nil案。)

关于这一点,我有三个问题:

  • 有没有办法消除
    愚蠢的
    ?似乎Coq知道类型是相等的,它只需要一些提示
  • 我到底该怎么办呢?我在编写一个类似
    的愚蠢函数时遇到了很多麻烦
  • 这甚至是处理异构列表的正确方法吗?对我来说,这似乎是最简单的一个,但我对Curry Howard以及Coq代码的实际含义的理解非常松散

  • 这是Coq新手经常遇到的问题之一:无法向Coq展示如何使用在
    match
    语句分支中获得的附加信息

    解决方案是使用所谓的重新抽象依赖于scrutinee的参数,并使
    匹配
    返回一个函数:

    Fixpoint concatTuples {r : schema} {s : schema} : tuple r -> tuple s -> tuple (concatSchema r s) :=
      match r return tuple r -> tuple s -> tuple (concatSchema r s) with
        | nil => fun a b => b
        | cons (Col _ t) _ => fun a b => (fst a, concatTuples (snd a) b)
      end.
    
    在这种特殊情况下,实际上不需要
    返回
    注释,因为Coq可以推断它。然而,当事情有点不对劲时,忽略它通常会导致无法理解的错误消息,所以最好将它们保留在其中。请注意,我们还必须在列表的第一个元素(
    Col\ut
    pattern)中包含嵌套匹配,以便在
    tuple
    的定义中模拟该模式。再次详细解释了这里发生的事情以及如何在Coq中编写此类函数

    为了回答你的最后一个问题,对异构列表的许多开发或多或少与你在这里所做的相同(例如,我有一个与此非常相似的开发)。如果我必须更改任何内容,我会删除
    元组定义中的嵌套模式,这允许您编写此类代码,同时使用更少的
    匹配和注释。比较:

    Definition typeOfCol c :=
      match c with
      | Col _ t => t
      end.
    
    (* Sends a schema to the corresponding Coq type. *)
    Fixpoint tuple (s : schema) : Set :=
      match s with
        | nil => unit
        | cons col sch => prod (toType (typeOfCol col)) (tuple sch)
      end.
    
    Fixpoint concatTuples {r : schema} {s : schema} : tuple r -> tuple s -> tuple (concatSchema r s) :=
      match r return tuple r -> tuple s -> tuple (concatSchema r s) with
        | nil => fun a b => b
        | cons _ _ => fun a b => (fst a, concatTuples (snd a) b)
      end.
    

    你可以找到这个问题的其他例子。

    我会尽量避免这么多,呃,“类型变量”。你到底是什么意思?