簡體   English   中英

Coq將功能擴展為目標的一部分是什么意思?

[英]What does it mean when Coq expands a function as part of the goal?

我試圖解決以下定理,並陷入最后的simpl.

Lemma nonzeros_app : forall l1 l2 : natlist,
  nonzeros (l1 ++ l2) = (nonzeros l1) ++ (nonzeros l2).
Proof.
  intros l1 l2. induction l1 as [| n' l' IHl'].
  -simpl. reflexivity.
  -simpl. 
Qed.

那時,Coq將目標從:

1 subgoal (ID 170)

  n' : nat
  l', l2 : natlist
  IHl' : nonzeros (l' ++ l2) = nonzeros l' ++ nonzeros l2
  ============================
  nonzeros ((n' :: l') ++ l2) = nonzeros (n' :: l') ++ nonzeros l2

至:

1 subgoal (ID 185)

  n' : nat
  l', l2 : natlist
  IHl' : nonzeros (l' ++ l2) = nonzeros l' ++ nonzeros l2
  ============================
  match n' with
  | 0 => nonzeros (l' ++ l2)
  | S _ => n' :: nonzeros (l' ++ l2)
  end =
  match n' with
  | 0 => nonzeros l'
  | S _ => n' :: nonzeros l'
  end ++ nonzeros l2

在我看來,這完全是個謎。 Coq只是復制將函數的定義粘貼到我的目標中是什么意思? 我什至要怎么辦?


問題背景:

有人告訴我解決方案是:

Lemma nonzeros_app : forall l1 l2 : natlist,
  nonzeros (l1 ++ l2) = (nonzeros l1) ++ (nonzeros l2).
Proof.
  intros l1 l2. induction l1.
  - simpl. reflexivity.
  - simpl. { induction n.
             - ...
             - ... }
Qed.

這讓我想了解為什么他們在n上使用歸納法,因為我覺得在那里永遠不會發生歸納法。 所以我問,為什么? 但是我意識到,在問起我為什么之前甚至不了解證明狀態之前,我就意識到了,因為這似乎只是將粘貼復制到了證明狀態(這對我來說沒有意義)。 因此,在我問為什么使用歸納法之前,我必須問一下在此之前證明狀態是什么,也許這將闡明為什么對n歸納法。

我假設您已通過以下方式(或類似方式)定義了nonzeros

Require Import List.
Import ListNotations.


Definition natlist := list nat.

Fixpoint nonzeros (l : natlist) :=
  match l with
  | [] => []
  | 0 :: xs => nonzeros xs
  | x :: xs => x :: nonzeros xs
  end.

因此, nonzeros是遞歸的,結構遞減為l Coq的simpl策略采用了一種啟發式方法,在該方法中,如果將固定點的定義應用於以構造函數作為開頭符號的術語,則會展開固定點的定義。 在您的情況下,例如nonzeros (n' :: l') ,常量nonzeros后跟由構造函數Cons (= :: nonzeros構成的項。 Coq執行所謂的“減少增量”,用其定義替換nonzero的出現。 由於該定義是match ,因此您將獲得一個match作為新術語。 進一步的替換確實使它簡化了一點,但是不能消除兩種情況:一種表示零水頭,一種表示非零水頭。

出現的nonzeros ((n' :: l') ++ l2)發生同樣的情況,首先將其簡化為nonzeros (n' :: (l' ++ l2)) ,因此參數的開頭為Cons

如果要避免在簡化時公開match表達式,可以將以下偽指令放在nonzeros的定義nonzeros

Arguments nonzeros l : simpl nomatch.

這特別是告訴simpl ,如果會最終在更改位置公開match項,則避免擴展術語。

至於您的朋友在這里使用的induction :它用於強制將案例拆分為n' ,以便可以分別處理每個案例( n' = 0n' = S _ )。 實際上,這里不需要歸納法。 一個簡單的案例拆分( case n' )將執行相同的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM