[英]Theorem about vectors and recursive functions
下面我要證明aaa
。
任意自然數 k 的函數輸出的第 k 個元素必須與經過相同處理的同一向量的第 k 個值相同。
Require Import Coq.Vectors.Vector.
Require Import Psatz.
From mathcomp Require Import ssreflect.
Definition kLess : forall (k P:nat), (P - k) < (S P).
intros. lia.
Defined.
Definition Sum {A}(v:t nat A) :nat:= Vector.fold_right Nat.add v 0.
Fixpoint Sumation {A} (k:nat)(v:t nat (S A)):t nat (S k):=
match k in nat return t nat (S k) with
|0 => cons _ ((nth_order v (kLess k A)) + (Sum v)) _ (nil nat)
|S k' => cons _ ((nth_order v (kLess k A)) + (Sum v)) _ (Sumation k' v)
end.
Lemma aaa {n}(k:nat)(v:t nat (S n)): nth_order (Sumation n v) (kLess k n) = (nth_order v (kLess k n)) + (Sum v).
Proof.
rewrite /nth_order.
induction n.
destruct k => //.
請告訴我您的解決方案。
你需要理清你的陳述。 在目前的形式中,數字n
和向量v
用於不同目的的太多地方。 這使得歸納證明非常困難。
如果您查看Sumation
中的遞歸調用,您會看到第二個顯式參數(本地命名為v
)在遞歸調用期間不會更改,而主要遞歸參數k
減少。 因此,您必須有一個語句,其中第二個顯式參數不必具有大小S n
。 v
的大小大於或等於S n
就足夠了。
同樣, kLess _ _
的使用阻礙了你的思考能力和 Coq 的重寫能力。 真正重要的是,我們正在使用小於大小的參數訪問內部v
和Sumation _ _
調用的結果內部,因此您應該對此進行概括。
下面的證明利用了這些准則。
Require Import Coq.Vectors.Vector.
Require Import Psatz.
Require Import ssreflect.
Require Import Arith.
Definition kLess : forall (k P:nat), (P - k) < (S P).
intros. lia.
Defined.
Definition Sum {A}(v:t nat A) :nat:= Vector.fold_right Nat.add v 0.
Fixpoint Sumation {A} (k:nat)(v:t nat (S A)):t nat (S k):=
match k in nat return t nat (S k) with
|0 => cons _ ((nth_order v (kLess k A)) + (Sum v)) _ (nil nat)
|S k' => cons _ ((nth_order v (kLess k A)) + (Sum v)) _ (Sumation k' v)
end.
Definition v := cons nat 0 1 (cons nat 1 0 (nil nat)).
Compute Sumation 0 v.
Compute nth_order (Sumation 0 v) (kLess 0 _).
Compute nth_order v (kLess 0 _) + Sum v.
Lemma aaa {n}(k:nat)(v:t nat (S n)): nth_order (Sumation n v) (kLess k n) =
(nth_order v (kLess k n)) + (Sum v).
Proof.
move: n k v.
suff main : (forall (n m k : nat) (v : t nat (S m)) (h1 : m - k < S m)
(h2 : n - k < S n),
k <= n <= m->
nth_order (Sumation n v) h2 = nth_order v h1
+ Sum v).
move=> n k v.
have [klen | ngtk] := (Compare_dec.le_lt_dec k n).
rewrite (main n n k v); intuition.
by congr (nth _ _ + _); apply: Fin.of_nat_ext.
rewrite /nth_order /=.
rewrite (_ : Fin.of_nat_lt (kLess k n) = Fin.F1).
by move: (kLess k n); rewrite [n - k](_ : _ = 0) //; lia.
case: n v {ngtk} => //=.
move=> n v; rewrite /nth_order (_ : Fin.of_nat_lt _ = Fin.F1) //.
by move: (kLess (S n) (S n)); rewrite /= (Nat.sub_diag n).
elim => [ | n Ih] m k v h1 h2 [kle nle].
rewrite /= /nth_order /=.
congr (nth _ _ + _).
have k0 : k = 0 by lia.
move: (kLess 0 m) h1; rewrite k0 Nat.sub_0_r.
by apply: Fin.of_nat_ext.
rewrite /=.
have [nltSm | neqSm] := Compare_dec.le_lt_eq_dec _ _ kle.
rewrite /nth_order.
have [k' k'P] : exists k', S n - k = S k'.
exists (n - k); lia.
have h' : S k' < S (S n).
by lia.
have -> /= : Fin.of_nat_lt h2 = Fin.of_nat_lt h'.
move: h'; rewrite -k'P => h'.
by apply Fin.of_nat_ext.
move: (Lt.lt_S_n k' _ _) => {h'}h2.
have k'P2 : n - k = k' by lia.
rewrite -[LHS]/(nth_order (Sumation n v) h2).
move: h2; rewrite -k'P2=> h2.
rewrite Ih; first by lia.
by [].
rewrite /nth_order.
have -> /= : Fin.of_nat_lt h2 =
Fin.of_nat_lt (Nat.lt_0_succ (S n)).
move: h2; rewrite neqSm Nat.sub_diag; apply: Fin.of_nat_ext.
lia.
congr (nth _ _ + _).
by move: h1; rewrite neqSm; apply: Fin.of_nat_ext.
Qed.
我在Vnth_map
中找到了CoLoR.Util.Vector.VecUtil
。
如果我們重寫Sumation
並使用Vnth
將sumMap
添加到腳本中,我們可以輕松證明aaa
。
Require Import Psatz.
Require Import CoLoR.Util.Vector.VecUtil.
Definition kLess : forall (k P:nat), (P - k) < (S P).
intros. lia.
Defined.
Definition Sum {A}(v:vector nat A) :nat:= Vector.fold_right Nat.add v 0.
Definition partialSum {n} (v:vector nat n)(m:nat):nat:= m + (Sum v).
Definition Sumation {n} (v:vector nat n) := Vmap (partialSum v) v.
Lemma important {n}(k:nat)(v:vector nat (S n)): Vnth (Sumation v) (kLess k n) = (partialSum v) (Vnth v (kLess k n)).
Proof.
apply Vnth_map.
Qed.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.