Coq 如何用复杂的模式匹配进行推理?

Coq 如何用复杂的模式匹配进行推理?,coq,Coq,Coq允许编写复杂的模式匹配,但随后它将其分解,以便其内核能够处理它们 例如,让我们考虑下面的代码。 Require Import List. Import ListNotations. Inductive bar := A | B | C. Definition f (l : list bar) := match l with | _ :: A :: _ => 1 | _ => 2 end. 我们在列表和第二个元素上进行模式匹配。打印f显示Coq存储了更复杂的

Coq允许编写复杂的模式匹配,但随后它将其分解,以便其内核能够处理它们

例如,让我们考虑下面的代码。

Require Import List. Import ListNotations.

Inductive bar := A | B | C.

Definition f (l : list bar) :=
  match l with
  | _ :: A :: _ => 1
  | _ => 2
  end.
我们在列表和第二个元素上进行模式匹配。打印
f
显示Coq存储了更复杂的版本

Print f.
(* f = fun l : list bar => match l with
                        | [] => 2
                        | [_] => 2
                        | _ :: A :: _ => 1
                        | _ :: B :: _ => 2
                        | _ :: C :: _ => 2
                        end
     : list bar -> nat
*)
问题是,在证明操作
f
中,我必须处理5个案例,而不是仅处理2个,其中4个是多余的


处理这个问题的最好方法是什么?有没有一种方法可以像完全按照定义一样对模式匹配进行推理?

您是正确的,因为Coq实际上简化了模式匹配,从而产生了大量冗余。 然而,有一些方法可以对案例分析进行推理,你的意思是与Coq的理解相反

  • 使用
    函数
    和是一种方法
  • 最近,还允许您定义模式匹配,它会自动为其派生归纳原则(您可以使用
    funelim
    调用)。 为了使coq案例能够被分解,您必须使用视图的概念。 它们是在方程式的上下文中描述的。 我将详细介绍如何使您的示例适应它
From Equations Require Import Equations.
Require Import List. Import ListNotations.

Inductive bar := A | B | C.

Equations discr (b : list bar) : Prop :=
  discr (_ :: A :: _) := False ;
  discr _ := True.

Inductive view : list bar -> Set :=
| view_foo : forall x y, view (x :: A :: y)
| view_other : forall l, discr l -> view l.

Equations viewc l : view l :=
    viewc (x :: A :: y) := view_foo x y ;
    viewc l := view_other l I.

Equations f (l : list bar) : nat :=
    f l with viewc l := {
    | view_foo _ _ => 1 ;
    | view_other _ _ => 2
    }.

Goal forall l, f l < 3.
Proof.
    intro l.
    funelim (f l).
    - repeat constructor.
    - repeat constructor.
Qed.
Require Import List. Import ListNotations.

Inductive bar := A | B | C.

Definition f (l : list bar) :=
  match l with
  | _ :: A :: _ => 1
  | _ => 2
  end.

Definition discr (l : list bar) : Prop :=
    match l with
    | _ :: A :: _ => False
    | _ => True
    end.

Lemma f_ind :
    forall (P : list bar -> nat -> Prop),
        (forall x y, P (x :: A :: y) 1) ->
        (forall l, discr l -> P l 2) ->
        forall l, P l (f l).
Proof.
    intros P h1 h2 l.
    destruct l as [| x [|[] l]].
    3: eapply h1.
    all: eapply h2.
    all: exact I.
Qed.

Goal forall l, f l < 3.
Proof.
    intro l.
    eapply f_ind.
    - intros. repeat constructor.
    - intros. repeat constructor.
Qed.