簡體   English   中英

破壞程序定點coq中的條件

[英]Destruct if condition in program fixpoint coq

我要在部分coq使用if expression = true的證明中證明因子函數的正確性

Require Import ZArith Znumtheory.

Local Open Scope Z_scope.


Require Coq.Program.Tactics.
Require Coq.Program.Wf.

Lemma divgt0 ( a b : Z ) ( agt0 : 0 < a ) ( bgt1 : 1 < b ) (dvd : (b|a) ) : 0<a/b.
Proof.
  apply Zdivide_Zdiv_lt_pos.
  auto.
  auto.
  auto.
Qed.

Program Fixpoint factor ( a b : Z ) ( agt0 : 0 < a ) ( bgt1 : 1 < b ) {measure (Z.abs_nat a)} := 
  if Zdivide_dec b a 
  then 1+factor (a/b) b (divgt0 a b agt0 bgt1 _)  bgt1 
  else 0.
Next Obligation.
  assert ( 0 < a / b < a ).
  apply Zdivide_Zdiv_lt_pos.
  auto.
  auto.
  auto.
  apply Zabs_nat_lt.
  omega.
Qed.

Lemma factor_div ( a b : Z ) ( agt0 : 0 < a ) ( bgt1 : 1 < b ) : (b ^ (factor a b agt0 bgt1) | a).
Proof.
  unfold factor.

展開后,我希望看到一個if並破壞其條件,但是現在我看到了:

1 subgoal
a, b : Z
agt0 : 0 < a
bgt1 : 1 < b
______________________________________(1/1)
(b
 ^ factor_func
     (existT (fun a0 : Z => {b0 : Z & {_ : 0 < a0 & 1 < b0}}) a
        (existT (fun b0 : Z => {_ : 0 < a & 1 < b0}) b
           (existT (fun _ : 0 < a => 1 < b) agt0 bgt1))) | a)

我怎樣才能完成證明?

Program為您提供了難以使用的術語,因此您應證明一個factor等於其主體的引理,然后用該factor重寫,而不是展開。 (我用match代替了if掌握dvd證明條款。)

Lemma factor_lemma a b agt0 bgt1:
  factor a b agt0 bgt1 =
  match Zdivide_dec b a with
  | left dvd => 1+factor (a/b) b (divgt0 a b agt0 bgt1 dvd)  bgt1
  | right notdvd =>  0 end.
Proof.
  unfold factor at 1.
  unfold factor_func; rewrite Program.Wf.Fix_eq; fold factor_func.
  - reflexivity.
  - intros.
    destruct Zdivide_dec; auto.
    congruence.
Qed.

當您展開並用Fix_eq重寫時,您會看到一個可怕的目標術語,那就是最好將其快速折疊! :-)無論如何,可以通過reflexivityauto處理。

第二個目標通常需要使用omega或類似函數進行代數運算,以證明LHS等於RHS,但在這種情況下, congruence就足夠了。

我怎么知道使用Fix_eq 展開factor_func我看到它包含Wf.Fix_sub ,所以我用Search (Wf.Fix_sub).搜索了引理Search (Wf.Fix_sub). 並發現了一些。

現在,您應該通過引理重寫來繼續證明:

Lemma factor_div ( a b : Z ) ( agt0 : 0 < a ) ( bgt1 : 1 < b ) : (b ^ (factor a b agt0 bgt1) | a).
Proof.
  rewrite factor_lemma.
  destruct Zdivide_dec.

  2:   now rewrite Z.pow_0_r;apply Z.divide_1_l.

現在您的目標狀態是

  a, b : Z
  agt0 : 0 < a
  bgt1 : 1 < b
  d : (b | a)
  ============================
  (b ^ (1 + factor (a / b) b (divgt0 a b agt0 bgt1 d) bgt1) | a)

這可能更有意義。

暫無
暫無

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

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