aboutsummaryrefslogtreecommitdiffstats
path: root/src/hls/Memorygen.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/hls/Memorygen.v')
-rw-r--r--src/hls/Memorygen.v3201
1 files changed, 0 insertions, 3201 deletions
diff --git a/src/hls/Memorygen.v b/src/hls/Memorygen.v
deleted file mode 100644
index 34e264d..0000000
--- a/src/hls/Memorygen.v
+++ /dev/null
@@ -1,3201 +0,0 @@
-(*
- * Vericert: Verified high-level synthesis.
- * Copyright (C) 2021 Yann Herklotz <yann@yannherklotz.com>
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- *)
-
-Require Import Coq.micromega.Lia.
-
-Require Import compcert.backend.Registers.
-Require Import compcert.common.AST.
-Require Import compcert.common.Globalenvs.
-Require compcert.common.Memory.
-Require Import compcert.common.Values.
-Require Import compcert.lib.Floats.
-Require Import compcert.lib.Integers.
-Require Import compcert.lib.Maps.
-Require compcert.common.Smallstep.
-Require compcert.verilog.Op.
-
-Require Import vericert.common.Vericertlib.
-Require Import vericert.hls.ValueInt.
-Require Import vericert.hls.Verilog.
-Require Import vericert.hls.HTL.
-Require Import vericert.hls.AssocMap.
-Require Import vericert.hls.Array.
-
-Local Open Scope positive.
-Local Open Scope assocmap.
-
-#[local] Hint Resolve max_reg_stmnt_le_stmnt_tree : mgen.
-#[local] Hint Resolve max_reg_stmnt_lt_stmnt_tree : mgen.
-#[local] Hint Resolve max_stmnt_lt_module : mgen.
-
-Lemma int_eq_not_false : forall x, Int.eq x (Int.not x) = false.
-Proof.
- intros. unfold Int.eq.
- rewrite Int.unsigned_not.
- replace Int.max_unsigned with 4294967295%Z by crush.
- assert (X: forall x, (x <> 4294967295 - x)%Z) by lia.
- specialize (X (Int.unsigned x)). apply zeq_false; auto.
-Qed.
-
-Definition transf_maps state ram in_ (dc: PTree.t stmnt * PTree.t stmnt) :=
- match dc, in_ with
- | (d, c), (i, n) =>
- match PTree.get i d, PTree.get i c with
- | Some (Vnonblock (Vvari r e1) e2), Some c_s =>
- if r =? (ram_mem ram) then
- let nd := Vseq (Vnonblock (Vvar (ram_u_en ram)) (Vunop Vnot (Vvar (ram_u_en ram))))
- (Vseq (Vnonblock (Vvar (ram_wr_en ram)) (Vlit (ZToValue 1)))
- (Vseq (Vnonblock (Vvar (ram_d_in ram)) e2)
- (Vnonblock (Vvar (ram_addr ram)) e1)))
- in
- (PTree.set i nd d, c)
- else dc
- | Some (Vnonblock (Vvar e1) (Vvari r e2)), Some (Vnonblock (Vvar st') e3) =>
- if (r =? (ram_mem ram)) && (st' =? state) && (Z.pos n <=? Int.max_unsigned)%Z
- && (e1 <? state) && (max_reg_expr e2 <? state) && (max_reg_expr e3 <? state)
- then
- let nd :=
- Vseq (Vnonblock (Vvar (ram_u_en ram)) (Vunop Vnot (Vvar (ram_u_en ram))))
- (Vseq (Vnonblock (Vvar (ram_wr_en ram)) (Vlit (ZToValue 0)))
- (Vnonblock (Vvar (ram_addr ram)) e2))
- in
- let aout := Vnonblock (Vvar e1) (Vvar (ram_d_out ram)) in
- let redirect := Vnonblock (Vvar state) (Vlit (posToValue n)) in
- (PTree.set i nd (PTree.set n aout d),
- PTree.set i redirect (PTree.set n (Vnonblock (Vvar st') e3) c))
- else dc
- | _, _ => dc
- end
- end.
-
-Lemma transf_maps_wf :
- forall state ram d c d' c' i,
- map_well_formed c /\ map_well_formed d ->
- transf_maps state ram i (d, c) = (d', c') ->
- map_well_formed c' /\ map_well_formed d'.
-Proof.
- unfold transf_maps; intros; repeat destruct_match;
- match goal with
- | H: (_, _) = (_, _) |- _ => inv H
- end; auto.
- unfold map_well_formed.
- simplify; intros.
- destruct (Pos.eq_dec p0 p1); subst; auto.
- destruct (Pos.eq_dec p p1); subst. unfold map_well_formed in *.
- apply AssocMap.elements_correct in Heqo.
- eapply in_map with (f := fst) in Heqo. simplify.
- apply H1 in Heqo. auto.
- apply AssocMapExt.elements_iff in H3. inv H3.
- repeat rewrite AssocMap.gso in H8 by lia.
- apply AssocMap.elements_correct in H8.
- eapply in_map with (f := fst) in H8. simplify.
- unfold map_well_formed in *. apply H0 in H8. auto.
- apply AssocMapExt.elements_iff in H3. inv H3.
- destruct (Pos.eq_dec p0 p1); subst; auto.
- destruct (Pos.eq_dec p p1); subst. unfold map_well_formed in *.
- apply AssocMap.elements_correct in Heqo.
- eapply in_map with (f := fst) in Heqo. simplify.
- apply H1 in Heqo. auto.
- repeat rewrite AssocMap.gso in H8 by lia.
- apply AssocMap.elements_correct in H8.
- eapply in_map with (f := fst) in H8. simplify.
- unfold map_well_formed in *. apply H1 in H8. auto.
- unfold map_well_formed in *; simplify; intros.
- destruct (Pos.eq_dec p0 p1); subst; auto.
- destruct (Pos.eq_dec p p1); subst. unfold map_well_formed in *.
- apply AssocMap.elements_correct in Heqo.
- eapply in_map with (f := fst) in Heqo. simplify.
- apply H1 in Heqo. auto.
- apply AssocMapExt.elements_iff in H. inv H.
- repeat rewrite AssocMap.gso in H2 by lia.
- apply AssocMap.elements_correct in H2.
- eapply in_map with (f := fst) in H2. simplify.
- unfold map_well_formed in *. apply H1 in H2. auto.
-Qed.
-
-Definition max_pc {A: Type} (m: PTree.t A) :=
- fold_right Pos.max 1%positive (map fst (PTree.elements m)).
-
-Fixpoint zip_range {A: Type} n (l: list A) {struct l} :=
- match l with
- | nil => nil
- | a :: b => (a, n) :: zip_range (n+1) b
- end.
-
-Lemma zip_range_fst_idem : forall A (l: list A) a, map fst (zip_range a l) = l.
-Proof. induction l; crush. Qed.
-
-Lemma zip_range_not_in_snd :
- forall A (l: list A) a n, a < n -> ~ In a (map snd (zip_range n l)).
-Proof.
- unfold not; induction l; crush.
- inv H0; try lia. eapply IHl.
- assert (X: a0 < n + 1) by lia. apply X; auto. auto.
-Qed.
-
-Lemma zip_range_snd_no_repet :
- forall A (l: list A) a, list_norepet (map snd (zip_range a l)).
-Proof.
- induction l; crush; constructor; auto; [].
- apply zip_range_not_in_snd; lia.
-Qed.
-
-Lemma zip_range_in :
- forall A (l: list A) a n i, In (a, i) (zip_range n l) -> In a l.
-Proof.
- induction l; crush. inv H. inv H0. auto. right. eapply IHl; eauto.
-Qed.
-
-Lemma zip_range_not_in :
- forall A (l: list A) a i n, ~ In a l -> ~ In (a, i) (zip_range n l).
-Proof.
- unfold not; induction l; crush. inv H0. inv H1. apply H. left. auto.
- apply H. right. eapply zip_range_in; eauto.
-Qed.
-
-Lemma zip_range_no_repet :
- forall A (l: list A) a, list_norepet l -> list_norepet (zip_range a l).
-Proof.
- induction l; simplify; constructor;
- match goal with H: list_norepet _ |- _ => inv H end;
- [apply zip_range_not_in|]; auto.
-Qed.
-
-Definition transf_code state ram d c :=
- fold_right (transf_maps state ram) (d, c)
- (zip_range (Pos.max (max_pc c) (max_pc d) + 1)
- (map fst (PTree.elements d))).
-
-Lemma transf_code_wf' :
- forall l c d state ram c' d',
- map_well_formed c /\ map_well_formed d ->
- fold_right (transf_maps state ram) (d, c) l = (d', c') ->
- map_well_formed c' /\ map_well_formed d'.
-Proof.
- induction l; intros; simpl in *. inv H0; auto.
- remember (fold_right (transf_maps state ram) (d, c) l). destruct p.
- apply transf_maps_wf in H0. auto. eapply IHl; eauto.
-Qed.
-
-Lemma transf_code_wf :
- forall c d state ram c' d',
- map_well_formed c /\ map_well_formed d ->
- transf_code state ram d c = (d', c') ->
- map_well_formed c' /\ map_well_formed d'.
-Proof. eauto using transf_code_wf'. Qed.
-
-Lemma ram_wf :
- forall x,
- x + 1 < x + 2 /\ x + 2 < x + 3 /\ x + 3 < x + 4 /\ x + 4 < x + 5 /\ x + 5 < x + 6.
-Proof. lia. Qed.
-
-Lemma module_ram_wf' :
- forall m addr,
- addr = max_reg_module m + 1 ->
- mod_clk m < addr.
-Proof. unfold max_reg_module; lia. Qed.
-
-Definition transf_module (m: module): module.
- refine (
- let max_reg := max_reg_module m in
- let addr := max_reg+1 in
- let en := max_reg+2 in
- let d_in := max_reg+3 in
- let d_out := max_reg+4 in
- let wr_en := max_reg+5 in
- let u_en := max_reg+6 in
- let new_size := (mod_stk_len m) in
- let ram := mk_ram new_size (mod_stk m) en u_en addr wr_en d_in d_out ltac:(eauto using ram_wf) in
- let tc := transf_code (mod_st m) ram (mod_datapath m) (mod_controllogic m) in
- match mod_ram m with
- | None =>
- mkmodule m.(mod_params)
- (fst tc)
- (snd tc)
- (mod_entrypoint m)
- (mod_st m)
- (mod_stk m)
- (mod_stk_len m)
- (mod_finish m)
- (mod_return m)
- (mod_start m)
- (mod_reset m)
- (mod_clk m)
- (AssocMap.set u_en (None, VScalar 1)
- (AssocMap.set en (None, VScalar 1)
- (AssocMap.set wr_en (None, VScalar 1)
- (AssocMap.set d_out (None, VScalar 32)
- (AssocMap.set d_in (None, VScalar 32)
- (AssocMap.set addr (None, VScalar 32) m.(mod_scldecls)))))))
- (AssocMap.set m.(mod_stk)
- (None, VArray 32 (2 ^ Nat.log2_up new_size))%nat m.(mod_arrdecls))
- (Some ram)
- _ (mod_ordering_wf m) _ (mod_params_wf m)
- | _ => m
- end).
- eapply transf_code_wf. apply (mod_wf m). destruct tc eqn:?; simpl.
- rewrite <- Heqp. intuition.
- inversion 1; subst. auto using module_ram_wf'.
-Defined.
-
-Definition transf_fundef := transf_fundef transf_module.
-
-Definition transf_program (p : program) :=
- transform_program transf_fundef p.
-
-Inductive match_assocmaps : positive -> assocmap -> assocmap -> Prop :=
- match_assocmap: forall p rs rs',
- (forall r, r < p -> rs!r = rs'!r) ->
- match_assocmaps p rs rs'.
-
-Inductive match_arrs : assocmap_arr -> assocmap_arr -> Prop :=
-| match_assocmap_arr_intro: forall ar ar',
- (forall s arr,
- ar ! s = Some arr ->
- exists arr',
- ar' ! s = Some arr'
- /\ (forall addr,
- array_get_error addr arr = array_get_error addr arr')
- /\ arr_length arr = arr_length arr')%nat ->
- (forall s, ar ! s = None -> ar' ! s = None) ->
- match_arrs ar ar'.
-
-Inductive match_arrs_size : assocmap_arr -> assocmap_arr -> Prop :=
- match_arrs_size_intro :
- forall nasa basa,
- (forall s arr,
- nasa ! s = Some arr ->
- exists arr',
- basa ! s = Some arr' /\ arr_length arr = arr_length arr') ->
- (forall s arr,
- basa ! s = Some arr ->
- exists arr',
- nasa ! s = Some arr' /\ arr_length arr = arr_length arr') ->
- (forall s, basa ! s = None <-> nasa ! s = None) ->
- match_arrs_size nasa basa.
-
-Definition match_empty_size (m : module) (ar : assocmap_arr) : Prop :=
- match_arrs_size (empty_stack m) ar.
-#[local] Hint Unfold match_empty_size : mgen.
-
-Definition disable_ram (ram: option ram) (asr : assocmap_reg) : Prop :=
- match ram with
- | Some r => Int.eq (asr # ((ram_en r), 32)) (asr # ((ram_u_en r), 32)) = true
- | None => True
- end.
-
-Inductive match_stackframes : stackframe -> stackframe -> Prop :=
- match_stackframe_intro :
- forall r m pc asr asa asr' asa'
- (DISABLE_RAM: disable_ram (mod_ram (transf_module m)) asr')
- (MATCH_ASSOC: match_assocmaps (max_reg_module m + 1) asr asr')
- (MATCH_ARRS: match_arrs asa asa')
- (MATCH_EMPT1: match_empty_size m asa)
- (MATCH_EMPT2: match_empty_size m asa')
- (MATCH_RES: r < mod_st m),
- match_stackframes (Stackframe r m pc asr asa)
- (Stackframe r (transf_module m) pc asr' asa').
-
-Inductive match_states : state -> state -> Prop :=
-| match_state :
- forall res res' m st asr asr' asa asa'
- (ASSOC: match_assocmaps (max_reg_module m + 1) asr asr')
- (ARRS: match_arrs asa asa')
- (STACKS: list_forall2 match_stackframes res res')
- (ARRS_SIZE: match_empty_size m asa)
- (ARRS_SIZE2: match_empty_size m asa')
- (DISABLE_RAM: disable_ram (mod_ram (transf_module m)) asr'),
- match_states (State res m st asr asa)
- (State res' (transf_module m) st asr' asa')
-| match_returnstate :
- forall res res' i
- (STACKS: list_forall2 match_stackframes res res'),
- match_states (Returnstate res i) (Returnstate res' i)
-| match_initial_call :
- forall m,
- match_states (Callstate nil m nil)
- (Callstate nil (transf_module m) nil).
-#[local] Hint Constructors match_states : htlproof.
-
-Definition empty_stack_ram r :=
- AssocMap.set (ram_mem r) (Array.arr_repeat None (ram_size r)) (AssocMap.empty arr).
-
-Definition empty_stack' len st :=
- AssocMap.set st (Array.arr_repeat None len) (AssocMap.empty arr).
-
-Definition match_empty_size' l s (ar : assocmap_arr) : Prop :=
- match_arrs_size (empty_stack' l s) ar.
-#[local] Hint Unfold match_empty_size : mgen.
-
-Definition merge_reg_assocs r :=
- Verilog.mkassociations (Verilog.merge_regs (assoc_nonblocking r) (assoc_blocking r)) empty_assocmap.
-
-Definition merge_arr_assocs st len r :=
- Verilog.mkassociations (Verilog.merge_arrs (assoc_nonblocking r) (assoc_blocking r)) (empty_stack' len st).
-
-Inductive match_reg_assocs : positive -> reg_associations -> reg_associations -> Prop :=
- match_reg_association:
- forall p rab rab' ran ran',
- match_assocmaps p rab rab' ->
- match_assocmaps p ran ran' ->
- match_reg_assocs p (mkassociations rab ran) (mkassociations rab' ran').
-
-Inductive match_arr_assocs : arr_associations -> arr_associations -> Prop :=
- match_arr_association:
- forall rab rab' ran ran',
- match_arrs rab rab' ->
- match_arrs ran ran' ->
- match_arr_assocs (mkassociations rab ran) (mkassociations rab' ran').
-
-Ltac mgen_crush := crush; eauto with mgen.
-
-Lemma match_assocmaps_equiv : forall p a, match_assocmaps p a a.
-Proof. constructor; auto. Qed.
-#[local] Hint Resolve match_assocmaps_equiv : mgen.
-
-Lemma match_arrs_equiv : forall a, match_arrs a a.
-Proof. econstructor; mgen_crush. Qed.
-#[local] Hint Resolve match_arrs_equiv : mgen.
-
-Lemma match_reg_assocs_equiv : forall p a, match_reg_assocs p a a.
-Proof. destruct a; constructor; mgen_crush. Qed.
-#[local] Hint Resolve match_reg_assocs_equiv : mgen.
-
-Lemma match_arr_assocs_equiv : forall a, match_arr_assocs a a.
-Proof. destruct a; constructor; mgen_crush. Qed.
-#[local] Hint Resolve match_arr_assocs_equiv : mgen.
-
-Lemma match_arrs_size_equiv : forall a, match_arrs_size a a.
-Proof. intros; repeat econstructor; eauto. Qed.
-#[local] Hint Resolve match_arrs_size_equiv : mgen.
-
-Lemma match_stacks_equiv :
- forall m s l,
- mod_stk m = s ->
- mod_stk_len m = l ->
- empty_stack' l s = empty_stack m.
-Proof. unfold empty_stack', empty_stack; mgen_crush. Qed.
-#[local] Hint Rewrite match_stacks_equiv : mgen.
-
-Lemma match_assocmaps_max1 :
- forall p p' a b,
- match_assocmaps (Pos.max p' p) a b ->
- match_assocmaps p a b.
-Proof.
- intros. inv H. constructor. intros.
- apply H0. lia.
-Qed.
-#[local] Hint Resolve match_assocmaps_max1 : mgen.
-
-Lemma match_assocmaps_max2 :
- forall p p' a b,
- match_assocmaps (Pos.max p p') a b ->
- match_assocmaps p a b.
-Proof.
- intros. inv H. constructor. intros.
- apply H0. lia.
-Qed.
-#[local] Hint Resolve match_assocmaps_max2 : mgen.
-
-Lemma match_assocmaps_ge :
- forall p p' a b,
- match_assocmaps p' a b ->
- p <= p' ->
- match_assocmaps p a b.
-Proof.
- intros. inv H. constructor. intros.
- apply H1. lia.
-Qed.
-#[local] Hint Resolve match_assocmaps_ge : mgen.
-
-Lemma match_reg_assocs_max1 :
- forall p p' a b,
- match_reg_assocs (Pos.max p' p) a b ->
- match_reg_assocs p a b.
-Proof. intros; inv H; econstructor; mgen_crush. Qed.
-#[local] Hint Resolve match_reg_assocs_max1 : mgen.
-
-Lemma match_reg_assocs_max2 :
- forall p p' a b,
- match_reg_assocs (Pos.max p p') a b ->
- match_reg_assocs p a b.
-Proof. intros; inv H; econstructor; mgen_crush. Qed.
-#[local] Hint Resolve match_reg_assocs_max2 : mgen.
-
-Lemma match_reg_assocs_ge :
- forall p p' a b,
- match_reg_assocs p' a b ->
- p <= p' ->
- match_reg_assocs p a b.
-Proof. intros; inv H; econstructor; mgen_crush. Qed.
-#[local] Hint Resolve match_reg_assocs_ge : mgen.
-
-Definition forall_ram (P: reg -> Prop) ram :=
- P (ram_en ram)
- /\ P (ram_u_en ram)
- /\ P (ram_addr ram)
- /\ P (ram_wr_en ram)
- /\ P (ram_d_in ram)
- /\ P (ram_d_out ram).
-
-Lemma forall_ram_lt :
- forall m r,
- (mod_ram m) = Some r ->
- forall_ram (fun x => x < max_reg_module m + 1) r.
-Proof.
- assert (X: forall a b c, a < b + 1 -> a < Pos.max c b + 1) by lia.
- unfold forall_ram; simplify; unfold HTL.max_reg_module; repeat apply X;
- unfold HTL.max_reg_ram; rewrite H; try lia.
-Qed.
-#[local] Hint Resolve forall_ram_lt : mgen.
-
-Definition exec_all d_s c_s rs1 ar1 rs3 ar3 :=
- exists f rs2 ar2,
- stmnt_runp f rs1 ar1 c_s rs2 ar2
- /\ stmnt_runp f rs2 ar2 d_s rs3 ar3.
-
-Definition exec_all_ram r d_s c_s rs1 ar1 rs4 ar4 :=
- exists f rs2 ar2 rs3 ar3,
- stmnt_runp f rs1 ar1 c_s rs2 ar2
- /\ stmnt_runp f rs2 ar2 d_s rs3 ar3
- /\ exec_ram (merge_reg_assocs rs3) (merge_arr_assocs (ram_mem r) (ram_size r) ar3) (Some r) rs4 ar4.
-
-(* Lemma merge_reg_idempotent : *)
-(* forall rs p, *)
-(* match_reg_assocs p (merge_reg_assocs (merge_reg_assocs rs)) (merge_reg_assocs rs). *)
-(* Proof. intros. unfold merge_reg_assocs. cbn. unfold merge_regs. *)
-(* #[global] Hint Rewrite merge_reg_idempotent : mgen. *)
-
-Lemma merge_arr_idempotent :
- forall ar st len v v',
- (assoc_nonblocking ar)!st = Some v ->
- (assoc_blocking ar)!st = Some v' ->
- arr_length v' = len ->
- arr_length v = len ->
- (assoc_blocking (merge_arr_assocs st len (merge_arr_assocs st len ar)))!st
- = (assoc_blocking (merge_arr_assocs st len ar))!st
- /\ (assoc_nonblocking (merge_arr_assocs st len (merge_arr_assocs st len ar)))!st
- = (assoc_nonblocking (merge_arr_assocs st len ar))!st.
-Proof.
- split; simplify; eauto.
- unfold merge_arrs.
- rewrite AssocMap.gcombine by reflexivity.
- unfold empty_stack'.
- (* rewrite AssocMap.gss. *)
- (* setoid_rewrite merge_arr_empty2; auto. *)
- (* rewrite AssocMap.gcombine by reflexivity. *)
- (* unfold merge_arr, arr. *)
- (* rewrite H. rewrite H0. auto. *)
- (* unfold combine. *)
- (* simplify. *)
- (* rewrite list_combine_length. *)
- (* rewrite (arr_wf v). rewrite (arr_wf v'). *)
- (* lia. *)
-(* Qed. *) Admitted.
-
-Lemma empty_arr :
- forall m s,
- (exists l, (empty_stack m) ! s = Some (arr_repeat None l))
- \/ (empty_stack m) ! s = None.
-Proof.
- unfold empty_stack. simplify.
- destruct (Pos.eq_dec s (mod_stk m)); subst.
- left. eexists. apply AssocMap.gss.
- right. rewrite AssocMap.gso; auto.
-Qed.
-
-Lemma merge_arr_empty':
- forall m ar s v,
- match_empty_size m ar ->
- (merge_arrs (empty_stack m) ar) ! s = v ->
- ar ! s = v.
-Proof.
- inversion 1; subst.
- pose proof (empty_arr m s).
- simplify.
- destruct (merge_arrs (empty_stack m) ar) ! s eqn:?; subst.
- - inv H3. inv H4.
- learn H3 as H5. apply H0 in H5. inv H5. simplify.
- unfold merge_arrs in *. (* rewrite AssocMap.gcombine in Heqo; auto. *)
- (* rewrite H3 in Heqo. erewrite merge_arr_empty2 in Heqo. auto. eauto. *)
- (* rewrite list_repeat_len in H6. auto. *)
- (* learn H4 as H6. apply H2 in H6. *)
- (* unfold merge_arrs in *. rewrite AssocMap.gcombine in Heqo; auto. *)
- (* rewrite H4 in Heqo. unfold Verilog.arr in *. rewrite H6 in Heqo. *)
- (* discriminate. *)
- (* - inv H3. inv H4. learn H3 as H4. apply H0 in H4. inv H4. simplify. *)
- (* rewrite list_repeat_len in H6. *)
- (* unfold merge_arrs in *. rewrite AssocMap.gcombine in Heqo; auto. rewrite H3 in Heqo. *)
- (* unfold Verilog.arr in *. rewrite H4 in Heqo. *)
- (* discriminate. *)
- (* apply H2 in H4; auto. *)
-(* Qed. *) Admitted.
-
-Lemma merge_arr_empty :
- forall m ar ar',
- match_empty_size m ar ->
- match_arrs ar ar' ->
- match_arrs (merge_arrs (empty_stack m) ar) ar'.
-Proof.
- inversion 1; subst; inversion 1; subst;
- econstructor; intros; apply merge_arr_empty' in H6; auto.
-Qed.
-#[local] Hint Resolve merge_arr_empty : mgen.
-
-Lemma merge_arr_empty'':
- forall m ar s v,
- match_empty_size m ar ->
- ar ! s = v ->
- (merge_arrs (empty_stack m) ar) ! s = v.
-Proof.
- inversion 1; subst.
- pose proof (empty_arr m s).
- simplify.
- destruct (merge_arrs (empty_stack m) ar) ! s eqn:?; subst.
- - inv H3. inv H4.
- learn H3 as H5. apply H0 in H5. inv H5. simplify.
- unfold merge_arrs in *. (* rewrite AssocMap.gcombine in Heqo; auto. *)
-(* rewrite H3 in Heqo. erewrite merge_arr_empty2 in Heqo. auto. eauto. *)
-(* rewrite list_repeat_len in H6. auto. *)
-(* learn H4 as H6. apply H2 in H6. *)
-(* unfold merge_arrs in *. rewrite AssocMap.gcombine in Heqo; auto. *)
-(* rewrite H4 in Heqo. unfold Verilog.arr in *. rewrite H6 in Heqo. *)
-(* discriminate. *)
-(* - inv H3. inv H4. learn H3 as H4. apply H0 in H4. inv H4. simplify. *)
-(* rewrite list_repeat_len in H6. *)
-(* unfold merge_arrs in *. rewrite AssocMap.gcombine in Heqo; auto. rewrite H3 in Heqo. *)
-(* unfold Verilog.arr in *. rewrite H4 in Heqo. *)
-(* discriminate. *)
-(* apply H2 in H4; auto. *)
-(* Qed. *) Admitted.
-
-Lemma merge_arr_empty_match :
- forall m ar,
- match_empty_size m ar ->
- match_empty_size m (merge_arrs (empty_stack m) ar).
-Proof.
- inversion 1; subst.
- constructor; simplify.
- learn H3 as H4. apply H0 in H4. inv H4. simplify.
- eexists; split; eauto. apply merge_arr_empty''; eauto.
- apply merge_arr_empty' in H3; auto.
- split; simplify.
- unfold merge_arrs in H3. (* rewrite AssocMap.gcombine in H3; auto. *)
-(* unfold merge_arr in *. *)
-(* destruct (empty_stack m) ! s eqn:?; *)
-(* destruct ar ! s; try discriminate; eauto. *)
-(* apply merge_arr_empty''; auto. apply H2 in H3; auto. *)
-(* Qed. *) Admitted.
-#[local] Hint Resolve merge_arr_empty_match : mgen.
-
-Definition ram_present {A: Type} ar r v v' :=
- (assoc_nonblocking ar)!(ram_mem r) = Some v
- /\ @arr_length A v = ram_size r
- /\ (assoc_blocking ar)!(ram_mem r) = Some v'
- /\ arr_length v' = ram_size r.
-
-Lemma find_assoc_get :
- forall rs r trs,
- rs ! r = trs ! r ->
- rs # r = trs # r.
-Proof.
- intros; unfold find_assocmap, AssocMapExt.get_default; rewrite H; auto.
-Qed.
-#[local] Hint Resolve find_assoc_get : mgen.
-
-Lemma find_assoc_get2 :
- forall rs p r v trs,
- (forall r, r < p -> rs ! r = trs ! r) ->
- r < p ->
- rs # r = v ->
- trs # r = v.
-Proof.
- intros; unfold find_assocmap, AssocMapExt.get_default; rewrite <- H; auto.
-Qed.
-#[local] Hint Resolve find_assoc_get2 : mgen.
-
-Lemma get_assoc_gt :
- forall A (rs : AssocMap.t A) p r v trs,
- (forall r, r < p -> rs ! r = trs ! r) ->
- r < p ->
- rs ! r = v ->
- trs ! r = v.
-Proof. intros. rewrite <- H; auto. Qed.
-#[local] Hint Resolve get_assoc_gt : mgen.
-
-Lemma expr_runp_matches :
- forall f rs ar e v,
- expr_runp f rs ar e v ->
- forall trs tar,
- match_assocmaps (max_reg_expr e + 1) rs trs ->
- match_arrs ar tar ->
- expr_runp f trs tar e v.
-Proof.
- induction 1.
- - intros. econstructor.
- - intros. econstructor. inv H0. symmetry.
- apply find_assoc_get.
- apply H2. crush.
- - intros. econstructor. apply IHexpr_runp; eauto.
- inv H1. constructor. simplify.
- assert (forall a b c, a < b + 1 -> a < Pos.max c b + 1) by lia.
- eapply H4 in H1. eapply H3 in H1. auto.
- inv H2.
- unfold arr_assocmap_lookup in *.
- destruct (stack ! r) eqn:?; [|discriminate].
- inv H1.
- inv H0.
- eapply H3 in Heqo. inv Heqo. inv H0.
- unfold arr in *. rewrite H1. inv H5.
- rewrite H0. auto.
- - intros. econstructor; eauto. eapply IHexpr_runp1; eauto.
- econstructor. inv H2. intros.
- assert (forall a b c, a < b + 1 -> a < Pos.max b c + 1) by lia.
- simplify.
- eapply H5 in H2. apply H4 in H2. auto.
- apply IHexpr_runp2; eauto.
- econstructor. inv H2. intros.
- assert (forall a b c, a < b + 1 -> a < Pos.max c b + 1) by lia.
- simplify. eapply H5 in H2. apply H4 in H2. auto.
- - intros. econstructor; eauto.
- - intros. econstructor; eauto. apply IHexpr_runp1; eauto.
- constructor. inv H2. intros. simplify.
- assert (forall a b c, a < b + 1 -> a < Pos.max b c + 1) by lia.
- eapply H5 in H2. apply H4 in H2. auto.
- apply IHexpr_runp2; eauto. simplify.
- assert (forall a b c d, a < b + 1 -> a < Pos.max c (Pos.max b d) + 1) by lia.
- constructor. intros. eapply H4 in H5. inv H2. apply H6 in H5. auto.
- - intros. eapply erun_Vternary_false. apply IHexpr_runp1; eauto. constructor. inv H2.
- intros. simplify. assert (forall a b c, a < b + 1 -> a < Pos.max b c + 1) by lia.
- eapply H5 in H2. apply H4 in H2. auto.
- apply IHexpr_runp2; eauto. econstructor. inv H2. simplify.
- assert (forall a b c d, a < b + 1 -> a < Pos.max c (Pos.max d b) + 1) by lia.
- eapply H5 in H2. apply H4 in H2. auto. auto.
-Qed.
-#[local] Hint Resolve expr_runp_matches : mgen.
-
-Lemma expr_runp_matches2 :
- forall f rs ar e v p,
- expr_runp f rs ar e v ->
- max_reg_expr e < p ->
- forall trs tar,
- match_assocmaps p rs trs ->
- match_arrs ar tar ->
- expr_runp f trs tar e v.
-Proof.
- intros. eapply expr_runp_matches; eauto.
- assert (max_reg_expr e + 1 <= p) by lia.
- mgen_crush.
-Qed.
-#[local] Hint Resolve expr_runp_matches2 : mgen.
-
-Lemma match_assocmaps_gss :
- forall p rab rab' r rhsval,
- match_assocmaps p rab rab' ->
- match_assocmaps p rab # r <- rhsval rab' # r <- rhsval.
-Proof.
- intros. inv H. econstructor.
- intros.
- unfold find_assocmap. unfold AssocMapExt.get_default.
- destruct (Pos.eq_dec r r0); subst.
- repeat rewrite PTree.gss; auto.
- repeat rewrite PTree.gso; auto.
-Qed.
-#[local] Hint Resolve match_assocmaps_gss : mgen.
-
-Lemma match_assocmaps_gt :
- forall p s ra ra' v,
- p <= s ->
- match_assocmaps p ra ra' ->
- match_assocmaps p ra (ra' # s <- v).
-Proof.
- intros. inv H0. constructor.
- intros. rewrite AssocMap.gso; try lia. apply H1; auto.
-Qed.
-#[local] Hint Resolve match_assocmaps_gt : mgen.
-
-Lemma match_reg_assocs_block :
- forall p rab rab' r rhsval,
- match_reg_assocs p rab rab' ->
- match_reg_assocs p (block_reg r rab rhsval) (block_reg r rab' rhsval).
-Proof. inversion 1; econstructor; eauto with mgen. Qed.
-#[local] Hint Resolve match_reg_assocs_block : mgen.
-
-Lemma match_reg_assocs_nonblock :
- forall p rab rab' r rhsval,
- match_reg_assocs p rab rab' ->
- match_reg_assocs p (nonblock_reg r rab rhsval) (nonblock_reg r rab' rhsval).
-Proof. inversion 1; econstructor; eauto with mgen. Qed.
-#[local] Hint Resolve match_reg_assocs_nonblock : mgen.
-
-Lemma some_inj :
- forall A (x: A) y,
- Some x = Some y ->
- x = y.
-Proof. inversion 1; auto. Qed.
-
-Lemma arrs_present :
- forall r i v ar arr,
- (arr_assocmap_set r i v ar) ! r = Some arr ->
- exists b, ar ! r = Some b.
-Proof.
- intros. unfold arr_assocmap_set in *.
- destruct ar!r eqn:?.
- rewrite AssocMap.gss in H.
- inv H. eexists. auto. rewrite Heqo in H. discriminate.
-Qed.
-
-Ltac inv_exists :=
- match goal with
- | H: exists _, _ |- _ => inv H
- end.
-
-Lemma array_get_error_bound_gt :
- forall A i (a : Array A),
- (i >= arr_length a)%nat ->
- array_get_error i a = None.
-Proof.
- intros. unfold array_get_error.
- apply nth_error_None. destruct a. simplify.
- lia.
-Qed.
-#[local] Hint Resolve array_get_error_bound_gt : mgen.
-
-Lemma array_get_error_each :
- forall A addr i (v : A) a x,
- arr_length a = arr_length x ->
- array_get_error addr a = array_get_error addr x ->
- array_get_error addr (array_set i v a) = array_get_error addr (array_set i v x).
-Proof.
- intros.
- destruct (Nat.eq_dec addr i); subst.
- destruct (lt_dec i (arr_length a)).
- repeat rewrite array_get_error_set_bound; auto.
- rewrite <- H. auto.
- apply Nat.nlt_ge in n.
- repeat rewrite array_get_error_bound_gt; auto.
- rewrite <- array_set_len. rewrite <- H. lia.
- repeat rewrite array_gso; auto.
-Qed.
-#[local] Hint Resolve array_get_error_each : mgen.
-
-Lemma match_arrs_gss :
- forall ar ar' r v i,
- match_arrs ar ar' ->
- match_arrs (arr_assocmap_set r i v ar) (arr_assocmap_set r i v ar').
-Proof.
- Ltac mag_tac :=
- match goal with
- | H: ?ar ! _ = Some _, H2: forall s arr, ?ar ! s = Some arr -> _ |- _ =>
- let H3 := fresh "H" in
- learn H as H3; apply H2 in H3; inv_exists; simplify
- | H: ?ar ! _ = None, H2: forall s, ?ar ! s = None -> _ |- _ =>
- let H3 := fresh "H" in
- learn H as H3; apply H2 in H3; inv_exists; simplify
- | H: ?ar ! _ = _ |- context[match ?ar ! _ with _ => _ end] =>
- unfold Verilog.arr in *; rewrite H
- | H: ?ar ! _ = _, H2: context[match ?ar ! _ with _ => _ end] |- _ =>
- unfold Verilog.arr in *; rewrite H in H2
- | H: context[(_ # ?s <- _) ! ?s] |- _ => rewrite AssocMap.gss in H
- | H: context[(_ # ?r <- _) ! ?s], H2: ?r <> ?s |- _ => rewrite AssocMap.gso in H; auto
- | |- context[(_ # ?s <- _) ! ?s] => rewrite AssocMap.gss
- | H: ?r <> ?s |- context[(_ # ?r <- _) ! ?s] => rewrite AssocMap.gso; auto
- end.
- intros.
- inv H. econstructor; simplify.
- destruct (Pos.eq_dec r s); subst.
- - unfold arr_assocmap_set, Verilog.arr in *.
- destruct ar!s eqn:?.
- mag_tac.
- econstructor; simplify.
- repeat mag_tac; auto.
- intros. repeat mag_tac. simplify.
- apply array_get_error_each; auto.
- repeat mag_tac; crush.
- repeat mag_tac; crush.
- - unfold arr_assocmap_set in *.
- destruct ar ! r eqn:?. rewrite AssocMap.gso in H; auto.
- apply H0 in Heqo. apply H0 in H. repeat inv_exists. simplify.
- econstructor. unfold Verilog.arr in *. rewrite H3. simplify.
- rewrite AssocMap.gso; auto. eauto. intros. auto. auto.
- apply H1 in Heqo. apply H0 in H. repeat inv_exists; simplify.
- econstructor. unfold Verilog.arr in *. rewrite Heqo. simplify; eauto.
- - destruct (Pos.eq_dec r s); unfold arr_assocmap_set, Verilog.arr in *; simplify; subst.
- destruct ar!s eqn:?; repeat mag_tac; crush.
- apply H1 in H. mag_tac; crush.
- destruct ar!r eqn:?; repeat mag_tac; crush.
- apply H1 in Heqo. repeat mag_tac; auto.
-Qed.
-#[local] Hint Resolve match_arrs_gss : mgen.
-
-Lemma match_arr_assocs_block :
- forall rab rab' r i rhsval,
- match_arr_assocs rab rab' ->
- match_arr_assocs (block_arr r i rab rhsval) (block_arr r i rab' rhsval).
-Proof. inversion 1; econstructor; eauto with mgen. Qed.
-#[local] Hint Resolve match_arr_assocs_block : mgen.
-
-Lemma match_arr_assocs_nonblock :
- forall rab rab' r i rhsval,
- match_arr_assocs rab rab' ->
- match_arr_assocs (nonblock_arr r i rab rhsval) (nonblock_arr r i rab' rhsval).
-Proof. inversion 1; econstructor; eauto with mgen. Qed.
-#[local] Hint Resolve match_arr_assocs_nonblock : mgen.
-
-Lemma match_states_same :
- forall f rs1 ar1 c rs2 ar2 p,
- stmnt_runp f rs1 ar1 c rs2 ar2 ->
- max_reg_stmnt c < p ->
- forall trs1 tar1,
- match_reg_assocs p rs1 trs1 ->
- match_arr_assocs ar1 tar1 ->
- exists trs2 tar2,
- stmnt_runp f trs1 tar1 c trs2 tar2
- /\ match_reg_assocs p rs2 trs2
- /\ match_arr_assocs ar2 tar2.
-Proof.
- Ltac match_states_same_facts :=
- match goal with
- | H: match_reg_assocs _ _ _ |- _ =>
- let H2 := fresh "H" in
- learn H as H2; inv H2
- | H: match_arr_assocs _ _ |- _ =>
- let H2 := fresh "H" in
- learn H as H2; inv H2
- | H1: context[exists _, _], H2: context[exists _, _] |- _ =>
- learn H1; learn H2;
- exploit H1; mgen_crush; exploit H2; mgen_crush
- | H1: context[exists _, _] |- _ =>
- learn H1; exploit H1; mgen_crush
- end.
- Ltac match_states_same_tac :=
- match goal with
- | |- exists _, _ => econstructor
- | |- _ < _ => lia
- | H: context[_ <> _] |- stmnt_runp _ _ _ (Vcase _ (Stmntcons _ _ _) _) _ _ =>
- eapply stmnt_runp_Vcase_nomatch
- | |- stmnt_runp _ _ _ (Vcase _ (Stmntcons _ _ _) _) _ _ =>
- eapply stmnt_runp_Vcase_match
- | H: valueToBool _ = false |- stmnt_runp _ _ _ _ _ _ =>
- eapply stmnt_runp_Vcond_false
- | |- stmnt_runp _ _ _ _ _ _ => econstructor
- | |- expr_runp _ _ _ _ _ => eapply expr_runp_matches2
- end; mgen_crush; try lia.
- induction 1; simplify; repeat match_states_same_facts;
- try destruct_match; try solve [repeat match_states_same_tac].
- - inv H. exists (block_reg r {| assoc_blocking := rab'; assoc_nonblocking := ran' |} rhsval);
- repeat match_states_same_tac; econstructor.
- - exists (nonblock_reg r {| assoc_blocking := rab'; assoc_nonblocking := ran' |} rhsval);
- repeat match_states_same_tac; inv H; econstructor.
- - econstructor. exists (block_arr r i {| assoc_blocking := rab'0; assoc_nonblocking := ran'0 |} rhsval).
- simplify; repeat match_states_same_tac. inv H. econstructor.
- repeat match_states_same_tac. eauto. mgen_crush.
- - econstructor. exists (nonblock_arr r i {| assoc_blocking := rab'0; assoc_nonblocking := ran'0 |} rhsval).
- simplify; repeat match_states_same_tac. inv H. econstructor.
- repeat match_states_same_tac. eauto. mgen_crush.
-Qed.
-
-Lemma match_reg_assocs_merge :
- forall p rs rs',
- match_reg_assocs p rs rs' ->
- match_reg_assocs p (merge_reg_assocs rs) (merge_reg_assocs rs').
-Proof.
- inversion 1.
- econstructor; econstructor; crush. inv H3. inv H.
- inv H7. inv H9.
- unfold merge_regs.
- destruct (ran!r) eqn:?; destruct (rab!r) eqn:?.
- erewrite AssocMapExt.merge_correct_1; eauto.
- erewrite AssocMapExt.merge_correct_1; eauto.
- rewrite <- H2; eauto.
- erewrite AssocMapExt.merge_correct_1; eauto.
- erewrite AssocMapExt.merge_correct_1; eauto.
- rewrite <- H2; eauto.
- erewrite AssocMapExt.merge_correct_2; eauto.
- erewrite AssocMapExt.merge_correct_2; eauto.
- rewrite <- H2; eauto.
- rewrite <- H; eauto.
- erewrite AssocMapExt.merge_correct_3; eauto.
- erewrite AssocMapExt.merge_correct_3; eauto.
- rewrite <- H2; eauto.
- rewrite <- H; eauto.
-Qed.
-#[local] Hint Resolve match_reg_assocs_merge : mgen.
-
-Lemma transf_not_changed :
- forall state ram n d c i d_s c_s,
- (forall e1 e2 r, d_s <> Vnonblock (Vvari r e1) e2) ->
- (forall e1 e2 r, d_s <> Vnonblock e1 (Vvari r e2)) ->
- d!i = Some d_s ->
- c!i = Some c_s ->
- transf_maps state ram (i, n) (d, c) = (d, c).
-Proof. intros; unfold transf_maps; repeat destruct_match; mgen_crush. Qed.
-
-Lemma transf_not_changed_neq :
- forall state ram n d c d' c' i a d_s c_s,
- transf_maps state ram (a, n) (d, c) = (d', c') ->
- d!i = Some d_s ->
- c!i = Some c_s ->
- a <> i -> n <> i ->
- d'!i = Some d_s /\ c'!i = Some c_s.
-Proof.
- unfold transf_maps; intros; repeat destruct_match; mgen_crush;
- match goal with [ H: (_, _) = (_, _) |- _ ] => inv H end;
- repeat (rewrite AssocMap.gso; auto).
-Qed.
-
-Lemma forall_gt :
- forall l, Forall (Pos.ge (fold_right Pos.max 1 l)) l.
-Proof.
- induction l; auto.
- constructor. inv IHl; simplify; lia.
- simplify. destruct (Pos.max_dec a (fold_right Pos.max 1 l)).
- rewrite e. apply Pos.max_l_iff in e. apply Pos.le_ge in e.
- apply Forall_forall. rewrite Forall_forall in IHl.
- intros.
- assert (X: forall a b c, a >= c -> c >= b -> a >= b) by lia.
- apply X with (b := x) in e; auto.
- rewrite e; auto.
-Qed.
-
-Lemma max_index_list :
- forall A (l : list (positive * A)) i d_s,
- In (i, d_s) l ->
- list_norepet (map fst l) ->
- i <= fold_right Pos.max 1 (map fst l).
-Proof.
- induction l; crush.
- inv H. inv H0. simplify. lia.
- inv H0.
- let H := fresh "H" in
- assert (H: forall a b c, c <= b -> c <= Pos.max a b) by lia;
- apply H; eapply IHl; eauto.
-Qed.
-
-Lemma max_index :
- forall A d i (d_s: A), d ! i = Some d_s -> i <= max_pc d.
-Proof.
- unfold max_pc;
- eauto using max_index_list,
- PTree.elements_correct, PTree.elements_keys_norepet.
-Qed.
-
-Lemma max_index_2' :
- forall l i, i > fold_right Pos.max 1 l -> Forall (Pos.gt i) l.
-Proof. induction l; crush; constructor; [|apply IHl]; lia. Qed.
-
-Lemma max_index_2'' :
- forall l i, Forall (Pos.gt i) l -> ~ In i l.
-Proof.
- induction l; crush. unfold not in *.
- intros. inv H0. inv H. lia. eapply IHl.
- inv H. apply H4. auto.
-Qed.
-
-Lemma elements_correct_none :
- forall A am k,
- ~ List.In k (List.map (@fst _ A) (AssocMap.elements am)) ->
- AssocMap.get k am = None.
-Proof.
- intros. apply AssocMapExt.elements_correct' in H. unfold not in *.
- destruct am ! k eqn:?; auto. exfalso. apply H. eexists. auto.
-Qed.
-#[local] Hint Resolve elements_correct_none : assocmap.
-
-Lemma max_index_2 :
- forall A (d: AssocMap.t A) i, i > max_pc d -> d ! i = None.
-Proof.
- intros. unfold max_pc in *. apply max_index_2' in H.
- apply max_index_2'' in H. apply elements_correct_none. auto.
-Qed.
-
-Definition match_prog (p: program) (tp: program) :=
- Linking.match_program (fun cu f tf => tf = transf_fundef f) eq p tp.
-
-Lemma transf_program_match:
- forall p, match_prog p (transf_program p).
-Proof.
- intros. unfold transf_program, match_prog.
- apply Linking.match_transform_program.
-Qed.
-
-Lemma exec_all_Vskip :
- forall rs ar,
- exec_all Vskip Vskip rs ar rs ar.
-Proof.
- unfold exec_all.
- intros. repeat econstructor.
- Unshelve. unfold fext. exact tt.
-Qed.
-
-Lemma match_assocmaps_trans:
- forall p rs1 rs2 rs3,
- match_assocmaps p rs1 rs2 ->
- match_assocmaps p rs2 rs3 ->
- match_assocmaps p rs1 rs3.
-Proof.
- intros. inv H. inv H0. econstructor; eauto.
- intros. rewrite H1 by auto. auto.
-Qed.
-
-Lemma match_reg_assocs_trans:
- forall p rs1 rs2 rs3,
- match_reg_assocs p rs1 rs2 ->
- match_reg_assocs p rs2 rs3 ->
- match_reg_assocs p rs1 rs3.
-Proof.
- intros. inv H. inv H0.
- econstructor; eapply match_assocmaps_trans; eauto.
-Qed.
-
-Lemma empty_arrs_match :
- forall m,
- match_arrs (empty_stack m) (empty_stack (transf_module m)).
-Proof.
- intros;
- unfold empty_stack, transf_module; repeat destruct_match; mgen_crush.
-Qed.
-#[local] Hint Resolve empty_arrs_match : mgen.
-
-Lemma max_module_stmnts :
- forall m,
- Pos.max (max_stmnt_tree (mod_controllogic m))
- (max_stmnt_tree (mod_datapath m)) < max_reg_module m + 1.
-Proof. intros. unfold max_reg_module. lia. Qed.
-#[local] Hint Resolve max_module_stmnts : mgen.
-
-Lemma transf_module_code :
- forall m,
- mod_ram m = None ->
- transf_code (mod_st m)
- {| ram_size := mod_stk_len m;
- ram_mem := mod_stk m;
- ram_en := max_reg_module m + 2;
- ram_addr := max_reg_module m + 1;
- ram_wr_en := max_reg_module m + 5;
- ram_d_in := max_reg_module m + 3;
- ram_d_out := max_reg_module m + 4;
- ram_u_en := max_reg_module m + 6;
- ram_ordering := ram_wf (max_reg_module m) |}
- (mod_datapath m) (mod_controllogic m)
- = ((mod_datapath (transf_module m)), mod_controllogic (transf_module m)).
-Proof. unfold transf_module; intros; repeat destruct_match; crush.
- apply surjective_pairing. Qed.
-#[local] Hint Resolve transf_module_code : mgen.
-
-Lemma transf_module_code_ram :
- forall m r, mod_ram m = Some r -> transf_module m = m.
-Proof. unfold transf_module; intros; repeat destruct_match; crush. Qed.
-#[local] Hint Resolve transf_module_code_ram : mgen.
-
-Lemma mod_reset_lt : forall m, mod_reset m < max_reg_module m + 1.
-Proof. intros; unfold max_reg_module; lia. Qed.
-#[local] Hint Resolve mod_reset_lt : mgen.
-
-Lemma mod_finish_lt : forall m, mod_finish m < max_reg_module m + 1.
-Proof. intros; unfold max_reg_module; lia. Qed.
-#[local] Hint Resolve mod_finish_lt : mgen.
-
-Lemma mod_return_lt : forall m, mod_return m < max_reg_module m + 1.
-Proof. intros; unfold max_reg_module; lia. Qed.
-#[local] Hint Resolve mod_return_lt : mgen.
-
-Lemma mod_start_lt : forall m, mod_start m < max_reg_module m + 1.
-Proof. intros; unfold max_reg_module; lia. Qed.
-#[local] Hint Resolve mod_start_lt : mgen.
-
-Lemma mod_stk_lt : forall m, mod_stk m < max_reg_module m + 1.
-Proof. intros; unfold max_reg_module; lia. Qed.
-#[local] Hint Resolve mod_stk_lt : mgen.
-
-Lemma mod_st_lt : forall m, mod_st m < max_reg_module m + 1.
-Proof. intros; unfold max_reg_module; lia. Qed.
-#[local] Hint Resolve mod_st_lt : mgen.
-
-Lemma mod_reset_modify :
- forall m ar ar' v,
- match_assocmaps (max_reg_module m + 1) ar ar' ->
- ar ! (mod_reset m) = Some v ->
- ar' ! (mod_reset (transf_module m)) = Some v.
-Proof.
- inversion 1. intros.
- unfold transf_module; repeat destruct_match; simplify;
- rewrite <- H0; eauto with mgen.
-Qed.
-#[local] Hint Resolve mod_reset_modify : mgen.
-
-Lemma mod_finish_modify :
- forall m ar ar' v,
- match_assocmaps (max_reg_module m + 1) ar ar' ->
- ar ! (mod_finish m) = Some v ->
- ar' ! (mod_finish (transf_module m)) = Some v.
-Proof.
- inversion 1. intros.
- unfold transf_module; repeat destruct_match; simplify;
- rewrite <- H0; eauto with mgen.
-Qed.
-#[local] Hint Resolve mod_finish_modify : mgen.
-
-Lemma mod_return_modify :
- forall m ar ar' v,
- match_assocmaps (max_reg_module m + 1) ar ar' ->
- ar ! (mod_return m) = Some v ->
- ar' ! (mod_return (transf_module m)) = Some v.
-Proof.
- inversion 1. intros.
- unfold transf_module; repeat destruct_match; simplify;
- rewrite <- H0; eauto with mgen.
-Qed.
-#[local] Hint Resolve mod_return_modify : mgen.
-
-Lemma mod_start_modify :
- forall m ar ar' v,
- match_assocmaps (max_reg_module m + 1) ar ar' ->
- ar ! (mod_start m) = Some v ->
- ar' ! (mod_start (transf_module m)) = Some v.
-Proof.
- inversion 1. intros.
- unfold transf_module; repeat destruct_match; simplify;
- rewrite <- H0; eauto with mgen.
-Qed.
-#[local] Hint Resolve mod_start_modify : mgen.
-
-Lemma mod_st_modify :
- forall m ar ar' v,
- match_assocmaps (max_reg_module m + 1) ar ar' ->
- ar ! (mod_st m) = Some v ->
- ar' ! (mod_st (transf_module m)) = Some v.
-Proof.
- inversion 1. intros.
- unfold transf_module; repeat destruct_match; simplify;
- rewrite <- H0; eauto with mgen.
-Qed.
-#[local] Hint Resolve mod_st_modify : mgen.
-
-Lemma match_arrs_read :
- forall ra ra' addr v mem,
- arr_assocmap_lookup ra mem addr = Some v ->
- match_arrs ra ra' ->
- arr_assocmap_lookup ra' mem addr = Some v.
-Proof.
- unfold arr_assocmap_lookup. intros. destruct_match; destruct_match; try discriminate.
- inv H0. eapply H1 in Heqo0. inv Heqo0. simplify. unfold arr in *.
- rewrite H in Heqo. inv Heqo.
- rewrite H0. auto.
- inv H0. eapply H1 in Heqo0. inv Heqo0. inv H0. unfold arr in *.
- rewrite H3 in Heqo. discriminate.
-Qed.
-#[local] Hint Resolve match_arrs_read : mgen.
-
-Lemma match_reg_implies_equal :
- forall ra ra' p a b c,
- Int.eq (ra # a) (ra # b) = c ->
- a < p -> b < p ->
- match_assocmaps p ra ra' ->
- Int.eq (ra' # a) (ra' # b) = c.
-Proof.
- unfold find_assocmap, AssocMapExt.get_default; intros.
- inv H2. destruct (ra ! a) eqn:?; destruct (ra ! b) eqn:?;
- repeat rewrite <- H3 by lia; rewrite Heqo; rewrite Heqo0; auto.
-Qed.
-#[local] Hint Resolve match_reg_implies_equal : mgen.
-
-Lemma exec_ram_same :
- forall rs1 ar1 ram rs2 ar2 p,
- exec_ram rs1 ar1 (Some ram) rs2 ar2 ->
- forall_ram (fun x => x < p) ram ->
- forall trs1 tar1,
- match_reg_assocs p rs1 trs1 ->
- match_arr_assocs ar1 tar1 ->
- exists trs2 tar2,
- exec_ram trs1 tar1 (Some ram) trs2 tar2
- /\ match_reg_assocs p rs2 trs2
- /\ match_arr_assocs ar2 tar2.
-Proof.
- Ltac exec_ram_same_facts :=
- match goal with
- | H: match_reg_assocs _ _ _ |- _ => let H2 := fresh "H" in learn H as H2; inv H2
- | H: match_assocmaps _ _ _ |- _ => let H2 := fresh "H" in learn H as H2; inv H2
- | H: match_arr_assocs _ _ |- _ => let H2 := fresh "H" in learn H as H2; inv H2
- | H: match_arrs _ _ |- _ => let H2 := fresh "H" in learn H as H2; inv H2
- end.
- inversion 1; subst; destruct ram; unfold forall_ram; simplify; repeat exec_ram_same_facts.
- - repeat (econstructor; mgen_crush).
- - do 2 econstructor; simplify;
- [eapply exec_ram_Some_write; [ apply H1 | apply H2 | | | | | ] | | ];
- mgen_crush.
- - do 2 econstructor; simplify; [eapply exec_ram_Some_read | | ];
- repeat (try econstructor; mgen_crush).
-Qed.
-
-Lemma match_assocmaps_merge :
- forall p nasr basr nasr' basr',
- match_assocmaps p nasr nasr' ->
- match_assocmaps p basr basr' ->
- match_assocmaps p (merge_regs nasr basr) (merge_regs nasr' basr').
-Proof.
- unfold merge_regs.
- intros. inv H. inv H0. econstructor.
- intros.
- destruct nasr ! r eqn:?; destruct basr ! r eqn:?.
- erewrite AssocMapExt.merge_correct_1; mgen_crush.
- erewrite AssocMapExt.merge_correct_1; mgen_crush.
- erewrite AssocMapExt.merge_correct_1; mgen_crush.
- erewrite AssocMapExt.merge_correct_1; mgen_crush.
- erewrite AssocMapExt.merge_correct_2; mgen_crush.
- erewrite AssocMapExt.merge_correct_2; mgen_crush.
- erewrite AssocMapExt.merge_correct_3; mgen_crush.
- erewrite AssocMapExt.merge_correct_3; mgen_crush.
-Qed.
-#[local] Hint Resolve match_assocmaps_merge : mgen.
-
-Lemma list_combine_nth_error1 :
- forall l l' addr v,
- length l = length l' ->
- nth_error l addr = Some (Some v) ->
- nth_error (list_combine merge_cell l l') addr = Some (Some v).
-Proof. induction l; destruct l'; destruct addr; crush. Qed.
-
-Lemma list_combine_nth_error2 :
- forall l' l addr v,
- length l = length l' ->
- nth_error l addr = Some None ->
- nth_error l' addr = Some (Some v) ->
- nth_error (list_combine merge_cell l l') addr = Some (Some v).
-Proof. induction l'; try rewrite nth_error_nil in *; destruct l; destruct addr; crush. Qed.
-
-Lemma list_combine_nth_error3 :
- forall l l' addr,
- length l = length l' ->
- nth_error l addr = Some None ->
- nth_error l' addr = Some None ->
- nth_error (list_combine merge_cell l l') addr = Some None.
-Proof. induction l; destruct l'; destruct addr; crush. Qed.
-
-Lemma list_combine_nth_error4 :
- forall l l' addr,
- length l = length l' ->
- nth_error l addr = None ->
- nth_error (list_combine merge_cell l l') addr = None.
-Proof. induction l; destruct l'; destruct addr; crush. Qed.
-
-Lemma list_combine_nth_error5 :
- forall l l' addr,
- length l = length l' ->
- nth_error l' addr = None ->
- nth_error (list_combine merge_cell l l') addr = None.
-Proof. induction l; destruct l'; destruct addr; crush. Qed.
-
-Lemma array_get_error_merge1 :
- forall a a0 addr v,
- arr_length a = arr_length a0 ->
- array_get_error addr a = Some (Some v) ->
- array_get_error addr (combine merge_cell a a0) = Some (Some v).
-Proof.
- unfold array_get_error, combine in *; intros;
- apply list_combine_nth_error1; destruct a; destruct a0; crush.
-Qed.
-
-Lemma array_get_error_merge2 :
- forall a a0 addr v,
- arr_length a = arr_length a0 ->
- array_get_error addr a0 = Some (Some v) ->
- array_get_error addr a = Some None ->
- array_get_error addr (combine merge_cell a a0) = Some (Some v).
-Proof.
- unfold array_get_error, combine in *; intros;
- apply list_combine_nth_error2; destruct a; destruct a0; crush.
-Qed.
-
-Lemma array_get_error_merge3 :
- forall a a0 addr,
- arr_length a = arr_length a0 ->
- array_get_error addr a0 = Some None ->
- array_get_error addr a = Some None ->
- array_get_error addr (combine merge_cell a a0) = Some None.
-Proof.
- unfold array_get_error, combine in *; intros;
- apply list_combine_nth_error3; destruct a; destruct a0; crush.
-Qed.
-
-Lemma array_get_error_merge4 :
- forall a a0 addr,
- arr_length a = arr_length a0 ->
- array_get_error addr a = None ->
- array_get_error addr (combine merge_cell a a0) = None.
-Proof.
- unfold array_get_error, combine in *; intros;
- apply list_combine_nth_error4; destruct a; destruct a0; crush.
-Qed.
-
-Lemma array_get_error_merge5 :
- forall a a0 addr,
- arr_length a = arr_length a0 ->
- array_get_error addr a0 = None ->
- array_get_error addr (combine merge_cell a a0) = None.
-Proof.
- unfold array_get_error, combine in *; intros;
- apply list_combine_nth_error5; destruct a; destruct a0; crush.
-Qed.
-
-Lemma match_arrs_merge' :
- forall addr nasa basa arr s x x0 a a0 nasa' basa',
- (AssocMap.combine merge_arr nasa basa) ! s = Some arr ->
- nasa ! s = Some a ->
- basa ! s = Some a0 ->
- nasa' ! s = Some x0 ->
- basa' ! s = Some x ->
- arr_length x = arr_length x0 ->
- array_get_error addr a0 = array_get_error addr x ->
- arr_length a0 = arr_length x ->
- array_get_error addr a = array_get_error addr x0 ->
- arr_length a = arr_length x0 ->
- array_get_error addr arr = array_get_error addr (combine merge_cell x0 x).
-Proof.
- intros. rewrite AssocMap.gcombine in H by auto.
- unfold merge_arr in H.
- rewrite H0 in H. rewrite H1 in H. inv H.
- destruct (array_get_error addr a0) eqn:?; destruct (array_get_error addr a) eqn:?.
- destruct o; destruct o0.
- erewrite array_get_error_merge1; eauto. erewrite array_get_error_merge1; eauto.
- rewrite <- H6 in H4. rewrite <- H8 in H4. auto.
- erewrite array_get_error_merge2; eauto. erewrite array_get_error_merge2; eauto.
- rewrite <- H6 in H4. rewrite <- H8 in H4. auto.
- erewrite array_get_error_merge1; eauto. erewrite array_get_error_merge1; eauto.
- rewrite <- H6 in H4. rewrite <- H8 in H4. auto.
- erewrite array_get_error_merge3; eauto. erewrite array_get_error_merge3; eauto.
- rewrite <- H6 in H4. rewrite <- H8 in H4. auto.
- erewrite array_get_error_merge4; eauto. erewrite array_get_error_merge4; eauto.
- rewrite <- H6 in H4. rewrite <- H8 in H4. auto.
- erewrite array_get_error_merge5; eauto. erewrite array_get_error_merge5; eauto.
- rewrite <- H6 in H4. rewrite <- H8 in H4. auto.
- erewrite array_get_error_merge5; eauto. erewrite array_get_error_merge5; eauto.
- rewrite <- H6 in H4. rewrite <- H8 in H4. auto.
-Qed.
-
-Lemma match_arrs_merge :
- forall nasa nasa' basa basa',
- match_arrs_size nasa basa ->
- match_arrs nasa nasa' ->
- match_arrs basa basa' ->
- match_arrs (merge_arrs nasa basa) (merge_arrs nasa' basa').
-Proof.
- unfold merge_arrs.
- intros. inv H. inv H0. inv H1. econstructor.
- - intros. destruct nasa ! s eqn:?; destruct basa ! s eqn:?; unfold Verilog.arr in *.
- + pose proof Heqo. apply H in Heqo. pose proof Heqo0. apply H0 in Heqo0.
- repeat inv_exists. simplify.
- eexists. simplify. rewrite AssocMap.gcombine; eauto.
- unfold merge_arr. unfold Verilog.arr in *. rewrite H11. rewrite H12. auto.
- intros. eapply match_arrs_merge'; eauto. eapply H2 in H7; eauto.
- inv_exists. simplify. congruence.
- rewrite AssocMap.gcombine in H1; auto. unfold merge_arr in H1.
- rewrite H7 in H1. rewrite H8 in H1. inv H1.
- repeat rewrite combine_length; auto.
- eapply H2 in H7; eauto. inv_exists; simplify; congruence.
- eapply H2 in H7; eauto. inv_exists; simplify; congruence.
- + apply H2 in Heqo; inv_exists; crush.
- + apply H3 in Heqo0; inv_exists; crush.
- + rewrite AssocMap.gcombine in H1 by auto. unfold merge_arr in *.
- rewrite Heqo in H1. rewrite Heqo0 in H1. discriminate.
- - intros. rewrite AssocMap.gcombine in H1 by auto. unfold merge_arr in H1.
- repeat destruct_match; crush.
- rewrite AssocMap.gcombine by auto; unfold merge_arr.
- apply H5 in Heqo. apply H6 in Heqo0.
- unfold Verilog.arr in *.
- rewrite Heqo. rewrite Heqo0. auto.
-Qed.
-#[local] Hint Resolve match_arrs_merge : mgen.
-
-Lemma match_empty_size_merge :
- forall nasa2 basa2 m,
- match_empty_size m nasa2 ->
- match_empty_size m basa2 ->
- match_empty_size m (merge_arrs nasa2 basa2).
-Proof.
- intros. inv H. inv H0. constructor.
- simplify. unfold merge_arrs. rewrite AssocMap.gcombine by auto.
- pose proof H0 as H6. apply H1 in H6. inv_exists; simplify.
- pose proof H0 as H9. apply H in H9. inv_exists; simplify.
- eexists. simplify. unfold merge_arr. unfold Verilog.arr in *. rewrite H6.
- rewrite H9. auto. rewrite H8. symmetry. apply combine_length. congruence.
- intros.
- destruct (nasa2 ! s) eqn:?; destruct (basa2 ! s) eqn:?.
- unfold merge_arrs in H0. rewrite AssocMap.gcombine in H0 by auto.
- unfold merge_arr in *. setoid_rewrite Heqo in H0. setoid_rewrite Heqo0 in H0. inv H0.
- apply H2 in Heqo. apply H4 in Heqo0. repeat inv_exists; simplify.
- eexists. simplify. eauto. rewrite list_combine_length.
- rewrite (arr_wf a). rewrite (arr_wf a0). lia.
- unfold merge_arrs in H0. rewrite AssocMap.gcombine in H0 by auto.
- unfold merge_arr in *. setoid_rewrite Heqo in H0. setoid_rewrite Heqo0 in H0.
- apply H2 in Heqo. inv_exists; simplify.
- econstructor; eauto.
- unfold merge_arrs in H0. rewrite AssocMap.gcombine in H0 by auto.
- unfold merge_arr in *. setoid_rewrite Heqo in H0. setoid_rewrite Heqo0 in H0.
- inv H0. apply H4 in Heqo0. inv_exists; simplify. econstructor; eauto.
- unfold merge_arrs in H0. rewrite AssocMap.gcombine in H0 by auto.
- unfold merge_arr in *. setoid_rewrite Heqo in H0. setoid_rewrite Heqo0 in H0.
- discriminate.
- split; intros.
- unfold merge_arrs in H0. rewrite AssocMap.gcombine in H0 by auto.
- unfold merge_arr in *. repeat destruct_match; crush. apply H5 in Heqo0; auto.
- pose proof H0.
- apply H5 in H0.
- apply H3 in H6. unfold merge_arrs. rewrite AssocMap.gcombine by auto.
- setoid_rewrite H0. setoid_rewrite H6. auto.
-Qed.
-#[local] Hint Resolve match_empty_size_merge : mgen.
-
-Lemma match_empty_size_match :
- forall m nasa2 basa2,
- match_empty_size m nasa2 ->
- match_empty_size m basa2 ->
- match_arrs_size nasa2 basa2.
-Proof.
- Ltac match_empty_size_match_solve :=
- match goal with
- | H: context[forall s arr, ?ar ! s = Some arr -> _], H2: ?ar ! _ = Some _ |- _ =>
- let H3 := fresh "H" in
- learn H; pose proof H2 as H3; apply H in H3; repeat inv_exists
- | H: context[forall s, ?ar ! s = None <-> _], H2: ?ar ! _ = None |- _ =>
- let H3 := fresh "H" in
- learn H; pose proof H2 as H3; apply H in H3
- | H: context[forall s, _ <-> ?ar ! s = None], H2: ?ar ! _ = None |- _ =>
- let H3 := fresh "H" in
- learn H; pose proof H2 as H3; apply H in H3
- | |- exists _, _ => econstructor
- | |- _ ! _ = Some _ => eassumption
- | |- _ = _ => congruence
- | |- _ <-> _ => split
- end; simplify.
- inversion 1; inversion 1; constructor; simplify; repeat match_empty_size_match_solve.
-Qed.
-#[local] Hint Resolve match_empty_size_match : mgen.
-
-Lemma match_get_merge :
- forall p ran ran' rab rab' s v,
- s < p ->
- match_assocmaps p ran ran' ->
- match_assocmaps p rab rab' ->
- (merge_regs ran rab) ! s = Some v ->
- (merge_regs ran' rab') ! s = Some v.
-Proof.
- intros.
- assert (X: match_assocmaps p (merge_regs ran rab) (merge_regs ran' rab')) by auto with mgen.
- inv X. rewrite <- H3; auto.
-Qed.
-#[local] Hint Resolve match_get_merge : mgen.
-
-Ltac masrp_tac :=
- match goal with
- | H: context[forall s arr, ?ar ! s = Some arr -> _], H2: ?ar ! _ = Some _ |- _ =>
- let H3 := fresh "H" in
- learn H; pose proof H2 as H3; apply H in H3; repeat inv_exists
- | H: context[forall s, ?ar ! s = None <-> _], H2: ?ar ! _ = None |- _ =>
- let H3 := fresh "H" in
- learn H; pose proof H2 as H3; apply H in H3
- | H: context[forall s, _ <-> ?ar ! s = None], H2: ?ar ! _ = None |- _ =>
- let H3 := fresh "H" in
- learn H; pose proof H2 as H3; apply H in H3
- | ra: arr_associations |- _ =>
- let ra1 := fresh "ran" in let ra2 := fresh "rab" in destruct ra as [ra1 ra2]
- | |- _ ! _ = _ => solve [mgen_crush]
- | |- _ = _ => congruence
- | |- _ <> _ => lia
- | H: ?ar ! ?s = _ |- context[match ?ar ! ?r with _ => _ end] => learn H; destruct (Pos.eq_dec s r); subst
- | H: ?ar ! ?s = _ |- context[match ?ar ! ?s with _ => _ end] => setoid_rewrite H
- | |- context[match ?ar ! ?s with _ => _ end] => destruct (ar ! s) eqn:?
- | H: ?s <> ?r |- context[(_ # ?r <- _) ! ?s] => rewrite AssocMap.gso
- | H: ?r <> ?s |- context[(_ # ?r <- _) ! ?s] => rewrite AssocMap.gso
- | |- context[(_ # ?s <- _) ! ?s] => rewrite AssocMap.gss
- | H: context[match ?ar ! ?r with _ => _ end ! ?s] |- _ =>
- destruct (ar ! r) eqn:?; destruct (Pos.eq_dec r s); subst
- | H: ?ar ! ?s = _, H2: context[match ?ar ! ?s with _ => _ end] |- _ =>
- setoid_rewrite H in H2
- | H: context[match ?ar ! ?s with _ => _ end] |- _ => destruct (ar ! s) eqn:?
- | H: ?s <> ?r, H2: context[(_ # ?r <- _) ! ?s] |- _ => rewrite AssocMap.gso in H2
- | H: ?r <> ?s, H2: context[(_ # ?r <- _) ! ?s] |- _ => rewrite AssocMap.gso in H2
- | H: context[(_ # ?s <- _) ! ?s] |- _ => rewrite AssocMap.gss in H
- | |- context[match_empty_size] => constructor
- | |- context[arr_assocmap_set] => unfold arr_assocmap_set
- | H: context[arr_assocmap_set] |- _ => unfold arr_assocmap_set in H
- | |- exists _, _ => econstructor
- | |- _ <-> _ => split
- end; simplify.
-
-Lemma match_empty_assocmap_set :
- forall m r i rhsval asa,
- match_empty_size m asa ->
- match_empty_size m (arr_assocmap_set r i rhsval asa).
-Proof.
- inversion 1; subst; simplify.
- constructor. intros.
- repeat masrp_tac.
- intros. do 5 masrp_tac; try solve [repeat masrp_tac].
- apply H1 in H3. inv_exists. simplify.
- econstructor. simplify. apply H3. congruence.
- repeat masrp_tac. destruct (Pos.eq_dec r s); subst.
- rewrite AssocMap.gss in H8. discriminate.
- rewrite AssocMap.gso in H8; auto. apply H2 in H8. auto.
- destruct (Pos.eq_dec r s); subst. apply H1 in H5. inv_exists. simplify.
- rewrite H5 in H8. discriminate.
- rewrite AssocMap.gso; auto.
- apply H2 in H5. auto. apply H2 in H5. auto.
- Unshelve. auto.
-Qed.
-#[local] Hint Resolve match_empty_assocmap_set : mgen.
-
-Lemma match_arrs_size_stmnt_preserved :
- forall m f rs1 ar1 ar2 c rs2,
- stmnt_runp f rs1 ar1 c rs2 ar2 ->
- match_empty_size m (assoc_nonblocking ar1) ->
- match_empty_size m (assoc_blocking ar1) ->
- match_empty_size m (assoc_nonblocking ar2) /\ match_empty_size m (assoc_blocking ar2).
-Proof.
- induction 1; inversion 1; inversion 1; eauto; simplify; try solve [repeat masrp_tac].
- subst. apply IHstmnt_runp2; apply IHstmnt_runp1; auto.
- apply IHstmnt_runp2; apply IHstmnt_runp1; auto.
- apply match_empty_assocmap_set. auto.
- apply match_empty_assocmap_set. auto.
-Qed.
-
-Lemma match_arrs_size_stmnt_preserved2 :
- forall m f rs1 na ba na' ba' c rs2,
- stmnt_runp f rs1 {| assoc_nonblocking := na; assoc_blocking := ba |} c rs2
- {| assoc_nonblocking := na'; assoc_blocking := ba' |} ->
- match_empty_size m na ->
- match_empty_size m ba ->
- match_empty_size m na' /\ match_empty_size m ba'.
-Proof.
- intros.
- remember ({| assoc_blocking := ba; assoc_nonblocking := na |}) as ar1.
- remember ({| assoc_blocking := ba'; assoc_nonblocking := na' |}) as ar2.
- assert (X1: na' = (assoc_nonblocking ar2)) by (rewrite Heqar2; auto). rewrite X1.
- assert (X2: ba' = (assoc_blocking ar2)) by (rewrite Heqar2; auto). rewrite X2.
- assert (X3: na = (assoc_nonblocking ar1)) by (rewrite Heqar1; auto). rewrite X3 in *.
- assert (X4: ba = (assoc_blocking ar1)) by (rewrite Heqar1; auto). rewrite X4 in *.
- eapply match_arrs_size_stmnt_preserved; mgen_crush.
-Qed.
-#[local] Hint Resolve match_arrs_size_stmnt_preserved2 : mgen.
-
-Lemma match_arrs_size_ram_preserved :
- forall m rs1 ar1 ar2 ram rs2,
- exec_ram rs1 ar1 ram rs2 ar2 ->
- match_empty_size m (assoc_nonblocking ar1) ->
- match_empty_size m (assoc_blocking ar1) ->
- match_empty_size m (assoc_nonblocking ar2)
- /\ match_empty_size m (assoc_blocking ar2).
-Proof.
- induction 1; inversion 1; inversion 1; subst; simplify; try solve [repeat masrp_tac].
- masrp_tac. masrp_tac. solve [repeat masrp_tac].
- masrp_tac. masrp_tac. masrp_tac. masrp_tac. masrp_tac. masrp_tac. masrp_tac.
- masrp_tac. masrp_tac. masrp_tac. masrp_tac. masrp_tac. masrp_tac. masrp_tac.
- masrp_tac. apply H8 in H1; inv_exists; simplify. repeat masrp_tac. auto.
- repeat masrp_tac.
- repeat masrp_tac.
- repeat masrp_tac.
- destruct (Pos.eq_dec (ram_mem r) s); subst; repeat masrp_tac.
- destruct (Pos.eq_dec (ram_mem r) s); subst; repeat masrp_tac.
- apply H9 in H17; auto. apply H9 in H17; auto.
- Unshelve. eauto.
-Qed.
-#[local] Hint Resolve match_arrs_size_ram_preserved : mgen.
-
-Lemma match_arrs_size_ram_preserved2 :
- forall m rs1 na na' ba ba' ram rs2,
- exec_ram rs1 {| assoc_nonblocking := na; assoc_blocking := ba |} ram rs2
- {| assoc_nonblocking := na'; assoc_blocking := ba' |} ->
- match_empty_size m na -> match_empty_size m ba ->
- match_empty_size m na' /\ match_empty_size m ba'.
-Proof.
- intros.
- remember ({| assoc_blocking := ba; assoc_nonblocking := na |}) as ar1.
- remember ({| assoc_blocking := ba'; assoc_nonblocking := na' |}) as ar2.
- assert (X1: na' = (assoc_nonblocking ar2)) by (rewrite Heqar2; auto). rewrite X1.
- assert (X2: ba' = (assoc_blocking ar2)) by (rewrite Heqar2; auto). rewrite X2.
- assert (X3: na = (assoc_nonblocking ar1)) by (rewrite Heqar1; auto). rewrite X3 in *.
- assert (X4: ba = (assoc_blocking ar1)) by (rewrite Heqar1; auto). rewrite X4 in *.
- eapply match_arrs_size_ram_preserved; mgen_crush.
-Qed.
-#[local] Hint Resolve match_arrs_size_ram_preserved2 : mgen.
-
-Lemma empty_stack_m :
- forall m, empty_stack m = empty_stack' (mod_stk_len m) (mod_stk m).
-Proof. unfold empty_stack, empty_stack'; mgen_crush. Qed.
-#[local] Hint Rewrite empty_stack_m : mgen.
-
-Ltac clear_forall :=
- repeat match goal with
- | H: context[forall _, _] |- _ => clear H
- end.
-
-Lemma list_combine_none :
- forall n l,
- length l = n ->
- list_combine Verilog.merge_cell (list_repeat None n) l = l.
-Proof.
- induction n; intros; crush.
- - symmetry. apply length_zero_iff_nil. auto.
- - destruct l; crush.
- rewrite list_repeat_cons.
- crush. f_equal.
- eauto.
-Qed.
-
-Lemma combine_none :
- forall n a,
- a.(arr_length) = n ->
- arr_contents (combine Verilog.merge_cell (arr_repeat None n) a) = arr_contents a.
-Proof.
- intros.
- unfold combine.
- crush.
-
- rewrite <- (arr_wf a) in H.
- apply list_combine_none.
- assumption.
-Qed.
-
-Lemma combine_none2 :
- forall n a addr,
- arr_length a = n ->
- array_get_error addr (combine Verilog.merge_cell (arr_repeat None n) a)
- = array_get_error addr a.
-Proof. intros; auto using array_get_error_equal, combine_none. Qed.
-
-Lemma list_combine_lookup_first :
- forall l1 l2 n,
- length l1 = length l2 ->
- nth_error l1 n = Some None ->
- nth_error (list_combine Verilog.merge_cell l1 l2) n = nth_error l2 n.
-Proof.
- induction l1; intros; crush.
-
- rewrite nth_error_nil in H0.
- discriminate.
-
- destruct l2 eqn:EQl2. crush.
- simpl in H. inv H.
- destruct n; simpl in *.
- inv H0. simpl. reflexivity.
- eauto.
-Qed.
-
-Lemma combine_lookup_first :
- forall a1 a2 n,
- a1.(arr_length) = a2.(arr_length) ->
- array_get_error n a1 = Some None ->
- array_get_error n (combine Verilog.merge_cell a1 a2) = array_get_error n a2.
-Proof.
- intros.
-
- unfold array_get_error in *.
- apply list_combine_lookup_first; eauto.
- rewrite a1.(arr_wf). rewrite a2.(arr_wf).
- assumption.
-Qed.
-
-Lemma list_combine_lookup_second :
- forall l1 l2 n x,
- length l1 = length l2 ->
- nth_error l1 n = Some (Some x) ->
- nth_error (list_combine Verilog.merge_cell l1 l2) n = Some (Some x).
-Proof.
- induction l1; intros; crush; auto.
-
- destruct l2 eqn:EQl2. crush.
- simpl in H. inv H.
- destruct n; simpl in *.
- inv H0. simpl. reflexivity.
- eauto.
-Qed.
-
-Lemma combine_lookup_second :
- forall a1 a2 n x,
- a1.(arr_length) = a2.(arr_length) ->
- array_get_error n a1 = Some (Some x) ->
- array_get_error n (combine Verilog.merge_cell a1 a2) = Some (Some x).
-Proof.
- intros.
-
- unfold array_get_error in *.
- apply list_combine_lookup_second; eauto.
- rewrite a1.(arr_wf). rewrite a2.(arr_wf).
- assumption.
-Qed.
-
-Lemma match_get_arrs2 :
- forall a i v l,
- length a = l ->
- list_combine merge_cell (list_set i (Some v) (list_repeat None l)) a =
- list_combine merge_cell (list_repeat None l) (list_set i (Some v) a).
-Proof.
- induction a; crush; subst.
- - destruct i. unfold list_repeat. unfold list_repeat'. auto.
- unfold list_repeat. unfold list_repeat'. auto.
- - destruct i.
- rewrite list_repeat_cons. simplify. auto.
- rewrite list_repeat_cons. simplify. f_equal. apply IHa. auto.
-Qed.
-
-Lemma match_get_arrs :
- forall addr i v x4 x x3,
- x4 = arr_length x ->
- x4 = arr_length x3 ->
- array_get_error addr (combine merge_cell (array_set i (Some v) (arr_repeat None x4))
- (combine merge_cell x x3))
- = array_get_error addr (combine merge_cell (arr_repeat None x4)
- (array_set i (Some v) (combine merge_cell x x3))).
-Proof.
- intros. apply array_get_error_equal. unfold combine. simplify.
- destruct x; destruct x3; simplify.
- apply match_get_arrs2. rewrite list_combine_length. subst.
- rewrite H0. lia.
-Qed.
-
-Lemma combine_array_set' :
- forall a b i v,
- length a = length b ->
- list_combine merge_cell (list_set i (Some v) a) b =
- list_set i (Some v) (list_combine merge_cell a b).
-Proof.
- induction a; simplify; crush.
- - destruct i; crush.
- - destruct i; destruct b; crush.
- f_equal. apply IHa. auto.
-Qed.
-
-Lemma combine_array_set :
- forall a b i v addr,
- arr_length a = arr_length b ->
- array_get_error addr (combine merge_cell (array_set i (Some v) a) b)
- = array_get_error addr (array_set i (Some v) (combine merge_cell a b)).
-Proof.
- intros. destruct a; destruct b. unfold array_set. simplify.
- unfold array_get_error. simplify. f_equal.
- apply combine_array_set'. crush.
-Qed.
-
-Lemma array_get_combine' :
- forall a b a' b' addr,
- length a = length b ->
- length a = length b' ->
- length a = length a' ->
- nth_error a addr = nth_error a' addr ->
- nth_error b addr = nth_error b' addr ->
- nth_error (list_combine merge_cell a b) addr =
- nth_error (list_combine merge_cell a' b') addr.
-Proof.
- induction a; crush.
- - destruct b; crush; destruct b'; crush; destruct a'; crush.
- - destruct b; crush; destruct b'; crush; destruct a'; crush;
- destruct addr; crush; apply IHa.
-Qed.
-
-Lemma array_get_combine :
- forall a b a' b' addr,
- arr_length a = arr_length b ->
- arr_length a = arr_length b' ->
- arr_length a = arr_length a' ->
- array_get_error addr a = array_get_error addr a' ->
- array_get_error addr b = array_get_error addr b' ->
- array_get_error addr (combine merge_cell a b)
- = array_get_error addr (combine merge_cell a' b').
-Proof.
- intros; unfold array_get_error, combine in *; destruct a; destruct b;
- destruct a'; destruct b'; simplify; apply array_get_combine'; crush.
-Qed.
-
-Lemma match_empty_size_exists_Some :
- forall m rab s v,
- match_empty_size m rab ->
- rab ! s = Some v ->
- exists v', (empty_stack m) ! s = Some v' /\ arr_length v = arr_length v'.
-Proof. inversion 1; intros; repeat masrp_tac. Qed.
-
-Lemma match_empty_size_exists_None :
- forall m rab s,
- match_empty_size m rab ->
- rab ! s = None ->
- (empty_stack m) ! s = None.
-Proof. inversion 1; intros; repeat masrp_tac. Qed.
-
-Lemma match_empty_size_exists_None' :
- forall m rab s,
- match_empty_size m rab ->
- (empty_stack m) ! s = None ->
- rab ! s = None.
-Proof. inversion 1; intros; repeat masrp_tac. Qed.
-
-Lemma match_empty_size_exists_Some' :
- forall m rab s v,
- match_empty_size m rab ->
- (empty_stack m) ! s = Some v ->
- exists v', rab ! s = Some v' /\ arr_length v = arr_length v'.
-Proof. inversion 1; intros; repeat masrp_tac. Qed.
-
-Lemma match_arrs_Some :
- forall ra ra' s v,
- match_arrs ra ra' ->
- ra ! s = Some v ->
- exists v', ra' ! s = Some v'
- /\ (forall addr, array_get_error addr v = array_get_error addr v')
- /\ arr_length v = arr_length v'.
-Proof. inversion 1; intros; repeat masrp_tac. intros. rewrite H5. auto. Qed.
-
-Lemma match_arrs_None :
- forall ra ra' s,
- match_arrs ra ra' ->
- ra ! s = None ->
- ra' ! s = None.
-Proof. inversion 1; intros; repeat masrp_tac. Qed.
-
-Ltac learn_next :=
- match goal with
- | H: match_empty_size _ ?rab, H2: ?rab ! _ = Some _ |- _ =>
- let H3 := fresh "H" in
- learn H2 as H3; eapply match_empty_size_exists_Some in H3;
- eauto; inv_exists; simplify
- | H: match_empty_size _ ?rab, H2: ?rab ! _ = None |- _ =>
- let H3 := fresh "H" in
- learn H2 as H3; eapply match_empty_size_exists_None in H3; eauto
- end.
-
-Ltac learn_empty :=
- match goal with
- | H: match_empty_size _ _, H2: (empty_stack _) ! _ = Some _ |- _ =>
- let H3 := fresh "H" in
- learn H as H3; eapply match_empty_size_exists_Some' in H3;
- [| eassumption]; inv_exists; simplify
- | H: match_arrs ?ar _, H2: ?ar ! _ = Some _ |- _ =>
- let H3 := fresh "H" in
- learn H as H3; eapply match_arrs_Some in H3;
- [| eassumption]; inv_exists; simplify
- | H: match_empty_size _ _, H2: (empty_stack _) ! _ = None |- _ =>
- let H3 := fresh "H" in
- learn H as H3; eapply match_empty_size_exists_None' in H3;
- [| eassumption]; simplify
- end.
-
-Lemma empty_set_none :
- forall m ran rab s i v s0,
- match_empty_size m ran ->
- match_empty_size m rab ->
- (arr_assocmap_set s i v ran) ! s0 = None ->
- (arr_assocmap_set s i v rab) ! s0 = None.
-Proof.
- unfold arr_assocmap_set; inversion 1; subst; simplify.
- destruct (Pos.eq_dec s s0); subst.
- destruct ran ! s0 eqn:?.
- rewrite AssocMap.gss in H4. inv H4.
- learn_next. learn_empty. rewrite H6; auto.
- destruct ran ! s eqn:?. rewrite AssocMap.gso in H4.
- learn_next. learn_empty. rewrite H6. rewrite AssocMap.gso.
- repeat match goal with
- | H: Learnt _ |- _ => clear H
- end. clear Heqo. clear H5. clear H6.
- learn_next. repeat learn_empty. auto. auto. auto.
- pose proof Heqo. learn_next; repeat learn_empty.
- repeat match goal with
- | H: Learnt _ |- _ => clear H
- end.
- pose proof H4. learn_next; repeat learn_empty.
- rewrite H7. auto.
-Qed.
-
-Ltac clear_learnt :=
- repeat match goal with
- | H: Learnt _ |- _ => clear H
- end.
-
-Lemma match_arrs_size_assoc :
- forall a b,
- match_arrs_size a b ->
- match_arrs_size b a.
-Proof. inversion 1; constructor; crush; split; apply H2. Qed.
-#[local] Hint Resolve match_arrs_size_assoc : mgen.
-
-Lemma match_arrs_merge_set2 :
- forall rab rab' ran ran' s m i v,
- match_empty_size m rab ->
- match_empty_size m ran ->
- match_empty_size m rab' ->
- match_empty_size m ran' ->
- match_arrs rab rab' ->
- match_arrs ran ran' ->
- match_arrs (merge_arrs (arr_assocmap_set s i v ran) rab)
- (merge_arrs (arr_assocmap_set s i v (empty_stack m))
- (merge_arrs ran' rab')).
-Proof.
- simplify.
- constructor; intros.
- unfold arr_assocmap_set in *. destruct (Pos.eq_dec s s0); subst.
- destruct ran ! s0 eqn:?. unfold merge_arrs in *. rewrite AssocMap.gcombine in *; auto.
- learn_next. repeat learn_empty.
- econstructor. simplify. rewrite H6. rewrite AssocMap.gcombine by auto.
- rewrite AssocMap.gss. simplify. setoid_rewrite H9. setoid_rewrite H7. simplify.
- intros. rewrite AssocMap.gss in H5. setoid_rewrite H13 in H5.
- simplify. pose proof (empty_arr m s0). inv H5. inv_exists. setoid_rewrite H5 in H6. inv H6.
- unfold arr_repeat in H8. simplify. rewrite list_repeat_len in H8. rewrite list_repeat_len in H10.
- rewrite match_get_arrs. crush. rewrite combine_none2. rewrite combine_array_set; try congruence.
- apply array_get_error_each. rewrite combine_length; try congruence.
- rewrite combine_length; try congruence.
- apply array_get_combine; crush.
- rewrite <- array_set_len. rewrite combine_length; crush. crush. crush.
- setoid_rewrite H21 in H6; discriminate. rewrite combine_length.
- rewrite <- array_set_len; crush.
- unfold merge_arr in *. rewrite AssocMap.gss in H5. setoid_rewrite H13 in H5.
- inv H5. rewrite combine_length. rewrite <- array_set_len; crush.
- rewrite <- array_set_len; crush.
- rewrite combine_length; crush.
- destruct rab ! s0 eqn:?. learn_next. repeat learn_empty.
- rewrite H11 in Heqo. discriminate.
- unfold merge_arrs in H5. rewrite AssocMap.gcombine in H5; auto. rewrite Heqo in H5.
- rewrite Heqo0 in H5. crush.
-
- destruct ran ! s eqn:?.
- learn_next. repeat learn_empty. rewrite H6.
- unfold merge_arrs in *. rewrite AssocMap.gcombine in H5; auto.
- rewrite AssocMap.gcombine; auto. rewrite AssocMap.gso in H5; auto.
- rewrite AssocMap.gso; auto.
- destruct ran ! s0 eqn:?.
- learn_next.
- repeat match goal with
- | H: Learnt _ |- _ => clear H
- end.
- repeat learn_empty.
- repeat match goal with
- | H: Learnt _ |- _ => clear H
- end.
- rewrite AssocMap.gcombine; auto. setoid_rewrite Heqo0 in H5. setoid_rewrite H29 in H5.
- simplify.
- pose proof (empty_arr m s0). inv H5. inv_exists. rewrite H5 in H21. inv H21.
- econstructor. simplify. setoid_rewrite H23. rewrite H25. setoid_rewrite H5.
- simplify. intros. rewrite combine_none2. apply array_get_combine; solve [crush].
- crush. rewrite list_combine_length. rewrite (arr_wf x5). rewrite (arr_wf x6).
- rewrite <- H26. rewrite <- H28. rewrite list_repeat_len. lia. rewrite list_combine_length.
- rewrite (arr_wf a). rewrite (arr_wf x7). rewrite combine_length. rewrite arr_repeat_length.
- rewrite H24. rewrite <- H32. rewrite list_repeat_len. lia.
- rewrite arr_repeat_length. rewrite combine_length. rewrite <- H26. symmetry. apply list_repeat_len.
- congruence.
- rewrite H37 in H21; discriminate.
- repeat match goal with
- | H: Learnt _ |- _ => clear H
- end. eapply match_empty_size_exists_None in H0; eauto.
- clear H6. repeat learn_empty. setoid_rewrite Heqo0 in H5.
- setoid_rewrite H29 in H5. discriminate.
- pose proof (match_arrs_merge ran ran' rab rab').
- eapply match_empty_size_match in H; [|apply H0].
- apply H6 in H; auto. inv H. apply H7 in H5. inv_exists. simplify.
- learn_next. rewrite H9. econstructor. simplify.
- apply merge_arr_empty''; mgen_crush.
- auto. auto.
- unfold merge_arrs in *. rewrite AssocMap.gcombine in H5; auto. rewrite AssocMap.gcombine; auto.
- destruct (arr_assocmap_set s i v ran) ! s0 eqn:?; destruct rab ! s0 eqn:?; crush.
- learn_next. repeat learn_empty.
- repeat match goal with
- | H: Learnt _ |- _ => clear H
- end.
- erewrite empty_set_none. rewrite AssocMap.gcombine; auto.
- simplify. rewrite H7. rewrite H8. auto. apply H0. mgen_crush. auto.
-Qed.
-
-Definition all_match_empty_size m ar :=
- match_empty_size m (assoc_nonblocking ar) /\ match_empty_size m (assoc_blocking ar).
-#[local] Hint Unfold all_match_empty_size : mgen.
-
-Definition match_module_to_ram m ram :=
- ram_size ram = mod_stk_len m /\ ram_mem ram = mod_stk m.
-#[local] Hint Unfold match_module_to_ram : mgen.
-
-Lemma zip_range_forall_le :
- forall A (l: list A) n, Forall (Pos.le n) (map snd (zip_range n l)).
-Proof.
- induction l; crush; constructor; [lia|].
- assert (forall n x, n+1 <= x -> n <= x) by lia.
- apply Forall_forall. intros. apply H. generalize dependent x.
- apply Forall_forall. apply IHl.
-Qed.
-
-Lemma transf_code_fold_correct:
- forall l m state ram d' c' n,
- fold_right (transf_maps state ram) (mod_datapath m, mod_controllogic m) l = (d', c') ->
- Forall (fun x => x < n) (map fst l) ->
- Forall (Pos.le n) (map snd l) ->
- list_norepet (map fst l) ->
- list_norepet (map snd l) ->
- (forall p i c_s rs1 ar1 rs2 ar2 trs1 tar1 d_s,
- i < n ->
- all_match_empty_size m ar1 ->
- all_match_empty_size m tar1 ->
- match_module_to_ram m ram ->
- (mod_datapath m)!i = Some d_s ->
- (mod_controllogic m)!i = Some c_s ->
- match_reg_assocs p rs1 trs1 ->
- match_arr_assocs ar1 tar1 ->
- max_reg_module m < p ->
- exec_all d_s c_s rs1 ar1 rs2 ar2 ->
- exists d_s' c_s' trs2 tar2,
- d'!i = Some d_s' /\ c'!i = Some c_s'
- /\ exec_all_ram ram d_s' c_s' trs1 tar1 trs2 tar2
- /\ match_reg_assocs p (merge_reg_assocs rs2) (merge_reg_assocs trs2)
- /\ match_arr_assocs (merge_arr_assocs (ram_mem ram) (ram_size ram) ar2)
- (merge_arr_assocs (ram_mem ram) (ram_size ram) tar2)).
-Proof.
- induction l as [| a l IHl]; simplify.
- - match goal with
- | H: (_, _) = (_, _) |- _ => inv H
- end;
- unfold exec_all in *; repeat inv_exists; simplify.
- exploit match_states_same;
- try match goal with
- | H: stmnt_runp _ _ _ ?c _ _, H2: (mod_controllogic _) ! _ = Some ?c |- _ => apply H
- end; eauto; mgen_crush;
- try match goal with
- | H: (mod_controllogic _) ! _ = Some ?c |- _ =>
- apply max_reg_stmnt_le_stmnt_tree in H; unfold max_reg_module in *; lia
- end; intros;
- exploit match_states_same;
- try match goal with
- | H: stmnt_runp _ _ _ ?c _ _, H2: (mod_datapath _) ! _ = Some ?c |- _ => apply H
- end; eauto; mgen_crush;
- try match goal with
- | H: (mod_datapath _) ! _ = Some ?c |- _ =>
- apply max_reg_stmnt_le_stmnt_tree in H; unfold max_reg_module in *; lia
- end; intros;
- repeat match goal with
- | |- exists _, _ => eexists
- end; simplify; eauto;
- unfold exec_all_ram;
- repeat match goal with
- | |- exists _, _ => eexists
- end; simplify; eauto.
- constructor. admit.
- Abort.
-
-Lemma empty_stack_transf : forall m, empty_stack (transf_module m) = empty_stack m.
-Proof. unfold empty_stack, transf_module; intros; repeat destruct_match; crush. Qed.
-
-Definition alt_unchanged (d : AssocMap.t stmnt) (c: AssocMap.t stmnt) d' c' i :=
- d ! i = d' ! i /\ c ! i = c' ! i.
-
-Definition alt_store ram d (c : AssocMap.t stmnt) d' c' i :=
- exists e1 e2,
- d' ! i = Some (Vseq (Vnonblock (Vvar (ram_u_en ram)) (Vunop Vnot (Vvar (ram_u_en ram))))
- (Vseq (Vnonblock (Vvar (ram_wr_en ram)) (Vlit (ZToValue 1)))
- (Vseq (Vnonblock (Vvar (ram_d_in ram)) e2)
- (Vnonblock (Vvar (ram_addr ram)) e1))))
- /\ c' ! i = c ! i
- /\ d ! i = Some (Vnonblock (Vvari (ram_mem ram) e1) e2).
-
-Definition alt_load state ram d (c : AssocMap.t stmnt) d' c' i n :=
- exists ns e1 e2,
- d' ! i = Some (Vseq (Vnonblock (Vvar (ram_u_en ram)) (Vunop Vnot (Vvar (ram_u_en ram))))
- (Vseq (Vnonblock (Vvar (ram_wr_en ram)) (Vlit (ZToValue 0)))
- (Vnonblock (Vvar (ram_addr ram)) e2)))
- /\ d' ! n = Some (Vnonblock (Vvar e1) (Vvar (ram_d_out ram)))
- /\ c' ! i = Some (Vnonblock (Vvar state) (Vlit (posToValue n)))
- /\ c' ! n = Some (Vnonblock (Vvar state) ns)
- /\ c ! i = Some (Vnonblock (Vvar state) ns)
- /\ d ! i = Some (Vnonblock (Vvar e1) (Vvari (ram_mem ram) e2))
- /\ e1 < state
- /\ max_reg_expr e2 < state
- /\ max_reg_expr ns < state
- /\ (Z.pos n <= Int.max_unsigned)%Z.
-
-Definition alternatives state ram d c d' c' i n :=
- alt_unchanged d c d' c' i
- \/ alt_store ram d c d' c' i
- \/ alt_load state ram d c d' c' i n.
-
-Lemma transf_alternatives :
- forall ram n d c state i d' c',
- transf_maps state ram (i, n) (d, c) = (d', c') ->
- i <> n ->
- alternatives state ram d c d' c' i n.
-Proof.
- intros. unfold transf_maps in *.
- repeat destruct_match; match goal with
- | H: (_, _) = (_, _) |- _ => inv H
- end; try solve [left; econstructor; crush]; simplify;
- repeat match goal with
- | H: (_ =? _) = true |- _ => apply Peqb_true_eq in H; subst
- end; unfold alternatives; right;
- match goal with
- | H: context[Vnonblock (Vvari _ _) _] |- _ => left
- | _ => right
- end; repeat econstructor; simplify;
- repeat match goal with
- | |- ( _ # ?s <- _ ) ! ?s = Some _ => apply AssocMap.gss
- | |- ( _ # ?s <- _ ) ! ?r = Some _ => rewrite AssocMap.gso by lia
- | |- _ = None => apply max_index_2; lia
- | H: context[_ <? _] |- _ => apply Pos.ltb_lt in H
- end; auto.
-Qed.
-
-Lemma transf_alternatives_neq :
- forall state ram a n' n d'' c'' d' c' i d c,
- transf_maps state ram (a, n) (d, c) = (d', c') ->
- a <> i -> n' <> n -> i <> n' -> a <> n' ->
- i <> n -> a <> n ->
- alternatives state ram d'' c'' d c i n' ->
- alternatives state ram d'' c'' d' c' i n'.
-Proof.
- unfold alternatives, alt_unchanged, alt_store, alt_load, transf_maps; intros;
- repeat match goal with H: _ \/ _ |- _ => inv H | H: _ /\ _ |- _ => destruct H end;
- [left | right; left | right; right];
- repeat inv_exists; simplify;
- repeat destruct_match;
- repeat match goal with
- | H: (_, _) = (_, _) |- _ => inv H
- | |- exists _, _ => econstructor
- end; repeat split; repeat rewrite AssocMap.gso by lia; eauto; lia.
-Qed.
-
-Lemma transf_alternatives_neq2 :
- forall state ram a n' n d'' c'' d' c' i d c,
- transf_maps state ram (a, n) (d', c') = (d, c) ->
- a <> i -> n' <> n -> i <> n' -> a <> n' -> i <> n ->
- alternatives state ram d c d'' c'' i n' ->
- alternatives state ram d' c' d'' c'' i n'.
-Proof.
- unfold alternatives, alt_unchanged, alt_store, alt_load, transf_maps; intros;
- repeat match goal with H: _ \/ _ |- _ => inv H | H: _ /\ _ |- _ => destruct H end;
- [left | right; left | right; right];
- repeat inv_exists; simplify;
- repeat destruct_match;
- repeat match goal with
- | H: (_, _) = (_, _) |- _ => inv H
- | |- exists _, _ => econstructor
- end; repeat split; repeat rewrite AssocMap.gso in * by lia; eauto; lia.
-Qed.
-
-Lemma transf_alt_unchanged_neq :
- forall i c'' d'' d c d' c',
- alt_unchanged d' c' d'' c'' i ->
- d' ! i = d ! i ->
- c' ! i = c ! i ->
- alt_unchanged d c d'' c'' i.
-Proof. unfold alt_unchanged; simplify; congruence. Qed.
-
-Lemma transf_maps_neq :
- forall state ram d c i n d' c' i' n' va vb vc vd,
- transf_maps state ram (i, n) (d, c) = (d', c') ->
- d ! i' = va -> d ! n' = vb ->
- c ! i' = vc -> c ! n' = vd ->
- i <> i' -> i <> n' -> n <> i' -> n <> n' ->
- d' ! i' = va /\ d' ! n' = vb /\ c' ! i' = vc /\ c' ! n' = vd.
-Proof.
- unfold transf_maps; intros; repeat destruct_match; simplify;
- repeat match goal with
- | H: (_, _) = (_, _) |- _ => inv H
- | H: (_ =? _) = true |- _ => apply Peqb_true_eq in H; subst
- | |- context[( _ # ?s <- _ ) ! ?r] => rewrite AssocMap.gso by lia
- end; crush.
-Qed.
-
-Lemma alternatives_different_map :
- forall l state ram d c d'' c'' d' c' n i p,
- i <= p -> n > p ->
- Forall (Pos.lt p) (map snd l) ->
- Forall (Pos.ge p) (map fst l) ->
- ~ In n (map snd l) ->
- ~ In i (map fst l) ->
- fold_right (transf_maps state ram) (d, c) l = (d', c') ->
- alternatives state ram d' c' d'' c'' i n ->
- alternatives state ram d c d'' c'' i n.
-Proof.
- Opaque transf_maps.
- induction l; intros.
- - crush.
- - simplify; repeat match goal with
- | H: context[_ :: _] |- _ => inv H
- | H: transf_maps _ _ _ (fold_right (transf_maps ?s ?r) (?d, ?c) ?l) = (_, _) |- _ =>
- let X := fresh "X" in
- remember (fold_right (transf_maps s r) (d, c) l) as X
- | X: _ * _ |- _ => destruct X
- | H: (_, _) = _ |- _ => symmetry in H
- end; simplify.
- remember p0 as i'. symmetry in Heqi'. subst.
- remember p1 as n'. symmetry in Heqn'. subst.
- assert (i <> n') by lia.
- assert (n <> i') by lia.
- assert (n <> n') by lia.
- assert (i <> i') by lia.
- eapply IHl; eauto.
- eapply transf_alternatives_neq2; eauto; try lia.
-Qed.
-
-Lemma transf_fold_alternatives :
- forall l state ram d c d' c' i n d_s c_s,
- fold_right (transf_maps state ram) (d, c) l = (d', c') ->
- Pos.max (max_pc c) (max_pc d) < n ->
- Forall (Pos.lt (Pos.max (max_pc c) (max_pc d))) (map snd l) ->
- Forall (Pos.ge (Pos.max (max_pc c) (max_pc d))) (map fst l) ->
- list_norepet (map fst l) ->
- list_norepet (map snd l) ->
- In (i, n) l ->
- d ! i = Some d_s ->
- c ! i = Some c_s ->
- alternatives state ram d c d' c' i n.
-Proof.
- Opaque transf_maps.
- induction l; crush; [].
- repeat match goal with
- | H: context[_ :: _] |- _ => inv H
- | H: transf_maps _ _ _ (fold_right (transf_maps ?s ?r) (?d, ?c) ?l) = (_, _) |- _ =>
- let X := fresh "X" in
- remember (fold_right (transf_maps s r) (d, c) l) as X
- | X: _ * _ |- _ => destruct X
- | H: (_, _) = _ |- _ => symmetry in H
- end.
- inv H5. inv H1. simplify.
- eapply alternatives_different_map; eauto.
- simplify; lia. simplify; lia. apply transf_alternatives; auto. lia.
- simplify.
- assert (X: In i (map fst l)). { replace i with (fst (i, n)) by auto. apply in_map; auto. }
- assert (X2: In n (map snd l)). { replace n with (snd (i, n)) by auto. apply in_map; auto. }
- assert (X3: n <> p0). { destruct (Pos.eq_dec n p0); subst; crush. }
- assert (X4: i <> p). { destruct (Pos.eq_dec i p); subst; crush. }
- eapply transf_alternatives_neq; eauto; apply max_index in H7; lia.
- Transparent transf_maps.
-Qed.
-
-Lemma zip_range_inv :
- forall A (l: list A) i n,
- In i l ->
- exists n', In (i, n') (zip_range n l) /\ n' >= n.
-Proof.
- induction l; crush.
- inv H. econstructor.
- split. left. eauto. lia.
- eapply IHl in H0. inv H0. inv H.
- econstructor. split. right. apply H0. lia.
-Qed.
-
-Lemma zip_range_not_in_fst :
- forall A (l: list A) a n, ~ In a l -> ~ In a (map fst (zip_range n l)).
-Proof. unfold not; induction l; crush; inv H0; firstorder. Qed.
-
-Lemma zip_range_no_repet_fst :
- forall A (l: list A) a, list_norepet l -> list_norepet (map fst (zip_range a l)).
-Proof.
- induction l; simplify; constructor; inv H; firstorder;
- eapply zip_range_not_in_fst; auto.
-Qed.
-
-Lemma transf_code_alternatives :
- forall state ram d c d' c' i d_s c_s,
- transf_code state ram d c = (d', c') ->
- d ! i = Some d_s ->
- c ! i = Some c_s ->
- exists n, alternatives state ram d c d' c' i n.
-Proof.
- unfold transf_code;
- intros.
- pose proof H0 as X.
- apply PTree.elements_correct in X. assert (In i (map fst (PTree.elements d))).
- { replace i with (fst (i, d_s)) by auto. apply in_map. auto. }
- exploit zip_range_inv. apply H2. intros. inv H3. simplify.
- instantiate (1 := (Pos.max (max_pc c) (max_pc d) + 1)) in H3.
- exists x.
- eapply transf_fold_alternatives;
- eauto using forall_gt, PTree.elements_keys_norepet, max_index. lia.
- assert (Forall (Pos.le (Pos.max (max_pc c) (max_pc d) + 1))
- (map snd (zip_range (Pos.max (max_pc c) (max_pc d) + 1)
- (map fst (PTree.elements d))))) by apply zip_range_forall_le.
- apply Forall_forall; intros. eapply Forall_forall in H4; eauto. lia.
- rewrite zip_range_fst_idem. apply Forall_forall; intros.
- apply AssocMapExt.elements_iff in H4. inv H4. apply max_index in H6. lia.
- eapply zip_range_no_repet_fst. apply PTree.elements_keys_norepet.
- eapply zip_range_snd_no_repet.
-Qed.
-
-Lemma max_reg_stmnt_not_modified :
- forall s f rs ar rs' ar',
- stmnt_runp f rs ar s rs' ar' ->
- forall r,
- max_reg_stmnt s < r ->
- (assoc_blocking rs) ! r = (assoc_blocking rs') ! r.
-Proof.
- induction 1; crush;
- try solve [repeat destruct_match; apply IHstmnt_runp; try lia; auto].
- assert (X: (assoc_blocking asr1) ! r = (assoc_blocking asr2) ! r) by (apply IHstmnt_runp2; lia).
- assert (X2: (assoc_blocking asr0) ! r = (assoc_blocking asr1) ! r) by (apply IHstmnt_runp1; lia).
- congruence.
- inv H. simplify. rewrite AssocMap.gso by lia; auto.
-Qed.
-
-Lemma max_reg_stmnt_not_modified_nb :
- forall s f rs ar rs' ar',
- stmnt_runp f rs ar s rs' ar' ->
- forall r,
- max_reg_stmnt s < r ->
- (assoc_nonblocking rs) ! r = (assoc_nonblocking rs') ! r.
-Proof.
- induction 1; crush;
- try solve [repeat destruct_match; apply IHstmnt_runp; try lia; auto].
- assert (X: (assoc_nonblocking asr1) ! r = (assoc_nonblocking asr2) ! r) by (apply IHstmnt_runp2; lia).
- assert (X2: (assoc_nonblocking asr0) ! r = (assoc_nonblocking asr1) ! r) by (apply IHstmnt_runp1; lia).
- congruence.
- inv H. simplify. rewrite AssocMap.gso by lia; auto.
-Qed.
-
-Lemma int_eq_not_changed :
- forall ar ar' r r2 b,
- Int.eq (ar # r) (ar # r2) = b ->
- ar ! r = ar' ! r ->
- ar ! r2 = ar' ! r2 ->
- Int.eq (ar' # r) (ar' # r2) = b.
-Proof.
- unfold find_assocmap, AssocMapExt.get_default. intros.
- rewrite <- H0. rewrite <- H1. auto.
-Qed.
-
-Lemma merge_find_assocmap :
- forall ran rab x,
- ran ! x = None ->
- (merge_regs ran rab) # x = rab # x.
-Proof.
- unfold merge_regs, find_assocmap, AssocMapExt.get_default.
- intros. destruct (rab ! x) eqn:?.
- erewrite AssocMapExt.merge_correct_2; eauto.
- erewrite AssocMapExt.merge_correct_3; eauto.
-Qed.
-
-Lemma max_reg_module_controllogic_gt :
- forall m i v p,
- (mod_controllogic m) ! i = Some v ->
- max_reg_module m < p ->
- max_reg_stmnt v < p.
-Proof.
- intros. unfold max_reg_module in *.
- apply max_reg_stmnt_le_stmnt_tree in H. lia.
-Qed.
-
-Lemma max_reg_module_datapath_gt :
- forall m i v p,
- (mod_datapath m) ! i = Some v ->
- max_reg_module m < p ->
- max_reg_stmnt v < p.
-Proof.
- intros. unfold max_reg_module in *.
- apply max_reg_stmnt_le_stmnt_tree in H. lia.
-Qed.
-
-Lemma merge_arr_empty2 :
- forall m ar ar',
- match_empty_size m ar' ->
- match_arrs ar ar' ->
- match_arrs ar (merge_arrs (empty_stack m) ar').
-Proof.
- inversion 1; subst; inversion 1; subst.
- econstructor; intros. apply H4 in H6; inv_exists. simplify.
- eapply merge_arr_empty'' in H6; eauto.
- (* apply H5 in H6. pose proof H6. apply H2 in H7. *)
-(* unfold merge_arrs. rewrite AssocMap.gcombine; auto. setoid_rewrite H6. *)
-(* setoid_rewrite H7. auto. *)
-(* Qed. *) Admitted.
-#[local] Hint Resolve merge_arr_empty2 : mgen.
-
-Lemma find_assocmap_gso :
- forall ar x y v, x <> y -> (ar # y <- v) # x = ar # x.
-Proof.
- unfold find_assocmap, AssocMapExt.get_default; intros; rewrite AssocMap.gso; auto.
-Qed.
-
-Lemma find_assocmap_gss :
- forall ar x v, (ar # x <- v) # x = v.
-Proof.
- unfold find_assocmap, AssocMapExt.get_default; intros; rewrite AssocMap.gss; auto.
-Qed.
-
-Lemma expr_lt_max_module_datapath :
- forall m x,
- max_reg_stmnt x <= max_stmnt_tree (mod_datapath m) ->
- max_reg_stmnt x < max_reg_module m + 1.
-Proof. unfold max_reg_module. lia. Qed.
-
-Lemma expr_lt_max_module_controllogic :
- forall m x,
- max_reg_stmnt x <= max_stmnt_tree (mod_controllogic m) ->
- max_reg_stmnt x < max_reg_module m + 1.
-Proof. unfold max_reg_module. lia. Qed.
-
-Lemma int_eq_not :
- forall x y, Int.eq x y = true -> Int.eq x (Int.not y) = false.
-Proof.
- intros. pose proof (Int.eq_spec x y). rewrite H in H0. subst.
- apply int_eq_not_false.
-Qed.
-
-Lemma match_assocmaps_gt2 :
- forall (p s : positive) (ra ra' : assocmap) (v : value),
- p <= s -> match_assocmaps p ra ra' -> match_assocmaps p (ra # s <- v) ra'.
-Proof.
- intros; inv H0; constructor; intros.
- destruct (Pos.eq_dec r s); subst. lia.
- rewrite AssocMap.gso by lia. auto.
-Qed.
-
-Lemma match_assocmaps_switch_neq :
- forall p ra ra' r v' s v,
- match_assocmaps p ra ((ra' # r <- v') # s <- v) ->
- s <> r ->
- match_assocmaps p ra ((ra' # s <- v) # r <- v').
-Proof.
- inversion 1; constructor; simplify.
- destruct (Pos.eq_dec r0 s); destruct (Pos.eq_dec r0 r); subst; try lia.
- rewrite AssocMap.gso by lia. specialize (H0 s). apply H0 in H5.
- rewrite AssocMap.gss in H5. rewrite AssocMap.gss. auto.
- rewrite AssocMap.gss. apply H0 in H5. rewrite AssocMap.gso in H5 by lia.
- rewrite AssocMap.gss in H5. auto.
- repeat rewrite AssocMap.gso by lia.
- apply H0 in H5. repeat rewrite AssocMap.gso in H5 by lia.
- auto.
-Qed.
-
-Lemma match_assocmaps_duplicate :
- forall p ra ra' v' s v,
- match_assocmaps p ra (ra' # s <- v) ->
- match_assocmaps p ra ((ra' # s <- v') # s <- v).
-Proof.
- inversion 1; constructor; simplify.
- destruct (Pos.eq_dec r s); subst.
- rewrite AssocMap.gss. apply H0 in H4. rewrite AssocMap.gss in H4. auto.
- repeat rewrite AssocMap.gso by lia. apply H0 in H4. rewrite AssocMap.gso in H4 by lia.
- auto.
-Qed.
-
-Ltac simplify := intros; unfold_constants; cbn in *;
- repeat (nicify_hypotheses; nicify_goals; kill_bools; substpp);
- cbn in *.
-
-Ltac simplify_val := repeat (simplify; unfold uvalueToZ, valueToPtr, Ptrofs.of_int, valueToInt, intToValue,
- ptrToValue in *).
-
-Ltac crush_val := simplify_val; try discriminate; try congruence; try lia; liapp; try assumption.
-
-Ltac crush := simplify; try discriminate; try congruence; try lia; liapp;
- try assumption; auto.
-
-Ltac mgen_crush_local := crush; eauto with mgen.
-
-Lemma translation_correct :
- forall m asr nasa1 basa1 nasr1 basr1 basr2 nasr2 nasa2 basa2 nasr3 basr3
- nasa3 basa3 asr'0 asa'0 res' st tge pstval sf asa ctrl data f,
- asr ! (mod_reset m) = Some (ZToValue 0) ->
- asr ! (mod_finish m) = Some (ZToValue 0) ->
- asr ! (mod_st m) = Some (posToValue st) ->
- (mod_controllogic m) ! st = Some ctrl ->
- (mod_datapath m) ! st = Some data ->
- stmnt_runp f {| assoc_blocking := asr; assoc_nonblocking := empty_assocmap |}
- {| assoc_blocking := asa; assoc_nonblocking := empty_stack m |} ctrl
- {| assoc_blocking := basr1; assoc_nonblocking := nasr1 |}
- {| assoc_blocking := basa1; assoc_nonblocking := nasa1 |} ->
- basr1 ! (mod_st m) = Some (posToValue st) ->
- stmnt_runp f {| assoc_blocking := basr1; assoc_nonblocking := nasr1 |}
- {| assoc_blocking := basa1; assoc_nonblocking := nasa1 |} data
- {| assoc_blocking := basr2; assoc_nonblocking := nasr2 |}
- {| assoc_blocking := basa2; assoc_nonblocking := nasa2 |} ->
- exec_ram {| assoc_blocking := merge_regs nasr2 basr2; assoc_nonblocking := empty_assocmap |}
- {| assoc_blocking := merge_arrs nasa2 basa2; assoc_nonblocking := empty_stack m |} None
- {| assoc_blocking := basr3; assoc_nonblocking := nasr3 |}
- {| assoc_blocking := basa3; assoc_nonblocking := nasa3 |} ->
- (merge_regs nasr3 basr3) ! (mod_st m) = Some (posToValue pstval) ->
- (Z.pos pstval <= 4294967295)%Z ->
- match_states (State sf m st asr asa) (State res' (transf_module m) st asr'0 asa'0) ->
- mod_ram m = None ->
- exists R2 : state,
- Smallstep.plus step tge (State res' (transf_module m) st asr'0 asa'0) Events.E0 R2 /\
- match_states (State sf m pstval (merge_regs nasr3 basr3) (merge_arrs nasa3 basa3)) R2.
-Proof.
- Ltac tac0 :=
- repeat match goal with
- | H: match_reg_assocs _ _ _ |- _ => inv H
- | H: match_arr_assocs _ _ |- _ => inv H
- end.
- intros.
- repeat match goal with
- | H: match_states _ _ |- _ => inv H
- | H: context[exec_ram] |- _ => inv H
- | H: mod_ram _ = None |- _ =>
- let H2 := fresh "TRANSF" in learn H as H2; apply transf_module_code in H2
- end.
- eapply transf_code_alternatives in TRANSF; eauto; simplify; unfold alternatives in *.
- repeat match goal with H: _ \/ _ |- _ => inv H end.
- - unfold alt_unchanged in *; simplify.
- assert (MATCH_SIZE1: match_empty_size m nasa1 /\ match_empty_size m basa1).
- { eapply match_arrs_size_stmnt_preserved2; eauto. unfold match_empty_size; eauto with mgen. }
- assert (MATCH_SIZE2: match_empty_size m nasa2 /\ match_empty_size m basa2).
- { eapply match_arrs_size_stmnt_preserved2; mgen_crush. } simplify.
- assert (MATCH_ARR3: match_arrs_size nasa2 basa2) by eauto with mgen.
- exploit match_states_same; try solve [apply H4 | eapply max_stmnt_lt_module; eauto
- | econstructor; eauto with mgen];
- intros; repeat inv_exists; simplify; tac0.
- exploit match_states_same; try solve [eapply H6 | eapply max_stmnt_lt_module; eauto
- | econstructor; eauto with mgen];
- intros; repeat inv_exists; simplify; tac0.
- assert (MATCH_SIZE1': match_empty_size m ran'0 /\ match_empty_size m rab'0).
- { eapply match_arrs_size_stmnt_preserved2; eauto. unfold match_empty_size; eauto with mgen.
- rewrite empty_stack_transf; eauto with mgen. }
- assert (MATCH_SIZE2': match_empty_size m ran'2 /\ match_empty_size m rab'2).
- { eapply match_arrs_size_stmnt_preserved2; mgen_crush. } simplify.
- assert (MATCH_ARR3': match_arrs_size ran'2 rab'2) by eauto with mgen.
- do 2 econstructor. apply Smallstep.plus_one. econstructor.
- eauto with mgen. eauto with mgen. eauto with mgen.
- rewrite <- H12. eassumption. rewrite <- H7. eassumption.
- eauto. eauto with mgen. eauto.
- rewrite empty_stack_transf. unfold transf_module; repeat destruct_match; try discriminate.
- econstructor. simplify.
- unfold disable_ram in *. unfold transf_module in DISABLE_RAM.
- repeat destruct_match; try discriminate; []. simplify.
- pose proof H17 as R1. apply max_reg_stmnt_not_modified with (r := max_reg_module m + 2) in R1.
- pose proof H17 as R2. eapply max_reg_stmnt_not_modified_nb with (r := max_reg_module m + 2) in R2.
- pose proof H18 as R3. eapply max_reg_stmnt_not_modified with (r := max_reg_module m + 2) in R3.
- pose proof H18 as R4. eapply max_reg_stmnt_not_modified_nb with (r := max_reg_module m + 2) in R4.
- pose proof H17 as R1'. apply max_reg_stmnt_not_modified with (r := max_reg_module m + 6) in R1'.
- pose proof H17 as R2'. eapply max_reg_stmnt_not_modified_nb with (r := max_reg_module m + 6) in R2'.
- pose proof H18 as R3'. eapply max_reg_stmnt_not_modified with (r := max_reg_module m + 6) in R3'.
- pose proof H18 as R4'. eapply max_reg_stmnt_not_modified_nb with (r := max_reg_module m + 6) in R4'.
- simplify.
- pose proof DISABLE_RAM as DISABLE_RAM1.
- eapply int_eq_not_changed with (ar' := rab') in DISABLE_RAM; try congruence.
- eapply int_eq_not_changed with (ar' := rab'1) in DISABLE_RAM; try congruence.
- rewrite AssocMap.gempty in R2. rewrite <- R2 in R4.
- rewrite AssocMap.gempty in R2'. rewrite <- R2' in R4'.
- eapply int_eq_not_changed in DISABLE_RAM; auto. repeat (rewrite merge_find_assocmap; try congruence).
- eapply max_reg_module_datapath_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_datapath_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_controllogic_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_controllogic_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_datapath_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_datapath_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_controllogic_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_controllogic_gt; eauto; remember (max_reg_module m); lia.
- auto. auto. eauto with mgen. auto.
- econstructor; mgen_crush_local. apply merge_arr_empty; mgen_crush_local.
- unfold disable_ram in *. unfold transf_module in DISABLE_RAM.
- repeat destruct_match; crush. unfold transf_module in Heqo; repeat destruct_match; crush.
- pose proof H17 as R1. apply max_reg_stmnt_not_modified with (r := max_reg_module m + 2) in R1.
- pose proof H17 as R2. eapply max_reg_stmnt_not_modified_nb with (r := max_reg_module m + 2) in R2.
- pose proof H18 as R3. eapply max_reg_stmnt_not_modified with (r := max_reg_module m + 2) in R3.
- pose proof H18 as R4. eapply max_reg_stmnt_not_modified_nb with (r := max_reg_module m + 2) in R4.
- pose proof H17 as R1'. apply max_reg_stmnt_not_modified with (r := max_reg_module m + 6) in R1'.
- pose proof H17 as R2'. eapply max_reg_stmnt_not_modified_nb with (r := max_reg_module m + 6) in R2'.
- pose proof H18 as R3'. eapply max_reg_stmnt_not_modified with (r := max_reg_module m + 6) in R3'.
- pose proof H18 as R4'. eapply max_reg_stmnt_not_modified_nb with (r := max_reg_module m + 6) in R4'.
- simplify.
- pose proof DISABLE_RAM as DISABLE_RAM1.
- eapply int_eq_not_changed with (ar' := rab') in DISABLE_RAM; try congruence.
- eapply int_eq_not_changed with (ar' := rab'1) in DISABLE_RAM; try congruence.
- rewrite AssocMap.gempty in R2. rewrite <- R2 in R4.
- rewrite AssocMap.gempty in R2'. rewrite <- R2' in R4'.
- eapply int_eq_not_changed in DISABLE_RAM; auto. repeat (rewrite merge_find_assocmap; try congruence).
- unfold empty_assocmap; apply AssocMap.gempty.
- unfold empty_assocmap; apply AssocMap.gempty.
- eapply max_reg_module_datapath_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_datapath_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_controllogic_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_controllogic_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_datapath_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_datapath_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_controllogic_gt; eauto; remember (max_reg_module m); lia.
- eapply max_reg_module_controllogic_gt; eauto; remember (max_reg_module m); lia.
- - unfold alt_store in *; simplify. inv H6. inv H19. inv H19. simplify.
- exploit match_states_same; try solve [eapply H4 | eapply max_stmnt_lt_module; eauto
- | econstructor; eauto with mgen];
- intros; repeat inv_exists; simplify; tac0.
- do 2 econstructor. apply Smallstep.plus_one. econstructor. solve [eauto with mgen]. solve [eauto with mgen].
- solve [eauto with mgen].
- rewrite H7. eassumption. eassumption. eassumption. solve [eauto with mgen].
- econstructor. econstructor. econstructor. econstructor. econstructor.
- auto. auto. auto. econstructor. econstructor. econstructor.
- econstructor. econstructor. econstructor. econstructor.
- eapply expr_runp_matches2. eassumption. 2: { cbn. eassumption. }
- pose proof H3 as X. apply max_reg_stmnt_le_stmnt_tree in X.
- apply expr_lt_max_module_datapath in X; simplify; remember (max_reg_module m); lia.
- auto.
- econstructor. econstructor. eapply expr_runp_matches2; eauto.
- pose proof H3 as X. apply max_reg_stmnt_le_stmnt_tree in X.
- apply expr_lt_max_module_datapath in X.
- remember (max_reg_module m); simplify; lia.
-
- rewrite empty_stack_transf.
- unfold transf_module; repeat destruct_match; try discriminate; simplify; [].
- eapply exec_ram_Some_write.
- 3: {
- simplify. unfold merge_regs. repeat rewrite AssocMapExt.merge_add_assoc.
- repeat rewrite find_assocmap_gso by lia.
- pose proof H12 as X.
- eapply max_reg_stmnt_not_modified_nb with (r := (max_reg_module m + 2)) in X.
- rewrite AssocMap.gempty in X.
- apply merge_find_assocmap. repeat rewrite AssocMap.gso by lia. auto.
- apply max_reg_stmnt_le_stmnt_tree in H2.
- apply expr_lt_max_module_controllogic in H2. lia.
- }
- 3: {
- simplify. unfold merge_regs. erewrite merge_get_default4. eauto.
- repeat rewrite AssocMap.gso by lia. apply AssocMap.gss.
- }
- { unfold disable_ram in *. unfold transf_module in DISABLE_RAM;
- repeat destruct_match; try discriminate.
- simplify.
- pose proof H12 as X2.
- pose proof H12 as X4.
- apply max_reg_stmnt_not_modified with (r := max_reg_module m + 2) in X2.
- apply max_reg_stmnt_not_modified with (r := max_reg_module m + 6) in X4.
- assert (forall ar ar' x, ar ! x = ar' ! x -> ar # x = ar' # x).
- { intros. unfold find_assocmap, AssocMapExt.get_default. rewrite H6. auto. }
- apply H6 in X2. apply H6 in X4. simplify. rewrite <- X2. rewrite <- X4.
- apply int_eq_not. auto.
- apply max_reg_stmnt_le_stmnt_tree in H2.
- apply expr_lt_max_module_controllogic in H2. simplify. remember (max_reg_module m). lia.
- apply max_reg_stmnt_le_stmnt_tree in H2.
- apply expr_lt_max_module_controllogic in H2. simplify. remember (max_reg_module m). lia.
- }
- 2: {
- simplify. unfold merge_regs. erewrite merge_get_default4. eauto.
- repeat rewrite AssocMap.gso by lia. apply AssocMap.gss.
- }
- solve [auto].
- simplify. unfold merge_regs. erewrite merge_get_default4. eauto.
- repeat rewrite AssocMap.gso by lia. apply AssocMap.gss.
- simplify. unfold merge_regs. erewrite merge_get_default4. eauto.
- repeat rewrite AssocMap.gso by lia. apply AssocMap.gss.
- simplify. auto.
- simplify. auto.
- unfold merge_regs. repeat rewrite ! AssocMapExt.merge_add_assoc.
- unfold empty_assocmap.
- assert (mod_st (transf_module m) < max_reg_module m + 1).
- { unfold max_reg_module, transf_module; repeat destruct_match; try discriminate; simplify; lia. }
- remember (max_reg_module m).
- repeat rewrite AssocMap.gso by lia.
- unfold_merge.
- apply merge_get_default4.
- repeat rewrite AssocMap.gso by lia.
- unfold transf_module; repeat destruct_match; try discriminate; simplify.
- eapply match_assocmaps_merge in H21.
- 2: { apply H21. }
- admit. admit.
-
- econstructor. unfold merge_regs. admit.
-
- apply merge_arr_empty. apply match_empty_size_merge.
- apply match_empty_assocmap_set.
- eapply match_arrs_size_stmnt_preserved in H4; mgen_crush_local.
- eapply match_arrs_size_stmnt_preserved in H4; mgen_crush_local.
- apply match_arrs_merge_set2; auto.
- eapply match_arrs_size_stmnt_preserved in H4; mgen_crush_local.
- eapply match_arrs_size_stmnt_preserved in H4; mgen_crush_local.
- eapply match_arrs_size_stmnt_preserved in H12; mgen_crush_local.
- rewrite empty_stack_transf. mgen_crush_local.
- eapply match_arrs_size_stmnt_preserved in H12; mgen_crush_local.
- rewrite empty_stack_transf. mgen_crush_local.
- auto.
- admit.
- admit. admit.
- - unfold alt_load in *; simplify. inv H6.
- 2: { match goal with H: context[location_is] |- _ => inv H end. }
- match goal with H: context[location_is] |- _ => inv H end.
- inv H30. simplify. inv H4.
- 2: { match goal with H: context[location_is] |- _ => inv H end. }
- inv H27. simplify.
- do 2 econstructor. eapply Smallstep.plus_two.
- econstructor. mgen_crush_local. mgen_crush_local. mgen_crush_local. eassumption.
- eassumption. econstructor. simplify. econstructor. econstructor.
- solve [eauto with mgen]. econstructor. econstructor. econstructor.
- econstructor. econstructor. auto. auto. auto.
- econstructor. econstructor. econstructor.
- econstructor. econstructor. econstructor. cbn. eapply expr_runp_matches2; auto. eassumption.
- 2: { eassumption. }
- pose proof H3 as X. apply max_reg_stmnt_le_stmnt_tree in X.
- apply expr_lt_max_module_datapath in X. simplify. remember (max_reg_module m); lia.
- auto.
-
- simplify. rewrite empty_stack_transf. unfold transf_module; repeat destruct_match; crush.
- eapply exec_ram_Some_read; simplify.
- 2: {
- unfold merge_regs. admit.
- }
- 2: {
- unfold merge_regs. admit.
- }
- { unfold disable_ram, transf_module in DISABLE_RAM;
- repeat destruct_match; try discriminate. simplify. apply int_eq_not. auto. admit. } (* } *)
-(* { unfold merge_regs; unfold_merge. repeat rewrite AssocMap.gso by lia. apply AssocMap.gss. } *)
-(* { unfold merge_regs; unfold_merge. apply AssocMap.gss. } *)
-(* { eapply match_arrs_read. eassumption. mgen_crush_local. } *)
-(* { crush. } *)
-(* { crush. } *)
-(* { unfold merge_regs. unfold_merge. *)
-(* unfold transf_module; repeat destruct_match; try discriminate; simplify. *)
-(* assert (mod_st m < max_reg_module m + 1). *)
-(* { unfold max_reg_module; lia. } *)
-(* remember (max_reg_module m). repeat rewrite AssocMap.gso by lia. *)
-(* apply AssocMap.gss. *)
-(* } *)
-(* { auto. } *)
-
-(* { econstructor. *)
-(* { unfold merge_regs. unfold_merge. *)
-(* assert (mod_reset m < max_reg_module m + 1). *)
-(* { unfold max_reg_module; lia. } *)
-(* unfold transf_module; repeat destruct_match; try discriminate; simplify. *)
-(* assert (mod_st m < mod_reset m). *)
-(* { pose proof (mod_ordering_wf m); unfold module_ordering in *. simplify. *)
-(* repeat match goal with *)
-(* | H: context[_ <? _] |- _ => apply Pos.ltb_lt in H *)
-(* end; lia. *)
-(* } *)
-(* repeat rewrite AssocMap.gso by lia. *)
-(* inv ASSOC. rewrite <- H19. auto. lia. *)
-(* } *)
-(* { unfold merge_regs. unfold_merge. *)
-(* assert (mod_finish m < max_reg_module m + 1). *)
-(* { unfold max_reg_module; lia. } *)
-(* unfold transf_module; repeat destruct_match; try discriminate; simplify. *)
-(* assert (mod_st m < mod_finish m). *)
-(* { pose proof (mod_ordering_wf m). unfold module_ordering in *. simplify. *)
-(* repeat match goal with *)
-(* | H: context[_ <? _] |- _ => apply Pos.ltb_lt in H *)
-(* end; lia. *)
-(* } *)
-(* repeat rewrite AssocMap.gso by lia. *)
-(* inv ASSOC. rewrite <- H19. auto. lia. *)
-(* } *)
-(* { unfold merge_regs. unfold_merge. *)
-(* assert (mod_st m < max_reg_module m + 1). *)
-(* { unfold max_reg_module; lia. } *)
-(* unfold transf_module; repeat destruct_match; try discriminate; simplify. *)
-(* repeat rewrite AssocMap.gso by lia. apply AssocMap.gss. *)
-(* } *)
-(* { eassumption. } *)
-(* { eassumption. } *)
-(* { econstructor. econstructor. simplify. unfold merge_regs. unfold_merge. *)
-(* eapply expr_runp_matches. eassumption. *)
-(* assert (max_reg_expr x0 + 1 <= max_reg_module m + 1). *)
-(* { pose proof H2 as X. apply max_reg_stmnt_le_stmnt_tree in X. *)
-(* apply expr_lt_max_module_controllogic in X. simplify. remember (max_reg_module m). lia. } *)
-(* assert (max_reg_expr x0 + 1 <= mod_st m). *)
-(* { unfold module_ordering in *. simplify. *)
-(* repeat match goal with *)
-(* | H: context[_ <? _] |- _ => apply Pos.ltb_lt in H *)
-(* end. *)
-(* pose proof H2 as X. apply max_reg_stmnt_le_stmnt_tree in X. *)
-(* simplify. lia. *)
-(* } *)
-(* remember (max_reg_module m). *)
-(* apply match_assocmaps_gt; [lia|]. *)
-(* apply match_assocmaps_gt; [lia|]. *)
-(* apply match_assocmaps_gt; [lia|]. *)
-(* apply match_assocmaps_gt; [lia|]. *)
-(* apply match_assocmaps_gt; [lia|]. *)
-(* apply match_assocmaps_gt; [lia|]. *)
-(* simplify. *)
-(* eapply match_assocmaps_ge. eauto. lia. *)
-(* mgen_crush_local. *)
-(* } *)
-(* { simplify. unfold merge_regs. unfold_merge. *)
-(* unfold transf_module; repeat destruct_match; try discriminate; simplify. *)
-(* assert (mod_st m < max_reg_module m + 1). *)
-(* { unfold max_reg_module; lia. } *)
-(* remember (max_reg_module m). *)
-(* repeat rewrite AssocMap.gso by lia. apply AssocMap.gss. *)
-(* } *)
-(* { *)
-(* simplify. econstructor. econstructor. econstructor. simplify. *)
-(* unfold merge_regs; unfold_merge. *)
-(* repeat rewrite find_assocmap_gso by lia. apply find_assocmap_gss. *)
-(* } *)
-(* { simplify. rewrite empty_stack_transf. *)
-(* unfold transf_module; repeat destruct_match; try discriminate; simplify. *)
-(* econstructor. simplify. *)
-(* unfold merge_regs; unfold_merge. simplify. *)
-(* assert (r < max_reg_module m + 1). *)
-(* { pose proof H3 as X. eapply max_reg_module_datapath_gt with (p := max_reg_module m + 1) in X. *)
-(* unfold max_reg_stmnt in X. simplify. *)
-(* lia. lia. } *)
-(* assert (mod_st m < max_reg_module m + 1). *)
-(* { unfold max_reg_module; lia. } *)
-(* repeat rewrite find_assocmap_gso by lia. rewrite find_assocmap_gss. *)
-(* repeat rewrite find_assocmap_gso by lia. rewrite find_assocmap_gss. *)
-(* apply Int.eq_true. *)
-(* } *)
-(* { crush. } *)
-(* { crush. } *)
-(* { unfold merge_regs. unfold_merge. simplify. *)
-(* assert (r < mod_st m). *)
-(* { unfold module_ordering in *. simplify. *)
-(* repeat match goal with *)
-(* | H: context[_ <? _] |- _ => apply Pos.ltb_lt in H *)
-(* end. *)
-(* pose proof H3 as X. apply max_reg_stmnt_le_stmnt_tree in X. *)
-(* simplify. lia. *)
-(* } *)
-(* unfold merge_regs in H8. repeat rewrite AssocMapExt.merge_add_assoc in H8. *)
-(* simplify. rewrite AssocMap.gso in H8 by lia. rewrite AssocMap.gss in H8. *)
-(* unfold transf_module; repeat destruct_match; try discriminate; simplify. *)
-(* repeat rewrite AssocMap.gso by lia. *)
-(* apply AssocMap.gss. } *)
-(* { eassumption. } *)
-(* } *)
-(* { eauto. } *)
-(* { econstructor. *)
-(* { unfold merge_regs. unfold_merge. simplify. *)
-(* apply match_assocmaps_gss. *)
-(* unfold merge_regs in H8. repeat rewrite AssocMapExt.merge_add_assoc in H8. *)
-(* rewrite AssocMap.gso in H8. rewrite AssocMap.gss in H8. inv H8. *)
-(* remember (max_reg_module m). *)
-(* assert (mod_st m < max_reg_module m + 1). *)
-(* { unfold max_reg_module; lia. } *)
-(* apply match_assocmaps_switch_neq; [|lia]. *)
-(* apply match_assocmaps_gt; [lia|]. *)
-(* apply match_assocmaps_switch_neq; [|lia]. *)
-(* apply match_assocmaps_gt; [lia|]. *)
-(* apply match_assocmaps_switch_neq; [|lia]. *)
-(* apply match_assocmaps_gt; [lia|]. *)
-(* apply match_assocmaps_switch_neq; [|lia]. *)
-(* apply match_assocmaps_gt; [lia|]. *)
-(* apply match_assocmaps_switch_neq; [|lia]. *)
-(* apply match_assocmaps_gt; [lia|]. *)
-(* apply match_assocmaps_duplicate. *)
-(* apply match_assocmaps_gss. auto. *)
-(* assert (r < mod_st m). *)
-(* { unfold module_ordering in *. simplify. *)
-(* repeat match goal with *)
-(* | H: context[_ <? _] |- _ => apply Pos.ltb_lt in H *)
-(* end. *)
-(* pose proof H3 as X. apply max_reg_stmnt_le_stmnt_tree in X. *)
-(* simplify. lia. *)
-(* } lia. *)
-(* } *)
-(* { *)
-(* apply merge_arr_empty. mgen_crush_local. *)
-(* apply merge_arr_empty2. mgen_crush_local. *)
-(* apply merge_arr_empty2. mgen_crush_local. *)
-(* apply merge_arr_empty2. mgen_crush_local. *)
-(* mgen_crush_local. *)
-(* } *)
-(* { auto. } *)
-(* { mgen_crush_local. } *)
-(* { mgen_crush_local. } *)
-(* { unfold disable_ram. *)
-(* unfold transf_module; repeat destruct_match; try discriminate; simplify. *)
-(* unfold merge_regs. unfold_merge. simplify. *)
-(* assert (mod_st m < max_reg_module m + 1). *)
-(* { unfold max_reg_module; lia. } *)
-(* assert (r < max_reg_module m + 1). *)
-(* { pose proof H3 as X. eapply max_reg_module_datapath_gt with (p := max_reg_module m + 1) in X. *)
-(* unfold max_reg_stmnt in X. simplify. *)
-(* lia. lia. } *)
-(* repeat rewrite find_assocmap_gso by lia. *)
-(* rewrite find_assocmap_gss. *)
-(* repeat rewrite find_assocmap_gso by lia. *)
-(* rewrite find_assocmap_gss. apply Int.eq_true. *)
-(* } *)
-(* } *)
-(* Qed. *) Admitted.
-
-Lemma exec_ram_resets_en :
- forall rs ar rs' ar' r,
- exec_ram rs ar (Some r) rs' ar' ->
- assoc_nonblocking rs = empty_assocmap ->
- Int.eq ((assoc_blocking (merge_reg_assocs rs')) # (ram_en r, 32))
- ((assoc_blocking (merge_reg_assocs rs')) # (ram_u_en r, 32)) = true.
-Proof.
- inversion 1; intros; subst; unfold merge_reg_assocs; simplify.
- - rewrite H6. mgen_crush_local.
- (* - unfold merge_regs. rewrite H12. unfold_merge. *)
-(* unfold find_assocmap, AssocMapExt.get_default in *. *)
-(* rewrite AssocMap.gss; auto. rewrite AssocMap.gso; auto. setoid_rewrite H4. apply Int.eq_true. *)
-(* pose proof (ram_ordering r); lia. *)
-(* - unfold merge_regs. rewrite H11. unfold_merge. *)
-(* unfold find_assocmap, AssocMapExt.get_default in *. *)
-(* rewrite AssocMap.gss; auto. *)
-(* repeat rewrite AssocMap.gso by (pose proof (ram_ordering r); lia). *)
-(* setoid_rewrite H3. apply Int.eq_true. *)
-(* Qed. *) Admitted.
-
-Lemma disable_ram_set_gso :
- forall rs r i v,
- disable_ram (Some r) rs ->
- i <> (ram_en r) -> i <> (ram_u_en r) ->
- disable_ram (Some r) (rs # i <- v).
-Proof.
- unfold disable_ram, find_assocmap, AssocMapExt.get_default; intros;
- repeat rewrite AssocMap.gso by lia; auto.
-Qed.
-#[local] Hint Resolve disable_ram_set_gso : mgen.
-
-Lemma disable_ram_None rs : disable_ram None rs.
-Proof. unfold disable_ram; auto. Qed.
-#[local] Hint Resolve disable_ram_None : mgen.
-
-Lemma init_regs_equal_empty l st :
- Forall (Pos.gt st) l -> (init_regs nil l) ! st = None.
-Proof. induction l; simplify; apply AssocMap.gempty. Qed.
-
-Lemma forall_lt_num :
- forall l p p', Forall (Pos.gt p) l -> p < p' -> Forall (Pos.gt p') l.
-Proof. induction l; crush; inv H; constructor; [lia | eauto]. Qed.
-
-Section CORRECTNESS.
-
- Context (prog tprog: program).
- Context (TRANSL: match_prog prog tprog).
-
- Let ge : genv := Genv.globalenv prog.
- Let tge : genv := Genv.globalenv tprog.
-
- Lemma symbols_preserved:
- forall (s: AST.ident), Genv.find_symbol tge s = Genv.find_symbol ge s.
- Proof using TRANSL. intros. eapply (Genv.find_symbol_match TRANSL). Qed.
- #[local] Hint Resolve symbols_preserved : mgen.
-
- Lemma function_ptr_translated:
- forall (b: Values.block) (f: fundef),
- Genv.find_funct_ptr ge b = Some f ->
- exists tf,
- Genv.find_funct_ptr tge b = Some tf /\ transf_fundef f = tf.
- Proof using TRANSL.
- intros. exploit (Genv.find_funct_ptr_match TRANSL); eauto.
- intros (cu & tf & P & Q & R); exists tf; auto.
- Qed.
- #[local] Hint Resolve function_ptr_translated : mgen.
-
- Lemma functions_translated:
- forall (v: Values.val) (f: fundef),
- Genv.find_funct ge v = Some f ->
- exists tf,
- Genv.find_funct tge v = Some tf /\ transf_fundef f = tf.
- Proof using TRANSL.
- intros. exploit (Genv.find_funct_match TRANSL); eauto.
- intros (cu & tf & P & Q & R); exists tf; auto.
- Qed.
- #[local] Hint Resolve functions_translated : mgen.
-
- Lemma senv_preserved:
- Senv.equiv (Genv.to_senv ge) (Genv.to_senv tge).
- Proof (Genv.senv_transf TRANSL).
- #[local] Hint Resolve senv_preserved : mgen.
-
- Theorem transf_step_correct:
- forall (S1 : state) t S2,
- step ge S1 t S2 ->
- forall R1,
- match_states S1 R1 ->
- exists R2, Smallstep.plus step tge R1 t R2 /\ match_states S2 R2.
- Proof.
- Ltac transf_step_correct_assum :=
- match goal with
- | H: match_states _ _ |- _ => let H2 := fresh "MATCH" in learn H as H2; inv H2
- | H: mod_ram ?m = Some ?r |- _ =>
- let H2 := fresh "RAM" in learn H;
- pose proof (transf_module_code_ram m r H) as H2
- | H: mod_ram ?m = None |- _ =>
- let H2 := fresh "RAM" in learn H;
- pose proof (transf_module_code m H) as H2
- end.
- Ltac transf_step_correct_tac :=
- match goal with
- | |- Smallstep.plus _ _ _ _ _ => apply Smallstep.plus_one
- end.
- induction 1; destruct (mod_ram m) eqn:RAM; simplify; repeat transf_step_correct_assum;
- repeat transf_step_correct_tac.
- - assert (MATCH_SIZE1: match_empty_size m nasa1 /\ match_empty_size m basa1).
- { eapply match_arrs_size_stmnt_preserved2; eauto. unfold match_empty_size; mgen_crush_local. }
- simplify.
- assert (MATCH_SIZE2: match_empty_size m nasa2 /\ match_empty_size m basa2).
- { eapply match_arrs_size_stmnt_preserved2; mgen_crush_local. } simplify.
- assert (MATCH_SIZE2: match_empty_size m nasa3 /\ match_empty_size m basa3).
- { eapply match_arrs_size_ram_preserved2; mgen_crush_local. } simplify.
- assert (MATCH_ARR3: match_arrs_size nasa3 basa3) by mgen_crush_local.
- exploit match_states_same. apply H4. eauto with mgen.
- econstructor; eauto. econstructor; eauto. econstructor; eauto. econstructor; eauto.
- intros. repeat inv_exists. simplify. inv H18. inv H21.
- exploit match_states_same. apply H6. eauto with mgen.
- econstructor; eauto. econstructor; eauto. intros. repeat inv_exists. simplify. inv H18. inv H23.
- exploit exec_ram_same; eauto. eauto with mgen.
- econstructor. eapply match_assocmaps_merge; eauto. eauto with mgen.
- econstructor.
- apply match_arrs_merge; eauto with mgen. eauto with mgen.
- intros. repeat inv_exists. simplify. inv H18. inv H28.
- econstructor; simplify. apply Smallstep.plus_one. econstructor.
- mgen_crush_local. mgen_crush_local. mgen_crush_local. rewrite RAM0; eassumption. rewrite RAM0; eassumption.
- rewrite RAM0. eassumption. mgen_crush_local. eassumption. rewrite RAM0 in H21. rewrite RAM0.
- rewrite RAM. eassumption. eauto. eauto. eauto with mgen. eauto.
- econstructor. mgen_crush_local. apply match_arrs_merge; mgen_crush_local. eauto.
- apply match_empty_size_merge; mgen_crush_local; mgen_crush_local.
- assert (MATCH_SIZE1': match_empty_size m ran'0 /\ match_empty_size m rab'0).
- { eapply match_arrs_size_stmnt_preserved2; eauto. unfold match_empty_size; mgen_crush_local. }
- simplify.
- assert (MATCH_SIZE2': match_empty_size m ran'2 /\ match_empty_size m rab'2).
- { eapply match_arrs_size_stmnt_preserved2; mgen_crush_local. } simplify.
- assert (MATCH_SIZE2': match_empty_size m ran'4 /\ match_empty_size m rab'4).
- { eapply match_arrs_size_ram_preserved2; mgen_crush_local.
- unfold match_empty_size, transf_module, empty_stack.
- repeat destruct_match; crush. mgen_crush_local. }
- apply match_empty_size_merge; mgen_crush_local; mgen_crush_local.
- unfold disable_ram.
- unfold transf_module; repeat destruct_match; crush.
- apply exec_ram_resets_en in H21. unfold merge_reg_assocs in H21.
- simplify. auto. auto.
- - eapply translation_correct; eauto.
- - do 2 econstructor. apply Smallstep.plus_one.
- apply step_finish; mgen_crush_local. constructor; eauto.
- - do 2 econstructor. apply Smallstep.plus_one.
- apply step_finish; mgen_crush_local. econstructor; eauto.
- - econstructor. econstructor. apply Smallstep.plus_one. econstructor.
- replace (mod_entrypoint (transf_module m)) with (mod_entrypoint m) by (rewrite RAM0; auto).
- replace (mod_reset (transf_module m)) with (mod_reset m) by (rewrite RAM0; auto).
- replace (mod_finish (transf_module m)) with (mod_finish m) by (rewrite RAM0; auto).
- replace (empty_stack (transf_module m)) with (empty_stack m) by (rewrite RAM0; auto).
- replace (mod_params (transf_module m)) with (mod_params m) by (rewrite RAM0; auto).
- replace (mod_st (transf_module m)) with (mod_st m) by (rewrite RAM0; auto).
- repeat econstructor; mgen_crush_local.
- unfold disable_ram. unfold transf_module; repeat destruct_match; crush.
- pose proof (mod_ordering_wf m); unfold module_ordering in *.
- pose proof (mod_params_wf m).
- pose proof (mod_ram_wf m r Heqo0).
- pose proof (ram_ordering r).
- simplify.
- repeat rewrite find_assocmap_gso by lia.
- assert ((init_regs nil (mod_params m)) ! (ram_en r) = None).
- { apply init_regs_equal_empty. eapply forall_lt_num. eassumption. lia. }
- assert ((init_regs nil (mod_params m)) ! (ram_u_en r) = None).
- { apply init_regs_equal_empty. eapply forall_lt_num. eassumption. lia. }
- unfold find_assocmap, AssocMapExt.get_default. rewrite H7. rewrite H14. auto.
- - econstructor. econstructor. apply Smallstep.plus_one. econstructor.
- replace (mod_entrypoint (transf_module m)) with (mod_entrypoint m).
- replace (mod_reset (transf_module m)) with (mod_reset m).
- replace (mod_finish (transf_module m)) with (mod_finish m).
- replace (empty_stack (transf_module m)) with (empty_stack m).
- replace (mod_params (transf_module m)) with (mod_params m).
- replace (mod_st (transf_module m)) with (mod_st m).
- all: try solve [unfold transf_module; repeat destruct_match; mgen_crush_local].
- repeat econstructor; mgen_crush_local.
- unfold disable_ram. unfold transf_module; repeat destruct_match; crush.
- unfold max_reg_module.
- repeat rewrite find_assocmap_gso by lia.
- assert (max_reg_module m + 1 > max_list (mod_params m)).
- { unfold max_reg_module. lia. }
- apply max_list_correct in H0.
- unfold find_assocmap, AssocMapExt.get_default.
- rewrite init_regs_equal_empty. rewrite init_regs_equal_empty. auto.
- eapply forall_lt_num. eassumption. unfold max_reg_module. lia.
- eapply forall_lt_num. eassumption. unfold max_reg_module. lia.
- - inv STACKS. destruct b1; subst.
- econstructor. econstructor. apply Smallstep.plus_one.
- econstructor. eauto.
- clear Learn. inv H0. inv H3. inv STACKS. inv H3. constructor.
- constructor. intros.
- rewrite RAM0.
- destruct (Pos.eq_dec r res); subst.
- rewrite AssocMap.gss.
- rewrite AssocMap.gss. auto.
- rewrite AssocMap.gso; auto.
- symmetry. rewrite AssocMap.gso; auto.
- destruct (Pos.eq_dec (mod_st m) r); subst.
- rewrite AssocMap.gss.
- rewrite AssocMap.gss. auto.
- rewrite AssocMap.gso; auto.
- symmetry. rewrite AssocMap.gso; auto. inv MATCH_ASSOC0. apply H1. auto.
- auto. auto. auto. auto.
- rewrite RAM0. rewrite RAM. rewrite RAM0 in DISABLE_RAM. rewrite RAM in DISABLE_RAM.
- apply disable_ram_set_gso.
- apply disable_ram_set_gso. auto.
- pose proof (mod_ordering_wf m); unfold module_ordering in *.
- pose proof (ram_ordering r0). simplify.
- pose proof (mod_ram_wf m r0 H). lia.
- pose proof (mod_ordering_wf m); unfold module_ordering in *.
- pose proof (ram_ordering r0). simplify.
- pose proof (mod_ram_wf m r0 H). lia.
- pose proof (mod_ordering_wf m); unfold module_ordering in *.
- pose proof (ram_ordering r0). simplify.
- pose proof (mod_ram_wf m r0 H). lia.
- pose proof (mod_ordering_wf m); unfold module_ordering in *.
- pose proof (ram_ordering r0). simplify.
- pose proof (mod_ram_wf m r0 H). lia.
- - inv STACKS. destruct b1; subst.
- econstructor. econstructor. apply Smallstep.plus_one.
- econstructor. eauto.
- clear Learn. inv H0. inv H3. inv STACKS. constructor.
- constructor. intros.
- unfold transf_module. repeat destruct_match; crush.
- destruct (Pos.eq_dec r res); subst.
- rewrite AssocMap.gss.
- rewrite AssocMap.gss. auto.
- rewrite AssocMap.gso; auto.
- symmetry. rewrite AssocMap.gso; auto.
- destruct (Pos.eq_dec (mod_st m) r); subst.
- rewrite AssocMap.gss.
- rewrite AssocMap.gss. auto.
- rewrite AssocMap.gso; auto.
- symmetry. rewrite AssocMap.gso; auto. inv MATCH_ASSOC. apply H. auto.
- auto. auto. auto. auto.
- Opaque disable_ram.
- unfold transf_module in *; repeat destruct_match; crush.
- apply disable_ram_set_gso.
- apply disable_ram_set_gso.
- auto.
- simplify. unfold max_reg_module. lia.
- simplify. unfold max_reg_module. lia.
- simplify. unfold max_reg_module. lia.
- simplify. unfold max_reg_module. lia.
- Qed.
- #[local] Hint Resolve transf_step_correct : mgen.
-
- Lemma transf_initial_states :
- forall s1 : state,
- initial_state prog s1 ->
- exists s2 : state,
- initial_state tprog s2 /\ match_states s1 s2.
- Proof using TRANSL.
- simplify. inv H.
- exploit function_ptr_translated. eauto. intros.
- inv H. inv H3.
- econstructor. econstructor. econstructor.
- eapply (Genv.init_mem_match TRANSL); eauto.
- setoid_rewrite (Linking.match_program_main TRANSL).
- rewrite symbols_preserved. eauto.
- eauto.
- econstructor.
- Qed.
- #[local] Hint Resolve transf_initial_states : mgen.
-
- Lemma transf_final_states :
- forall (s1 : state)
- (s2 : state)
- (r : Int.int),
- match_states s1 s2 ->
- final_state s1 r ->
- final_state s2 r.
- Proof using TRANSL.
- intros. inv H0. inv H. inv STACKS. unfold valueToInt. constructor. auto.
- Qed.
- #[local] Hint Resolve transf_final_states : mgen.
-
- Theorem transf_program_correct:
- Smallstep.forward_simulation (semantics prog) (semantics tprog).
- Proof using TRANSL.
- eapply Smallstep.forward_simulation_plus; mgen_crush_local.
- apply senv_preserved.
- Qed.
-
-End CORRECTNESS.