You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何处理返回类型为a=b→c的match项(护航模式)的Coq证明

Coq护航模式下的证明推进问题

我在Coq开发中推进到以下证明目标后无法继续:

A: Type
a: list (list A)
b: list A
i,j: nat
Hi: i < length a
Hj: j < length (nth i a [])
--------------------------------------------
nth_error (nth i a []) j =
Some
  (match nth2 i j as e return (nth2 i j = e -> A) with
| Some a0 => fun _ : nth2 i j = Some a0 => a0
| None =>
    fun H : nth2 i j = None =>
False_rect A (nth2_not_None Hi Hj H)
end
  eq_refl)

我无法将nth2 i j改写为Some x(尽管已证明它不可能是None)。想请教:当使用返回类型为a=b -> c的护航模式时,该如何推进这个证明?注意:我不需要改用其他没有这个问题的nth2定义方案。


完整代码

Require Import List.
Import ListNotations.
Require Import Fin.

Section Example.

Variable (A:Type).
Variable (a:list (list A)) (b: list A).


Definition indices := 
  { '(i, j):(nat * nat) |  i < length a /\ j < length (nth i a [])}.


Definition lookup_spec (f:indices -> A) := 
  forall ij, let '(i,j) := proj1_sig ij in
  nth_error (nth i a []) j = Some (f ij).


Definition nth2 i j : option A :=
  match nth_error a i with Some ai => nth_error ai j | None => None end.


Lemma nth2_not_None {i j} (Hi: i < length a) (Hj: j < length (nth i a [])):
  nth2 i j <> None.
  unfold nth2.
  enough (exists (d:A), True) as [d _] by
  now rewrite (nth_error_nth' _ [] Hi), (nth_error_nth' _ d Hj).
  destruct (nth i a []) as [| x l]. now exfalso. now exists x.
Defined.



Definition lookup (ij : indices):  A :=
  let '(exist _ (i, j) (conj Hi Hj)) := ij in
  match nth2 i j as e return nth2 i j = e -> A with
  | Some a => fun _ => a 
  | None => fun H => False_rect _ (nth2_not_None Hi Hj H)
  end eq_refl.


Lemma lookup_ok: lookup_spec lookup.
    intros [[i j] [Hi Hj]].
    unfold proj1_sig, lookup.

(* 在此处卡壳 *)


解决方案

要处理这种护航模式的证明,核心思路是对nth2 i j进行分情况讨论,利用已有的Hi和Hj排除None的分支:

  • 首先,对nth2 i j执行分情况解构并保留等式关系:destruct (nth2 i j) eqn:E。
  • 对于None分支,结合nth2_not_None Hi Hj E可直接导出矛盾,用contradiction消除该分支。
  • 对于Some x分支,此时目标中的match表达式会被化简为x,再结合nth2的定义与Hi,将左边的nth_error (nth i a []) j与Some x关联,完成证明。

具体补充的证明步骤如下:

Lemma lookup_ok: lookup_spec lookup.
    intros [[i j] [Hi Hj]].
    unfold proj1_sig, lookup.
    (* 对nth2的结果分情况,记录等式 *)
    destruct (nth2 i j) eqn:E.
    - (* 分支:nth2 i j = Some a0 *)
      simpl. (* 此时match会被化简为a0 *)
      unfold nth2 in E.
      (* 利用Hi得到nth_error a i = Some (nth i a []) *)
      rewrite (nth_error_nth' _ [] Hi) in E.
      simpl in E.
      (* 此时E变为nth_error (nth i a []) j = Some a0,正好匹配目标 *)
      rewrite E.
      reflexivity.
    - (* 分支:nth2 i j = None *)
      (* 调用nth2_not_None得到矛盾 *)
      specialize (nth2_not_None Hi Hj E).
      contradiction.
Qed.

关键在于通过destruct ... eqn:E保留nth2 i j的结果与原表达式的等式关系,这样在Some分支中可以直接用该等式改写目标,而None分支则通过已有的引理直接排除。


内容的提问来源于stack exchange,提问作者larsr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 05:13:17