Require
WhyArrays.
Require
Omega.
Set Implicit Arguments.
Inductive
exchange [A:Set; t,t':(array A); i,j:Z] : Prop :=
exchange_c :
(array_length t) = (array_length t') ->
`0 <= i < (array_length t)` -> `0 <= j < (array_length t)` ->
(#t[i] = #t'[j]) ->
(#t[j] = #t'[i]) ->
((k:Z)`0<=k<(array_length t)` -> `k<>i` -> `k<>j` -> #t[k] = #t'[k]) ->
(exchange t t' i j).
Lemma
exchange_1 : (A:Set)(t:(array A))
(i,j:Z) `0<=i<(array_length t)` -> `0<=j<(array_length t)` ->
(access (store (store t i #t[j]) j #t[i]) i) = #t[j].
Proof
.
Intros A t i j H_i H_j.
AccessStore j i H; WhyArrays; Auto with datatypes.
Save
.
Hints
Resolve exchange_1 : v62 datatypes.
Lemma
exchange_proof :
(A:Set)(t:(array A))
(i,j:Z) `0<=i<(array_length t)` -> `0<=j<(array_length t)` ->
(exchange (store (store t i (access t j)) j (access t i)) t i j).
Proof
.
Intros A t i j H_i H_j.
Apply exchange_c; WhyArrays; Auto with datatypes.
Intros k H_k not_k_i not_k_j.
Cut ~j=k; Auto with datatypes. Intro not_j_k.
AccessOther; Auto with datatypes.
Save
.
Hints
Resolve exchange_proof : v62 datatypes.
Lemma
exchange_sym :
(A:Set)(t,t':(array A))(i,j:Z)
(exchange t t' i j) -> (exchange t' t i j).
Proof
.
Intros A t t' i j H1.
Elim H1; Intro eq; Rewrite eq; Clear H1; Intros.
Constructor 1; Auto with datatypes.
Intros. Rewrite (H3 k); Auto with datatypes.
Save
.
Hints
Resolve exchange_sym : v62 datatypes.
Lemma
exchange_id :
(A:Set)(t,t':(array A))(i,j:Z)
(exchange t t' i j) ->
i=j ->
(k:Z) `0 <= k < (array_length t)` -> (access t k)=(access t' k).
Proof
.
Intros A t t' i j Hex Heq k Hk.
Elim Hex. Clear Hex. Intros.
Rewrite Heq in H2. Rewrite Heq in H3.
Case (Z_eq_dec k j).
Intro Heq'. Rewrite Heq'. Assumption.
Intro Hnoteq. Apply (H4 k); Auto with datatypes. Rewrite Heq. Assumption.
Save
.
Hints
Resolve exchange_id : v62 datatypes.
Lemma
exchange_length :
(A:Set)(t,t':(array A))(i,j:Z)
(exchange t t' i j) ->
(array_length t) = (array_length t').
Proof
.
Intros A t t' i j. Induction 1; Auto.
Save
.
Hints
Resolve exchange_length : v62 datatypes.
Inductive
permut [A:Set] : (array A)->(array A)->Prop :=
exchange_is_permut :
(t,t':(array A))(i,j:Z)(exchange t t' i j) -> (permut t t')
| permut_refl :
(t:(array A))(permut t t)
| permut_sym :
(t,t':(array A))(permut t t') -> (permut t' t)
| permut_trans :
(t,t',t'':(array A))
(permut t t') -> (permut t' t'') -> (permut t t'').
Hints
Resolve exchange_is_permut permut_refl permut_sym permut_trans : v62 datatypes.
Lemma
permut_length :
(t,t':(array Z))
(permut t t') ->
(array_length t) = (array_length t').
Proof
.
Intros t t'; Induction 1; Auto; Intros.
Elim H0; Auto.
Omega.
Save
.
Hints
Resolve permut_length : v62 datatypes.
Inductive
sub_permut [A:Set; g,d:Z] : (array A)->(array A)->Prop :=
exchange_is_sub_permut :
(t,t':(array A))(i,j:Z)`g <= i <= d` -> `g <= j <= d`
-> (exchange t t' i j) -> (sub_permut g d t t')
| sub_permut_refl :
(t:(array A))(sub_permut g d t t)
| sub_permut_sym :
(t,t':(array A))(sub_permut g d t t') -> (sub_permut g d t' t)
| sub_permut_trans :
(t,t',t'':(array A))
(sub_permut g d t t') -> (sub_permut g d t' t'')
-> (sub_permut g d t t'').
Hints
Resolve exchange_is_sub_permut sub_permut_refl sub_permut_sym sub_permut_trans
: v62 datatypes.
Lemma
sub_permut_length :
(A:Set)(t,t':(array A))(g,d:Z)
(sub_permut g d t t') ->
(array_length t) = (array_length t').
Proof
.
Intros t t' g d; Induction 1; Auto; Intros.
Elim H2; Auto.
Omega.
Save
.
Hints
Resolve sub_permut_length : v62 datatypes.
Lemma
sub_permut_function :
(A:Set)(t,t':(array A))(g,d:Z)
(sub_permut g d t t') ->
`0 <= g` -> `d < (array_length t)` ->
(i:Z) `g <= i <= d`
-> (EX j:Z | `g <= j <= d` /\ #t[i]=#t'[j])
/\ (EX j:Z | `g <= j <= d` /\ #t'[i]=#t[j]).
Proof
.
Intros A t t' g d.
Induction 1; Intros.
Elim H2; Intros.
Elim (Z_eq_dec i0 i); Intros.
Split ; [ Exists j | Exists j ].
Split; [ Assumption | Rewrite a; Assumption ].
Split; [ Assumption | Rewrite a; Symmetry; Assumption ].
Elim (Z_eq_dec i0 j); Intros.
Split ; [ Exists i | Exists i ].
Split; [ Assumption | Rewrite a; Assumption ].
Split; [ Assumption | Rewrite a; Symmetry; Assumption ].
Split ; [ Exists i0 | Exists i0 ].
Split; [ Assumption | Apply H11; Omega ].
Split; [ Assumption | Symmetry; Apply H11; Omega ].
Split ; [ Exists i | Exists i].
Split; [ Assumption | Trivial ].
Split; [ Assumption | Trivial ].
Rewrite <- (sub_permut_length H0) in H3.
Elim (H1 H2 H3 i); Auto.
Split.
Elim (H1 H4 H5 i). Intros.
Elim H7; Intros.
Elim H9; Intros.
Rewrite (sub_permut_length H0) in H5.
Elim (H3 H4 H5 x). Intros.
Elim H12; Intros.
Elim H14; Intros.
Exists x0. Split ; [ Assumption | Idtac ].
Transitivity (access t'0 x); Auto.
Auto.
Auto.
Rewrite (sub_permut_length H0) in H5.
Elim (H3 H4 H5 i). Intros.
Elim H8; Intros.
Elim H9; Intros.
Rewrite <- (sub_permut_length H0) in H5.
Elim (H1 H4 H5 x). Intros.
Elim H13; Intros.
Elim H14; Intros.
Exists x0. Split ; [ Assumption | Idtac ].
Transitivity (access t'0 x); Auto.
Auto.
Auto.
Save
.
Definition
array_id := [A:Set][t,t':(array A)][g,d:Z]
(i:Z) `g <= i <= d` -> #t[i] = #t'[i].
Lemma
array_id_refl :
(A:Set)(t:(array A))(g,d:Z)
(array_id t t g d).
Proof
.
Unfold array_id.
Auto with datatypes.
Save
.
Hints
Resolve array_id_refl : v62 datatypes.
Lemma
array_id_sym :
(A:Set)(t,t':(array A))(g,d:Z)
(array_id t t' g d)
-> (array_id t' t g d).
Proof
.
Unfold array_id. Intros.
Symmetry; Auto with datatypes.
Save
.
Hints
Resolve array_id_sym : v62 datatypes.
Lemma
array_id_trans :
(A:Set)(t,t',t'':(array A))(g,d:Z)
(array_id t t' g d)
-> (array_id t' t'' g d)
-> (array_id t t'' g d).
Proof
.
Unfold array_id. Intros.
Apply trans_eq with y:=#t'[i]; Auto with datatypes.
Save
.
Hints
Resolve array_id_trans: v62 datatypes.
Lemma
sub_permut_id :
(A:Set)(t,t':(array A))(g,d:Z)
(sub_permut g d t t') ->
(array_id t t' `0` `g-1`) /\
(array_id t t' `d+1` `(array_length t)-1`).
Proof
.
Intros A t t' g d. Induction 1; Intros.
Elim H2; Intros.
Unfold array_id; Split; Intros.
Apply H8; Omega.
Apply H8; Omega.
Auto with datatypes.
Rewrite <- (sub_permut_length H0).
Decompose [and] H1; Auto with datatypes.
Intuition.
Apply array_id_trans with t'0; Auto with datatypes.
Apply array_id_trans with t'0; Auto with datatypes.
Rewrite (sub_permut_length H0); Auto.
Save
.
Hints
Resolve sub_permut_id.
Lemma
sub_permut_eq :
(A:Set)(t,t':(array A))(g,d:Z)
(sub_permut g d t t') ->
(i:Z) (`0<=i<g` \/ `d<i<(array_length t)`) -> #t[i]=#t'[i].
Proof
.
Intros A t t' g d Htt' i Hi.
Elim (sub_permut_id Htt'). Unfold array_id.
Intros.
Elim Hi; [ Intro; Apply H; Omega | Intro; Apply H0; Omega ].
Save
.
Lemma
sub_permut_is_permut :
(A:Set)(t,t':(array A))(g,d:Z)
(sub_permut g d t t') ->
(permut t t').
Proof
.
Intros A t t' g d. Induction 1; Intros; EAuto with datatypes.
Save
.
Hints
Resolve sub_permut_is_permut.
Lemma
sub_permut_void :
(A:Set)(t,t':(array A))
(g,g',d,d':Z) `d < g`
-> (sub_permut g d t t') -> (sub_permut g' d' t t').
Proof
.
Intros A t t' g g' d d' Hdg.
(Induction 1; Intros).
(Absurd `g <= d`; Omega).
Auto with datatypes.
Auto with datatypes.
EAuto with datatypes.
Save
.
Lemma
sub_permut_extension :
(A:Set)(t,t':(array A))
(g,g',d,d':Z) `g' <= g` -> `d <= d'`
-> (sub_permut g d t t') -> (sub_permut g' d' t t').
Proof
.
Intros A t t' g g' d d' Hgg' Hdd'.
(Induction 1; Intros).
Apply exchange_is_sub_permut with i:=i j:=j; [ Omega | Omega | Assumption ].
Auto with datatypes.
Auto with datatypes.
EAuto with datatypes.
Save
.