Reputation: 511
I want to proof the factor function correctness in Use proof of if expression = true in then part coq
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.
after unfold I expected see a if and destruct its condition , but now I see this :
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)
How I can complete the proof?
Upvotes: 0
Views: 696
Reputation: 5811
Program
gives you terms that are difficult to work with, so you should prove a lemma that factor
is equal to its body, and then rewrite with that, instead of unfolding. (I used match
instead of if
to get hold of the dvd
proof term.)
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.
When you unfold and rewrite with Fix_eq
you get such a horrible goal term to look at that it's best to fold it quickly! :-) It can be handled with reflexivity
or auto
anyway.
The second goal typically requires algebraic manipulation with omega
or similar to show that the LHS equals RHS, but in this case it was sufficient with congruence
.
How did I know to use Fix_eq
? When I unfolded factor_func
I saw it contained Wf.Fix_sub
, so I searched for lemmas with Search (Wf.Fix_sub).
and found a few.
Now you should continue your proof by rewriting with the lemma:
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.
Now your goal state is
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)
which probably makes more sense.
Upvotes: 2