mirror of
https://github.com/msgpack/msgpack-c.git
synced 2025-03-20 05:27:56 +01:00
334 lines
7.3 KiB
Coq
334 lines
7.3 KiB
Coq
(*
|
|
16bits,32bits,64bitsの定義。BigEndian。
|
|
*)
|
|
Require Import List Ascii NArith Omega Euclid.
|
|
Require Import Pow.
|
|
|
|
Open Scope char_scope.
|
|
|
|
(* * 型の定義 *)
|
|
Definition ascii8 : Set := ascii.
|
|
Definition ascii16 : Set := (ascii8 * ascii8)%type.
|
|
Definition ascii32 : Set := (ascii16 * ascii16)%type.
|
|
Definition ascii64 : Set := (ascii32 * ascii32)%type.
|
|
|
|
(** ** natとの相互変換 *)
|
|
Definition nat_of_ascii8 :=
|
|
nat_of_ascii.
|
|
|
|
Definition ascii8_of_nat :=
|
|
ascii_of_nat.
|
|
|
|
Definition ascii16_of_nat (a : nat) :=
|
|
let (q,r,_,_) := divmod a (pow 8) (pow_lt_O 8) in
|
|
(ascii8_of_nat q, ascii8_of_nat r).
|
|
|
|
Definition nat_of_ascii16 (a : ascii16) :=
|
|
let (a1, a2) := a in
|
|
(nat_of_ascii8 a1) * (pow 8) + (nat_of_ascii8 a2).
|
|
|
|
Definition ascii32_of_nat (a : nat) :=
|
|
let (q,r,_,_) := divmod a (pow 16) (pow_lt_O 16) in
|
|
(ascii16_of_nat q, ascii16_of_nat r).
|
|
|
|
Definition nat_of_ascii32 (a : ascii32) :=
|
|
let (a1, a2) := a in
|
|
(nat_of_ascii16 a1) * (pow 16) + (nat_of_ascii16 a2).
|
|
|
|
Definition ascii64_of_nat (a : nat) :=
|
|
let (q,r,_,_) := divmod a (pow 32) (pow_lt_O 32) in
|
|
(ascii32_of_nat q, ascii32_of_nat r).
|
|
|
|
Definition nat_of_ascii64 (a : ascii64) :=
|
|
let (a1, a2) := a in
|
|
(nat_of_ascii32 a1) * (pow 32) + (nat_of_ascii32 a2).
|
|
|
|
(** ** natに戻せることの証明 *)
|
|
Lemma nat_ascii8_embedding : forall n,
|
|
n < pow 8 ->
|
|
nat_of_ascii8 (ascii8_of_nat n) = n.
|
|
Proof.
|
|
intros.
|
|
unfold nat_of_ascii8,ascii8_of_nat.
|
|
rewrite nat_ascii_embedding.
|
|
reflexivity.
|
|
|
|
simpl in H.
|
|
assumption.
|
|
Qed.
|
|
|
|
Lemma nat_ascii16_embedding : forall n,
|
|
n < pow 16 ->
|
|
nat_of_ascii16 (ascii16_of_nat n) = n.
|
|
Proof.
|
|
intros.
|
|
unfold ascii16_of_nat, nat_of_ascii16.
|
|
destruct divmod.
|
|
rewrite (nat_ascii8_embedding q), (nat_ascii8_embedding r); try omega.
|
|
apply divmod_lt_q with (t := 8) in e;
|
|
change (8+8) with 16; assumption.
|
|
Qed.
|
|
|
|
Lemma nat_ascii32_embedding : forall n,
|
|
n < pow 32 ->
|
|
nat_of_ascii32 (ascii32_of_nat n) = n.
|
|
Proof.
|
|
intros.
|
|
unfold ascii32_of_nat, nat_of_ascii32.
|
|
destruct divmod.
|
|
rewrite (nat_ascii16_embedding q), (nat_ascii16_embedding r); try omega.
|
|
apply divmod_lt_q with (t := 16) in e;
|
|
change (16+16) with 32; assumption.
|
|
Qed.
|
|
|
|
Lemma nat_ascii64_embedding : forall n,
|
|
n < pow 64 ->
|
|
nat_of_ascii64 (ascii64_of_nat n) = n.
|
|
Proof.
|
|
intros.
|
|
unfold ascii64_of_nat, nat_of_ascii64.
|
|
destruct divmod.
|
|
rewrite (nat_ascii32_embedding q), (nat_ascii32_embedding r); try omega.
|
|
apply divmod_lt_q with (t := 32) in e;
|
|
change (32+32) with 64; assumption.
|
|
Qed.
|
|
|
|
(** ** ascii8への変換 *)
|
|
Definition list_of_ascii8 (x : ascii8) :=
|
|
x :: nil.
|
|
|
|
Definition list_of_ascii16 (p : ascii16) :=
|
|
match p with
|
|
(x1,x2) => (list_of_ascii8 x1) ++ (list_of_ascii8 x2)
|
|
end.
|
|
|
|
Definition list_of_ascii32 (p : ascii32) :=
|
|
match p with
|
|
(x1,x2) => (list_of_ascii16 x1) ++ (list_of_ascii16 x2)
|
|
end.
|
|
|
|
Definition list_of_ascii64 (p : ascii64) :=
|
|
match p with
|
|
(x1,x2) => (list_of_ascii32 x1) ++ (list_of_ascii32 x2)
|
|
end.
|
|
|
|
Lemma list_of_ascii8_eq : forall c1 c2,
|
|
list_of_ascii8 c1 = list_of_ascii8 c2 ->
|
|
c1 = c2.
|
|
Proof.
|
|
intros.
|
|
unfold list_of_ascii8 in H.
|
|
inversion H.
|
|
reflexivity.
|
|
Qed.
|
|
|
|
Lemma list_of_ascii16_eq : forall c1 c2,
|
|
list_of_ascii16 c1 = list_of_ascii16 c2 ->
|
|
c1 = c2.
|
|
Proof.
|
|
intros.
|
|
destruct c1; destruct c2.
|
|
inversion H.
|
|
reflexivity.
|
|
Qed.
|
|
|
|
Lemma list_of_ascii32_eq : forall c1 c2,
|
|
list_of_ascii32 c1 = list_of_ascii32 c2 ->
|
|
c1 = c2.
|
|
Proof.
|
|
intros.
|
|
destruct c1; destruct c2.
|
|
destruct a; destruct a0; destruct a1; destruct a2.
|
|
inversion H.
|
|
reflexivity.
|
|
Qed.
|
|
|
|
Lemma list_of_ascii64_eq : forall c1 c2,
|
|
list_of_ascii64 c1 = list_of_ascii64 c2 ->
|
|
c1 = c2.
|
|
Proof.
|
|
intros.
|
|
destruct c1; destruct c2.
|
|
destruct a; destruct a0; destruct a1; destruct a2.
|
|
destruct a; destruct a3; destruct a0; destruct a4;
|
|
destruct a1; destruct a5; destruct a2; destruct a6.
|
|
inversion H.
|
|
reflexivity.
|
|
Qed.
|
|
|
|
(** 0でないことの証明 *)
|
|
Lemma ascii8_not_O: forall n,
|
|
0 < n < pow 8 ->
|
|
"000" <> ascii8_of_nat n.
|
|
Proof.
|
|
intros.
|
|
destruct H.
|
|
apply nat_ascii8_embedding in H0.
|
|
destruct (ascii8_of_nat n).
|
|
intro.
|
|
destruct b; destruct b0; destruct b1; destruct b2; destruct b3; destruct b4; destruct b5; destruct b6; inversion H1.
|
|
compute in H0.
|
|
rewrite <- H0 in H.
|
|
inversion H.
|
|
Qed.
|
|
|
|
Lemma ascii16_not_O: forall n,
|
|
0 < n < pow 16 ->
|
|
("000","000") <> ascii16_of_nat n.
|
|
Proof.
|
|
intros.
|
|
unfold ascii16_of_nat.
|
|
destruct divmod.
|
|
destruct H.
|
|
intro.
|
|
inversion H1.
|
|
generalize e; intro.
|
|
apply divmod_not_O in e; auto with pow.
|
|
decompose [or] e.
|
|
apply ascii8_not_O in H3; auto.
|
|
apply divmod_lt_q with (t:=8) in e0; auto with pow.
|
|
|
|
apply ascii8_not_O in H4; auto with pow.
|
|
Qed.
|
|
|
|
Lemma ascii32_not_O: forall n,
|
|
0 < n < pow 32 ->
|
|
("000","000",("000","000")) <> ascii32_of_nat n.
|
|
Proof.
|
|
intros.
|
|
unfold ascii32_of_nat.
|
|
destruct divmod.
|
|
destruct H.
|
|
intro.
|
|
inversion H1.
|
|
generalize e; intro.
|
|
apply divmod_not_O in e.
|
|
decompose [or] e.
|
|
apply divmod_lt_q with (t:=16) in e0.
|
|
apply ascii16_not_O in H3.
|
|
contradiction.
|
|
|
|
split; assumption.
|
|
|
|
assumption.
|
|
|
|
exact H0.
|
|
|
|
apply ascii16_not_O in H4.
|
|
contradiction.
|
|
|
|
split; assumption.
|
|
|
|
assumption.
|
|
|
|
apply pow_lt_O.
|
|
Qed.
|
|
|
|
(* ** 2^n未満なら等価性が変らないことの証明 *)
|
|
Lemma ascii8_of_nat_eq : forall n m,
|
|
n < pow 8 ->
|
|
m < pow 8 ->
|
|
ascii8_of_nat n = ascii8_of_nat m ->
|
|
n = m.
|
|
Proof.
|
|
intros.
|
|
rewrite <- (nat_ascii8_embedding n), <- (nat_ascii8_embedding m), <- H1; auto.
|
|
Qed.
|
|
|
|
Lemma ascii16_of_nat_eq : forall n m,
|
|
n < pow 16 ->
|
|
m < pow 16 ->
|
|
ascii16_of_nat n = ascii16_of_nat m ->
|
|
n = m.
|
|
Proof.
|
|
intros.
|
|
rewrite <- (nat_ascii16_embedding n), <- (nat_ascii16_embedding m), <- H1; auto.
|
|
Qed.
|
|
|
|
Lemma ascii32_of_nat_eq : forall n m,
|
|
n < pow 32 ->
|
|
m < pow 32 ->
|
|
ascii32_of_nat n = ascii32_of_nat m ->
|
|
n = m.
|
|
Proof.
|
|
intros.
|
|
rewrite <- (nat_ascii32_embedding n), <- (nat_ascii32_embedding m), <- H1; auto.
|
|
Qed.
|
|
|
|
Lemma ascii8_of_nat_O:
|
|
"000" = ascii8_of_nat 0.
|
|
Proof.
|
|
compute.
|
|
reflexivity.
|
|
Qed.
|
|
|
|
Lemma ascii16_of_nat_O:
|
|
("000", "000") = ascii16_of_nat 0.
|
|
Proof.
|
|
unfold ascii16_of_nat.
|
|
destruct divmod.
|
|
apply divmod_O_pow in e.
|
|
decompose [and] e.
|
|
rewrite H, H0.
|
|
rewrite <- ascii8_of_nat_O.
|
|
reflexivity.
|
|
Qed.
|
|
|
|
Lemma ascii32_of_nat_O:
|
|
(("000", "000"),("000","000")) = ascii32_of_nat 0.
|
|
Proof.
|
|
unfold ascii32_of_nat.
|
|
destruct divmod.
|
|
apply divmod_O_pow in e.
|
|
decompose [and] e.
|
|
rewrite H, H0.
|
|
rewrite <- ascii16_of_nat_O.
|
|
reflexivity.
|
|
Qed.
|
|
|
|
(* lengthが等しいことの証明 *)
|
|
Lemma ascii8_length : forall c1 c2,
|
|
length (list_of_ascii8 c1) = length (list_of_ascii8 c2).
|
|
Proof.
|
|
auto.
|
|
Qed.
|
|
|
|
Lemma ascii16_length : forall c1 c2,
|
|
length (list_of_ascii16 c1) = length (list_of_ascii16 c2).
|
|
Proof.
|
|
destruct c1,c2.
|
|
auto.
|
|
Qed.
|
|
|
|
Lemma ascii32_length : forall c1 c2,
|
|
length (list_of_ascii32 c1) = length (list_of_ascii32 c2).
|
|
Proof.
|
|
destruct c1 as [a1 a2] ,c2 as [a3 a4].
|
|
destruct a1,a2,a3,a4.
|
|
auto.
|
|
Qed.
|
|
|
|
Lemma ascii64_length : forall c1 c2,
|
|
length (list_of_ascii64 c1) = length (list_of_ascii64 c2).
|
|
Proof.
|
|
destruct c1 as [a1 a2] ,c2 as [a3 a4].
|
|
destruct a1 as [b1 b2], a2 as [b3 b4], a3 as [b5 b6], a4 as [b7 b8].
|
|
destruct b1,b2,b3,b4,b5,b6,b7,b8.
|
|
auto.
|
|
Qed.
|
|
|
|
Lemma ascii5 : forall n b1 b2 b3 b4 b5 b6 b7 b8,
|
|
n < pow 5 ->
|
|
Ascii b1 b2 b3 b4 b5 b6 b7 b8 = ascii8_of_nat n ->
|
|
b6 = false /\ b7 = false /\ b8 = false.
|
|
Proof.
|
|
intros.
|
|
simpl in H.
|
|
do 32 (destruct n; [ inversion H0; auto | idtac]).
|
|
do 32 (apply Lt.lt_S_n in H).
|
|
inversion H.
|
|
Qed.
|
|
|
|
Hint Resolve ascii16_length ascii32_length ascii64_length
|
|
list_of_ascii8_eq list_of_ascii16_eq list_of_ascii32_eq list_of_ascii64_eq
|
|
: ascii. |