使用感应时保持信息?

时间:2010-12-23 14:38:19

标签: coq

我正在使用Coq Proof Assistant来实现(小)编程语言的模型(扩展由Bruno De Fraine,Erik Ernst,MarioSüdholt执行的Featherweight Java)。使用induction策略时不断出现的一件事是如何保留包含在类型构造函数中的信息。

我有一个子类型Prop,实现为

Inductive sub_type : typ -> typ -> Prop :=
| st_refl : forall t, sub_type t t
| st_trans : forall t1 t2 t3, sub_type t1 t2 -> sub_type t2 t3 -> sub_type t1 t3
| st_extends : forall C D,
    extends C D ->
    sub_type (c_typ C) (c_typ D).

Hint Constructors sub_type.

其中extends是Java中的类扩展机制,typ表示可用的两种不同类型,

Inductive typ : Set :=
| c_typ : cname -> typ
| r_typ : rname -> typ.

我希望保存类型信息的一个示例是在假设上使用induction策略时

H: sub_type (c_typ u) (c_typ v)

E.g。在

u : cname
v : cname
fsv : flds
H : sub_type (c_typ u) (c_typ v)
H0 : fields v fsv
============================
 exists fs : flds, fields u (fsv ++ fs)

使用induction H.会丢弃有关uv的所有信息。 st_refl案例变为

u : cname
v : cname
fsv : flds
t : typ
H0 : fields v fsv
============================
 exists fs : flds, fields u (fsv ++ fs)

正如您所看到的,uvtyp中的H构造函数相关联的信息,以及t的信息将丢失。更糟糕的是,由于此问题,Coq无法确定uv在这种情况下实际上必须相同。

inversion上使用H策略时,Coq成功地看到uv是相同的。然而,这种策略不适用于此,因为我需要induction生成的归纳假设来证明st_transst_extends个案。

是否有一种策略结合了inversioninduction的最佳效果,既可以生成归纳假设,又可以在不破坏有关构造函数包含内容的信息的情况下导出等式?或者,有没有办法手动导出我需要的信息? info inversion Hinfo induction H都表明会自动应用大量转换(尤其是使用inversion)。这些导致我尝试change策略以及let ... in构造,但没有任何进展。

3 个答案:

答案 0 :(得分:14)

当您需要引入具有参数具有特定结构(sub_type (c_typ u) (c_typ v))的从属类型(c_typ u)的假设时,这是一个普遍问题。有一个通用技巧,即有选择地将结构化参数重写为变量,保持环境中的相等性。

set (t1 := c_typ u) in H; assert (Eq1 : t1 = c_typ u) by reflexivity; clearbody t1.
set (t2 := c_typ u) in H; assert (Eq2 : t2 = c_typ u) by reflexivity; clearbody t2.
induction H. (*often "; try subst" or "; try rewrite Eq1; try rewrite Eq2" *).

从Coq 8.2开始,这种常见的set-assert-clearbody模式由内置策略remember term as ident in *goal_occurences*执行。

这是使用这种策略证明的一个愚蠢的引理。

Lemma subtype_r_left_equal :
  forall r1 t2, sub_type (r_typ r1) t2 -> r_typ r1 = t2.
Proof.
  intros.
  remember (r_typ r1) as t1 in H.
  induction H.
  congruence.
  solve [firstorder].
  discriminate.
Qed.

奖金提示(来自经验,但它已经有一段时间了,所以我不记得细节):当你在类型系统上进行相当的语法推理时(当你做这些机械校样时往往就是这种情况) ),可以方便地在Set中输入判断。考虑将派生键入为您推理的对象。我记得在类型派生中引入平等很方便的情况,这并不总是适用于Prop中的输入派生。


使用Problem.v,这是反身性案例的证明。对于传递性,我怀疑你的归纳假设不够强。这可能是您简化问题的方式的副产品,尽管传递性通常需要令人惊讶地涉及诱导假设或引理。

Fact sub_type_fields: forall u v fsv,
  sub_type (c_typ u) (c_typ v) -> fields v fsv ->
  exists fs, fields u (fsv ++ fs).
Proof.
  intros.
  remember (c_typ u) as t1 in H.
  remember (c_typ v) as t2 in H.
  induction H.
  (* case st_refl *)
  assert (v = u). congruence. subst v t.
  exists nil. rewrite <- app_nil_end. assumption.
  (* case st_trans *)
  subst t1 t3.
  (* case st_extends *)
Admitted.

答案 1 :(得分:5)

我遇到了类似的问题,Coq 8.3的“依赖感应”策略处理了业务。

答案 2 :(得分:3)

我确信CPDT对这个问题有一些评论,但它并不完全明显。以下是一些链接:

  1. http://adam.chlipala.net/cpdt/html/Cpdt.Predicates.html部分&#34;隐含平等的预测&#34;可能是Coq&#34;失去信息的最简单的情况。 (在破坏,而不是归纳。)它还解释了为什么这些信息丢失:当你破坏一个应用于不是自由变量的参数的类型时,这些类型首先被自由变量替换(这就是为什么Coq输了信息。)

  2. http://adam.chlipala.net/cpdt/html/Cpdt.Universes.html第34节&#34;避免公理的方法&#34;显示了一些避免公理K的技巧,包括&#34;平等技巧&#34;吉尔斯描述。搜索&#34;使用基于平等的通用技巧来支持对非变量参数的归纳以键入族#34;

  3. 我认为这种现象与依赖模式匹配密切相关。