Coq

时间:2015-04-25 20:41:20

标签: list heap coq isomorphism

我证明了一些关于列表的定理,并从中提取了算法。现在我想使用堆,因为查找和连接更快。我目前要做的是只为提取的列表类型使用自定义定义。我想以更正式的方式做到这一点,但理想情况下无需重做我的所有证据。可以说我有一个类型

Heap : Set -> Set

和同构

f : forall A, Heap A -> List A.

此外,我有函数H_app和H_nth,这样

H_app (f a) (f b) = f (a ++ b)

H_nth (f a) = nth a

一方面,我必须用模仿列表递归的专用函数替换每个列表递归。另一方面,事先我希望将++nth替换为H_appH_nth,因此提取的算法会更快。问题是我在某些地方使用simplcompute等策略,如果我只是替换证明代码中的所有内容,这可能会失败。之后有可能“重载”这些函数会很好。

这样的事情可能吗?

编辑:为了澄清,数字出现了类似的问题:我有一些使用nat的旧证明,但数字太大了。使用BinNat会更好,但是在旧证明中是否可以使用BinNat代替nat而无需进行太多修改? (尤其是,用+更有效的定义替换BinNat的低效率用法?)

1 个答案:

答案 0 :(得分:3)

为了清楚起见,我认为Heap必须是这样的 这样:

Inductive Heap A : Type :=
| Node : Heap A -> A -> Heap A -> Heap A
| Leaf : Heap A.

f定义为

Fixpoint f A (h : Heap A) : list A :=
  match h with
  | Node h1 a h2 => f h1 ++ a :: f h2
  | Leaf => []
  end.

如果是这种情况,那么f 定义之间的同构 所有Heap A的{​​{1}}和list A。相反,我们可以找到一个功能 A这样

g : forall A, list A -> Heap A

尽管如此,我们想说forall A (l : list A), f (g l) = l Heap都是。{ 当它们用于实现相同的某种意义上 抽象,即某种类型的元素集。

我们可以通过一种精确而正式的方式验证这一想法 在具有parametric polymorphism的语言中,例如Coq。这个 原则,称为parametricity,粗略地说 参数多态函数尊重我们强加的关系 在类型上我们用。实例化它们。

这有点抽象,所以让我们试着做更多 具体。假设你有一个列表功能(比如list) 仅使用foo++。能够用{替换nth 使用参数化的foo上的等效版本,我们需要做 Heap的定义是多态的,抽象了函数 列表:

foo

首先通过实例化来证明foo的属性 列表:

Definition foo (T : Set -> Set)
               (app : forall A, T A -> T A -> T A)
               (nth : forall A, T A -> nat -> option A)
               A (l : T A) : T A :=
  (* ... *)

现在,因为我们现在Definition list_foo := foo list @app @nth. Lemma list_foo_lemma : (* Some statement *). H_app与他们相容 列出对应物,因为H_nth是多态的,理论是 参数化说我们可以证明

foo
有了这个引理,应该可以运输属性 Definition H_foo := foo Heap @H_app @H_nth. Lemma foo_param : forall A (h : Heap A), f (H_foo h) = list_foo (f h). 的{​​{1}}类似属性。list_foo。例如,作为一个 举个简单的例子,我们可以证明H_foo是关联的,最多可以 转换为列表:

H_app

参数化的好处在于它适用于任何 参数化多态函数:只要合适 兼容性条件保持您的类型,应该是可能的 以类似的方式关联给定函数的两个实例 forall A (h1 h2 h3 : Heap A), list_foo (H_app h1 (H_app h2 h3)) = list_foo (H_app (H_app h1 h2) h3).

然而,有两个问题。第一个是必须改变 你的基本定义是多态的,这可能不是这样 坏。然而,更糟糕的是,尽管参数确保了 总是有可能证明foo_param之下的引理 在某些条件下,Coq不会免费提供给您,而您仍然可以 需要手工显示这些引理。有两件事可以帮助我们 减轻你的痛苦:

  1. Coq(CoqParam)的parametricity plugin应该是。{ 帮助自动为您提供样板证明。我有 但是从来没有使用它,所以我真的不能说它有多容易使用。

  2. Coq Effective Algebra Library(简称CoqEAL)使用 参数化来证明有效算法的事情 推理更方便的。特别是,他们定义 允许在foo_paramnat之间切换的优化,如 你建议。在内部,他们使用基于的基础设施 类型推断,你可以适应你的原始 例如,但我听说他们正在迁移他们的 实现使用CoqParam代替。