diff --git a/.vscode/settings.json b/.vscode/settings.json index f06b84c4..ab3b3b4f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,16 +1,16 @@ { "files.exclude": { + "**/*.vo": true, + "**/*.vok": true, + "**/*.vos": true, + "**/*.aux": true, + "**/*.glob": true, "**/.git": true, "**/.svn": true, "**/.hg": true, "**/CVS": true, "**/.DS_Store": true, "**/Thumbs.db": true, - "**/*.vo": true, - "**/*.vok": true, - "**/*.vos": true, - "**/*.aux": true, - "**/*.glob": true, "**/*_cp_aux.v": true }, "nixEnvSelector.suggestion": false, diff --git a/Makefile b/Makefile index 8a4f6771..c9a388ce 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ COQMODULE := xmm -COQTHEORIES := src/reordering/*.v src/xmm/*.v src/lib/*.v src/traces/*.v src/xmm_cons/*.v +COQTHEORIES := src/reordering/*.v src/xmm/*.v src/lib/*.v src/traces/*.v src/xmm_cons/*.v src/sequentialization/*.v .PHONY: all theories clean tounicode diff --git a/src/reordering/ReorderingExecA.v b/src/reordering/ReorderingExecA.v index b089fdce..6d0593ca 100644 --- a/src/reordering/ReorderingExecA.v +++ b/src/reordering/ReorderingExecA.v @@ -679,7 +679,6 @@ Proof using ADD SIMREL INV INV'. all: unfold f. all: rewrite ?collect_rel_id, ?set_collect_id. { basic_solver. } - { basic_solver. } { intros e EIN. unfold id. now apply rsr_a_labeq. } { apply rsr_rpo_emb. } diff --git a/src/sequentialization/Programs.v b/src/sequentialization/Programs.v new file mode 100644 index 00000000..10922ca1 --- /dev/null +++ b/src/sequentialization/Programs.v @@ -0,0 +1,44 @@ +From hahn Require Import Hahn. +From hahnExt Require Import HahnExt. +From imm Require Import Events Execution. +From xmm Require Import Instructions. +From xmm Require Import Core. +Require Import Lia Setoid Program.Basics. +Require Import Coq.Sorting.Mergesort. +Require Import Coq.Structures.OrderedType. + +Open Scope nat_scope. +Open Scope program_scope. + +Section Program. + +Definition program_trace := thread_id -> list label. +Definition program := program_trace -> Prop. + +Record program_trace_sequented (p_tr1 p_tr2 : program_trace) (t1 t2 : thread_id) : Prop := + { p_tr_eq : forall t, t <> t1 /\ t <> t2 -> p_tr1 t = p_tr2 t; + p_tr_empty : p_tr2 t2 = []; + p_tr_concat : p_tr2 t1 = p_tr1 t1 ++ p_tr1 t2; + }. + +Definition corresp_px (exec : WCore.t) (p_tr : program_trace) : Prop := + forall t i, (acts_set (WCore.G exec)) (ThreadEvent t i) -> + Some (lab (WCore.G exec) (ThreadEvent t i)) = nth_error (p_tr t) i. + +Definition program_sequented (p1 p2 : program) (t1 t2 : thread_id) : Prop := + forall p_tr : program_trace, + p2 p_tr -> exists p_tr', p1 p_tr' /\ + program_trace_sequented p_tr' p_tr t1 t2. + +Record exec_sequent (ex1 ex2 : WCore.t) (p1 p2 : program) + (t1 t2 : thread_id) : Prop := { + exec_sequented : program_sequented p1 p2 t1 t2; + traces_cond : forall p_tr1 p_tr2 : program_trace, + p1 p_tr1 -> p2 p_tr2 -> + corresp_px ex1 p_tr1 -> + corresp_px ex2 p_tr2 -> + program_trace_sequented p_tr1 p_tr2 t1 t2; + }. + + +End Program. diff --git a/src/sequentialization/SequentBase.v b/src/sequentialization/SequentBase.v new file mode 100644 index 00000000..455e900a --- /dev/null +++ b/src/sequentialization/SequentBase.v @@ -0,0 +1,179 @@ +Require Import AuxDef. +Require Import Core. +Require Import AuxRel AuxRel2. +Require Import Srf Rhb. +Require Import SimrelCommon. +Require Import StepOps. +Require Import AuxInj. +Require Import xmm_s_hb. +Require Import Lia. +From xmm Require Import Reordering. +From xmm Require Import ThreadTrace. +From xmm Require Import Programs. + +From hahn Require Import Hahn. +From hahnExt Require Import HahnExt. +From imm Require Import Events Execution Execution_eco. +Require Import Setoid Morphisms Program.Basics. + +Open Scope program_scope. + +Set Implicit Arguments. + +Section SimRelSeq. + +Variable X_s X_t : WCore.t. +Variable t_1 t_2 : thread_id. +Variable mapper : actid -> actid. +Variable mappre_rev : actid -> actid. + +Notation "'G_t'" := (WCore.G X_t). +Notation "'lab_t'" := (lab G_t). +Notation "'loc_t'" := (loc lab_t). +Notation "'val_t'" := (val lab_t). +Notation "'E_t'" := (acts_set G_t). +Notation "'sb_t'" := (sb G_t). +Notation "'rf_t'" := (rf G_t). +Notation "'co_t'" := (co G_t). +Notation "'rhb_t'" := (rhb G_t). +Notation "'rmw_t'" := (rmw G_t). +Notation "'rpo_t'" := (rpo G_t). +Notation "'rpo_imm_t'" := (rpo_imm G_t). +Notation "'rmw_dep_t'" := (rmw_dep G_t). +Notation "'data_t'" := (data G_t). +Notation "'ctrl_t'" := (ctrl G_t). +Notation "'addr_t'" := (addr G_t). + +Notation "'G_s'" := (WCore.G X_s). +Notation "'lab_s'" := (lab G_s). +Notation "'val_s'" := (val lab_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'E_s'" := (acts_set G_s). +Notation "'sb_s'" := (sb G_s). +Notation "'rf_s'" := (rf G_s). +Notation "'co_s'" := (co G_s). +Notation "'rhb_s'" := (rhb G_s). +Notation "'rmw_s'" := (rmw G_s). +Notation "'rpo_s'" := (rpo G_s). +Notation "'rpo_imm_s'" := (rpo_imm G_s). +Notation "'vf_s'" := (vf G_s). +Notation "'rmw_dep_s'" := (rmw_dep G_s). +Notation "'data_s'" := (data G_s). +Notation "'ctrl_s'" := (ctrl G_s). +Notation "'addr_s'" := (addr G_s). + +Notation "'Tid_' t" := (fun e => tid e = t) (at level 1). + +Definition po_seq := (Tid_ t_1 ∩₁ E_s) × (Tid_ t_2 ∩₁ E_s). + +Variable ptc_1 ptc_2 : program_trace. + +Definition t_12_len := length (ptc_2 t_1). +Definition t_1_len := length (ptc_1 t_1). +Definition t_2_len := length (ptc_1 t_2). + +Record seq_simrel : Prop := { + seq_inj : inj_dom E_t mapper; + + seq_tid_1 : forall e : actid, E_t e -> tid (mapper e) <> t_2 -> tid e = tid (mapper e); + seq_tid_2 : forall e : actid, E_t e -> tid (mapper e) = t_2 -> tid e = t_1; + + seq_lab : eq_dom E_t lab_t (lab_s ∘ mapper); + seq_lab_rev : eq_dom E_s lab_s (lab_t ∘ mappre_rev); + seq_acts : E_s ≡₁ mapper ↑₁ E_t; + seq_acts_rev : E_t ≡₁ mappre_rev ↑₁ E_s; + seq_sb : sb_s ∪ po_seq ≡ mapper ↑ sb_t; + seq_rf : rf_s ≡ mapper ↑ rf_t; + seq_co : co_s ≡ mapper ↑ co_t; + seq_rmw : rmw_s ≡ mapper ↑ rmw_t; + seq_threads : threads_set G_s ≡₁ threads_set G_t ∪₁ eq t_2; + + seq_ctrl : ctrl_s ≡ ∅₂; + seq_data : data_s ≡ ∅₂; + seq_addr : addr_s ≡ ∅₂; + seq_rmw_dep : rmw_dep_s ≡ ∅₂; + + seq_init : fixset is_init mapper; + seq_init_rev : fixset is_init mappre_rev; + seq_codom : mapper ↑₁ E_t ⊆₁ E_s; + + seq_mapeq : forall e : actid, E_t e -> tid (mapper e) <> t_2 -> mapper e = e; + seq_mapeq_rev : forall e : actid, E_s e -> tid e <> t_2 -> mappre_rev e = e; + seq_mapto : forall e : actid, E_t e -> tid (mapper e) = t_2 -> mapper e = ThreadEvent t_2 (index e - t_1_len); + seq_index : forall e : actid, E_t e -> tid (mapper e) = t_2 -> index e = t_1_len + index (mapper e); + seq_thrd : forall e : actid, E_t e -> tid (mapper e) = t_2 -> tid e = t_1; + seq_maprev : forall e : actid, E_s e -> tid e = t_2 -> mappre_rev e = ThreadEvent t_1 (index e + t_1_len); + + seq_out : forall e : actid, E_t e -> tid e <> t_1 -> mapper e = e; + seq_out_snd : forall e : actid, E_t e -> tid e = t_1 -> index e < t_1_len -> mapper e = e; + seq_out_move : forall e : actid, E_t e -> tid e = t_1 -> index e >= t_1_len -> mapper e = ThreadEvent t_2 (index e - t_1_len); + + seq_rest : forall e : actid, ~ E_t e -> mapper e = e; + seq_rest_rev : forall e : actid, ~ E_s e -> mappre_rev e = e; + seq_rlab : forall e : actid, ~ E_s e -> lab_s e = lab_t (mappre_rev e); +}. + +Record seq_simrel_inv : Prop := { + rsr_Gt_wf : Wf G_t; + rsr_nctrl : ctrl_t ≡ ∅₂; + rsr_ndata : data_t ≡ ∅₂; + rsr_naddr : addr_t ≡ ∅₂; + rsr_nrmw_dep : rmw_dep_t ≡ ∅₂; + rsr_init_acts : is_init ⊆₁ E_t; +}. + +End SimRelSeq. + +Section SeqSimrelInit. + +Variable X_t X_s : WCore.t. +Variable t_1 t_2 : thread_id. +Variable mapper : actid -> actid. +Variable mappre_rev : actid -> actid. + +Variable ptc_1 ptc_2 : program_trace. + +Notation "'G_t'" := (WCore.G X_t). +Notation "'G_s'" := (WCore.G X_s). + +Hypothesis INV : seq_simrel_inv X_t. + +Lemma seq_simrel_init threads + (NINIT1 : t_1 <> tid_init) + (NINIT2 : t_2 <> tid_init) + (THRD1 : threads t_1) + (THRDNEQ : t_1 <> t_2) + (INIT : threads tid_init) : + << SIMREL : seq_simrel + (WCore.Build_t (WCore.init_exec (threads ∪₁ eq t_2)) ∅₂) + (WCore.Build_t (WCore.init_exec threads) ∅₂) + t_1 t_2 + id id ptc_1 >>. +Proof using. + assert (IWF : Wf (WCore.init_exec threads)). + { now apply WCore.wf_init_exec. } + split; vauto; ins. + { assert (FALSE : t_2 = tid_init). + { rewrite <- H0. unfold tid. desf. + unfold is_init in H. desf. } + desf. } + { clear; basic_solver. } + { clear; basic_solver. } + { rewrite collect_rel_id; split; vauto. + unfold po_seq; ins. + assert (EMP1 : (fun e : actid => tid e = t_1) + ∩₁ (fun a : actid => is_init a) ≡₁ ∅). + { split; [|basic_solver]. + intros x COND. destruct COND as [TID ISINIT]. + unfold is_init in ISINIT. desf. } + assert (EMP2 : (fun e : actid => tid e = t_2) + ∩₁ (fun a : actid => is_init a) ≡₁ ∅). + { split; [|basic_solver]. + intros x COND. destruct COND as [TID ISINIT]. + unfold is_init in ISINIT. desf. } + rewrite EMP1, EMP2. clear; basic_solver 8. } + all : try basic_solver. + all : unfold is_init in H; desf. +Qed. + +End SeqSimrelInit. diff --git a/src/sequentialization/SequentExec.v b/src/sequentialization/SequentExec.v new file mode 100644 index 00000000..f3fc2f77 --- /dev/null +++ b/src/sequentialization/SequentExec.v @@ -0,0 +1,1507 @@ +Require Import AuxDef. +Require Import Core. +Require Import AuxRel AuxRel2. +Require Import Srf Rhb. +Require Import SimrelCommon. +Require Import StepOps. +Require Import AuxInj. +Require Import xmm_s_hb. +Require Import Lia. +From xmm Require Import Reordering. +From xmm Require Import ThreadTrace. +From xmm Require Import Programs. +From xmm Require Import SequentBase. +From xmm Require Import SequentWf. +From xmm Require Import ConsistencyMonotonicity. + +From hahn Require Import Hahn. +From hahnExt Require Import HahnExt. +From imm Require Import Events Execution Execution_eco. +Require Import Setoid Morphisms Program.Basics. + +Open Scope program_scope. + +Set Implicit Arguments. + +Section SimrelStep. + +Variable X_t X_t' X_s : WCore.t. +Variable t_1 t_2 : thread_id. +Variable mapper : actid -> actid. +Variable mapper_rev : actid -> actid. + +Variable e : actid. +Variable l : label. + +Variable thrdle : relation thread_id. + +Variable ptc_1 ptc_2 : program_trace. + +Notation "'G_t'" := (WCore.G X_t). +Notation "'G_t''" := (WCore.G X_t'). +Notation "'G_s'" := (WCore.G X_s). + +Notation "'R' G" := (fun e => is_true (is_r (lab G) e)) (at level 1). +Notation "'F' G" := (fun e => is_true (is_f (lab G) e)) (at level 1). +Notation "'W' G" := (fun e => is_true (is_w (lab G) e)) (at level 1). +Notation "'Acq' G" := (fun e => is_true (is_acq (lab G) e)) (at level 1). +Notation "'Rlx' G" := (fun e => is_true (is_rlx (lab G) e)) (at level 1). +Notation "'Rel' G" := (fun e => is_true (is_rel (lab G) e)) (at level 1). + +Notation "'lab_t'" := (lab G_t). +Notation "'val_t'" := (val lab_t). +Notation "'loc_t'" := (loc lab_t). +Notation "'same_loc_t'" := (same_loc lab_t). +Notation "'E_t'" := (acts_set G_t). +Notation "'sb_t'" := (sb G_t). +Notation "'rf_t'" := (rf G_t). +Notation "'co_t'" := (co G_t). +Notation "'rmw_t'" := (rmw G_t). +Notation "'rpo_t'" := (rpo G_t). +Notation "'rmw_dep_t'" := (rmw_dep G_t). +Notation "'data_t'" := (data G_t). +Notation "'ctrl_t'" := (ctrl G_t). +Notation "'addr_t'" := (addr G_t). +Notation "'W_t'" := (fun x => is_true (is_w lab_t x)). +Notation "'R_t'" := (fun x => is_true (is_r lab_t x)). +Notation "'Loc_t_' l" := (fun e => loc_t e = l) (at level 1). + +Notation "'lab_t''" := (lab G_t'). +Notation "'val_t''" := (val lab_t'). +Notation "'loc_t''" := (loc lab_t'). +Notation "'same_loc_t''" := (same_loc lab_t'). +Notation "'E_t''" := (acts_set G_t'). +Notation "'sb_t''" := (sb G_t'). +Notation "'rf_t''" := (rf G_t'). +Notation "'co_t''" := (co G_t'). +Notation "'rmw_t''" := (rmw G_t'). +Notation "'rpo_t''" := (rpo G_t'). +Notation "'rmw_dep_t''" := (rmw_dep G_t'). +Notation "'data_t''" := (data G_t'). +Notation "'ctrl_t''" := (ctrl G_t'). +Notation "'addr_t''" := (addr G_t'). +Notation "'W_t''" := (fun x => is_true (is_w lab_t' x)). +Notation "'R_t''" := (fun x => is_true (is_r lab_t' x)). +Notation "'Loc_t_'' l" := (fun e => loc_t' e = l) (at level 1). + +Notation "'lab_s'" := (lab G_s). +Notation "'val_s'" := (val lab_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'same_loc_s'" := (same_loc lab_s). +Notation "'E_s'" := (acts_set G_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'sb_s'" := (sb G_s). +Notation "'rf_s'" := (rf G_s). +Notation "'co_s'" := (co G_s). +Notation "'rmw_s'" := (rmw G_s). +Notation "'rpo_s'" := (rpo G_s). +Notation "'rmw_dep_s'" := (rmw_dep G_s). +Notation "'data_s'" := (data G_s). +Notation "'ctrl_s'" := (ctrl G_s). +Notation "'addr_s'" := (addr G_s). +Notation "'W_s'" := (fun x => is_true (is_w lab_s x)). +Notation "'R_s'" := (fun x => is_true (is_r lab_s x)). +Notation "'F_s'" := (F G_s). + +Notation "'Tid_' t" := (fun e => tid e = t) (at level 1). + +Hypothesis MAPREV : eq_dom E_t (mapper_rev ∘ mapper) id. +Hypothesis MAPREVR : eq_dom E_s (mapper ∘ mapper_rev) id. +Hypothesis PROGSEQ : program_trace_sequented ptc_1 ptc_2 t_1 t_2. +Hypothesis WFT : Wf G_t. + +Definition t_12_len := length (ptc_2 t_1). +Definition t_1_len := length (ptc_1 t_1). +Definition t_2_len := length (ptc_1 t_2). + +Hypothesis INV : seq_simrel_inv X_t. +Hypothesis INV' : seq_simrel_inv X_t'. + +Lemma simrel_step_e_t1 + (T1 : tid e = t_1) + (IND: index e < t_1_len) + (NINIT1 : t_1 <> tid_init) + (NINIT2 : t_2 <> tid_init) + (T2NOTIN : ~ threads_set G_t t_2) + (THRDNEQ : t_1 <> t_2) + (SIMREL : seq_simrel X_s X_t t_1 t_2 mapper mapper_rev ptc_1) + (STEP : WCore.exec_inst X_t X_t' e l) : + exists mapper' mapper_rev' X_s', + << SIMREL : seq_simrel X_s' X_t' t_1 t_2 mapper' mapper_rev' ptc_1 >> /\ + << STEP : WCore.exec_inst X_s X_s' (mapper' e) l >>. +Proof using. + destruct STEP as [ADD RFC CONS]. + destruct ADD as (r & R1 & w & W1 & W2 & ADD). + set (mapper' := upd mapper e e). + set (mapper_rev' := upd mapper_rev e e). + assert (ENOTIN : ~E_t e) by apply ADD. + assert (MAPEQ : eq_dom E_t mapper' mapper). + { subst mapper'. unfolder. intros x XINE. + clear - ENOTIN XINE. rewrite updo. + all: congruence. } + assert (MAPER_E : mapper' ↑₁ eq e ≡₁ eq e). + { subst mapper'. rewrite set_collect_eq. now rupd. } + assert (MAPSUB : mapper' ↑₁ E_t ≡₁ mapper ↑₁ E_t). + { clear - MAPEQ. now apply set_collect_eq_dom. } + assert (EQACTS : E_t' ≡₁ E_t ∪₁ eq e) by apply ADD. + assert (MAPREVDOM : E_t ≡₁ mapper_rev ↑₁ E_s). + { rewrite (seq_acts SIMREL). split. + { unfolder. intros x XINE. + exists (mapper x). splits; vauto. + apply MAPREV; vauto. } + unfolder. intros x (y & XINE & YEQ). + destruct XINE as (x0 & (INE & MAPPED)). + rewrite <- MAPPED in YEQ. rewrite <- YEQ. + assert (INE' : E_t x0) by vauto. + apply MAPREV in INE. clear - INE INE'. + unfold compose in INE. rewrite INE. + basic_solver. } + assert (MEPERREV_E : mapper_rev' ↑₁ eq e ≡₁ eq e). + { subst mapper_rev'. rewrite set_collect_eq. now rupd. } + assert (NEWE : + << NINIT : ~is_init e >> /\ + << NOTIN : ~E_s e >> /\ + << TID : tid e = t_1 >>). + { unfold NW; splits; vauto. + { intro FALSO. unfold is_init in FALSO. + unfold tid in T1. clear - T1 FALSO NINIT1. + basic_solver. } + intro FALSO. destruct ADD. + assert (CDD : e = mapper' e). + { unfold mapper'. rewrite upds; vauto. } + rewrite CDD in FALSO. + apply (seq_acts SIMREL) in FALSO. + destruct FALSO as [e' [C1 C2]]. + assert (C1' : E_t e') by vauto. + apply (seq_mapeq SIMREL) in C1; vauto. + { assert (EQQ : e' = e). + { rewrite CDD. rewrite <- C2. vauto. } + subst e'; desf. } + rewrite C2; rewrite <- CDD. + clear - T1 THRDNEQ. intros FALSE; desf. } + + assert (INDLEMMA : forall x y (NNIT : tid x <> tid_init) (EQT : tid x = tid y) (EQI : index x = index y), + x = y). + { clear. intros x y NNIT EQT EQI. + destruct x; destruct y; desf; ins. + desf. } + + unfold NW in NEWE. + destruct NEWE as (NINIT & NOTIN & TID). + + set (G_s' := {| + acts_set := mapper' ↑₁ E_t'; + threads_set := threads_set G_s; + lab := lab_t' ∘ mapper_rev'; + rf := mapper' ↑ rf_t'; + co := mapper' ↑ co_t'; + rmw := mapper' ↑ rmw_t'; + rmw_dep := ∅₂; + ctrl := ∅₂; + data := ∅₂; + addr := ∅₂; + |}). + set (X_s' := {| + WCore.sc := WCore.sc X_s; + WCore.G := G_s'; + |}). + + exists mapper', mapper_rev', X_s'. + assert (SIMRELQ : seq_simrel X_s' X_t' (tid e) t_2 mapper' mapper_rev' ptc_1). + { constructor; vauto; simpl; try basic_solver 6. + { rewrite (WCore.add_event_acts ADD). apply inj_dom_union. + { clear - SIMREL MAPEQ. + unfolder. ins. apply (seq_inj SIMREL); ins. + now rewrite <- !MAPEQ. } + { clear. basic_solver. } + rewrite MAPER_E, MAPSUB, (seq_codom SIMREL). + clear - NOTIN. basic_solver. } + { intros ev INE' TIDCOND. + destruct classic with (ev = e) as [EQ | NEQ]. + { subst ev. unfold mapper'. rewrite upds; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_tid_1 SIMREL); vauto. + apply EQACTS in INE'. destruct INE' as [C1 | C2]; vauto. + unfold mapper' in TIDCOND. rewrite updo in TIDCOND; vauto. } + { intros ev INE' TIDCOND. + destruct classic with (ev = e) as [EQ | NEQ]; vauto. + rewrite TID. apply (seq_tid_2 SIMREL); vauto. + { apply EQACTS in INE'. destruct INE' as [C1 | C2]; vauto. } + unfold mapper'. rewrite updo; vauto. } + { intros x COND. unfold compose. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper', mapper_rev'. + rewrite !upds; vauto. } + unfold mapper', mapper_rev'. + rewrite !updo; vauto. + { unfold compose in MAPREV. rewrite MAPREV. + { basic_solver. } + apply EQACTS in COND. + destruct COND as [C1 | C2]; vauto. } + rewrite updo; vauto. + assert (INE : E_t x). + { apply EQACTS in COND. + destruct COND as [C1 | C2]; vauto. } + intros FALSE. + assert (PROP : E_s e). + { rewrite <- FALSE. + apply (seq_codom SIMREL); vauto. } + desf. } + { rewrite EQACTS. + rewrite set_collect_union. + rewrite set_collect_union. + apply set_union_more. + { split. + { intros x COND. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper'. + desf. } + unfold set_collect. + exists (mapper' x). splits; vauto. + unfold mapper'. + rewrite updo; vauto. + unfold mapper_rev'. + rewrite updo; vauto. + { apply MAPREV; vauto. } + intros FALSE. + assert (INE : E_s e). + { destruct SIMREL. + apply seq_acts. + red; vauto. } + desf. } + intros x COND. + destruct COND as [x0 [[x1 [INE MAP1]] MAP2]]. + apply MAPREVDOM. + unfold set_collect. + exists x0; splits; vauto. + { destruct classic with (x1 = e) as [EQ | NEQ]. + { subst x1. unfold mapper'. + desf. } + unfold mapper'. + rewrite updo; vauto. + destruct SIMREL. + apply seq_acts. + red; vauto. } + unfold mapper'. + rewrite updo. + { unfold mapper_rev'. + rewrite updo; vauto. + intros FALSE. + assert (INES : E_s e). + { destruct SIMREL. + apply seq_acts. + red; vauto. } + desf. } + intros FALSE. desf. } + rewrite MAPER_E. + rewrite MEPERREV_E; vauto. } + { unfold sb. unfold G_s'; ins. + split; intros x y COND. + { destruct COND as [CD1 | CD2]. + { destruct CD1 as [x0 [[EQ1 [x' [INE1 M1]]] + [x1 [EXT [EQ2 [y' [INE2 M2]]]]]]]; subst. + unfold collect_rel. exists x', y'; splits; vauto. + unfold seq. exists x'; splits; vauto. + exists y'; splits; vauto. + unfold ext_sb in EXT. + destruct classic with (x' = e) as [EQ | NEQ]. + { subst. destruct e. + { clear - NINIT. desf. } + destruct classic with (thread = t_2) as [EQ | NEQ]. + { subst. clear - TID THRDNEQ. desf. } + unfold mapper' in EXT. rewrite upds in EXT. + destruct y'. + { destruct SIMREL. + clear - EXT seq_init. + unfold upd in EXT. desf. + rewrite seq_init in Heq; desf. } + destruct classic with (thread0 = t_2) as [EQ' | NEQ']. + { subst. destruct ADD. + exfalso. apply T2NOTIN. + apply add_event_threads; vauto. + apply wf_threads with (G := G_t') + (e := (ThreadEvent t_2 index0)); vauto. + apply INV'. } + desf. unfold upd in Heq. desf. + assert (MIND : index0 = index1). + { rewrite (seq_mapeq SIMREL) in Heq; vauto. + { apply EQACTS in INE2. + clear - INE2 n. + destruct INE2 as [C1 | C2]; vauto. } + intros FALSE. + rewrite <- (seq_tid_1 SIMREL) in FALSE; vauto. + { apply EQACTS in INE2. + clear - INE2 n. + destruct INE2 as [C1 | C2]; vauto. } + rewrite Heq in NEQ. desf. } + assert (MTID : thread0 = thread1). + { rewrite (seq_mapeq SIMREL) in Heq; vauto. + { apply EQACTS in INE2. + clear - INE2 n. + destruct INE2 as [C1 | C2]; vauto. } + intros FALSE. + rewrite <- (seq_tid_1 SIMREL) in FALSE; vauto. + { apply EQACTS in INE2. + clear - INE2 n. + destruct INE2 as [C1 | C2]; vauto. } + rewrite Heq in NEQ. desf. } + basic_solver 21. } + unfold mapper' in EXT. rewrite updo in EXT; vauto. + destruct x'. + { destruct SIMREL. + clear - seq_init EXT. + unfold upd in EXT. desf. + { destruct y'. + { rewrite seq_init in Heq0; desf. } + unfold ext_sb; basic_solver. } + destruct y'. + { rewrite seq_init in Heq0; desf. } + unfold ext_sb; basic_solver. } + destruct classic with (thread = t_2) as [EQ' | NEQ']. + { subst. destruct ADD. + exfalso. apply T2NOTIN. + apply add_event_threads; vauto. + apply wf_threads with (G := G_t') + (e := (ThreadEvent t_2 index)); vauto. + apply INV'. } + destruct classic with (y' = e) as [EQY | NEQY]. + { subst. unfold mapper' in EXT. rewrite upds in EXT. + desf. + { rewrite (seq_mapeq SIMREL) in Heq; vauto. + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + intros FALSE. + rewrite <- (seq_tid_1 SIMREL) in FALSE; vauto. + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite Heq in NEQ'. + unfold tid in NEQ'. destruct SIMREL. + assert (HLP : mapper_rev (InitEvent l0) = ThreadEvent thread index). + { rewrite <- Heq. apply MAPREV. + apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite seq_init_rev in HLP; vauto. } + destruct classic with (thread0 = t_2) as [EQT | NEQT]. + { subst. destruct ADD. + exfalso. apply T2NOTIN. + apply add_event_threads; vauto. + apply wf_threads with (G := G_t') + (e := (ThreadEvent t_2 index1)); vauto. + { apply INV'. } + destruct EXT; vauto. } + rewrite (seq_mapeq SIMREL) in Heq; vauto. + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite Heq. basic_solver. } + unfold mapper' in EXT. rewrite updo in EXT; vauto. + destruct y'. + { desf. + { destruct SIMREL. + clear - seq_init Heq0. + rewrite seq_init in Heq0; desf. } + destruct SIMREL. + clear - seq_init Heq0. + rewrite seq_init in Heq0; desf. } + desf. + { assert (HLP : mapper_rev (InitEvent l0) = ThreadEvent thread index). + { rewrite <- Heq. apply MAPREV. + apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite seq_init_rev in HLP; vauto. } + destruct EXT; subst. + destruct classic with (thread2 = t_2) as [EQT | NEQT]. + { subst. + assert (MIND1 : thread = t_1). + { rewrite <- (seq_tid_2 SIMREL) + with (e := (ThreadEvent thread index)); vauto. + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite Heq; vauto. } + assert (MIND2 : thread0 = t_1). + { rewrite <- (seq_tid_2 SIMREL) + with (e := (ThreadEvent thread0 index0)); vauto. + { apply EQACTS in INE2. + clear - INE2 NEQY. + destruct INE2 as [C1 | C2]; vauto. } + rewrite Heq0; vauto. } + assert (INDLESS : Events.index (ThreadEvent thread index) + < Events.index (ThreadEvent thread0 index0)). + { rewrite (seq_index SIMREL) + with (e := (ThreadEvent thread0 index0)). + { rewrite (seq_index SIMREL) + with (e := (ThreadEvent thread index)). + { rewrite Heq, Heq0. ins. + lia. } + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite Heq; vauto. } + { apply EQACTS in INE2. + clear - INE2 NEQY. + destruct INE2 as [C1 | C2]; vauto. } + rewrite Heq0; vauto. } + clear - MIND1 MIND2 INDLESS. + unfold ext_sb. basic_solver 21. } + rewrite (seq_mapeq SIMREL) in Heq; vauto. + { rewrite (seq_mapeq SIMREL) in Heq0; vauto. + { apply EQACTS in INE2. + clear - INE2 NEQY. + destruct INE2 as [C1 | C2]; vauto. } + rewrite Heq0; vauto. } + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite Heq; vauto. } + unfold po_seq in CD2. + change (WCore.G X_s') with G_s' in CD2. + unfold G_s' in CD2. ins. + destruct CD2 as [C1 C2]. + destruct C1 as [TR1 [x0 [IN1 MAP1]]]. + destruct C2 as [TR2 [y0 [IN2 MAP2]]]. + unfold collect_rel. exists x0, y0; splits. + { unfold seq. exists x0; splits. + { red; vauto. } + exists y0; splits. + { destruct SIMREL. + assert (NEQ1 : y0 <> e). + { intros FLS. subst y0. + unfold mapper' in MAP2. + rewrite upds in MAP2. + subst e. rewrite TID in TR2. + desf. } + assert (EQQ : mapper' y0 = mapper y0). + { unfold mapper'. rewrite updo; vauto. } + rewrite EQQ in MAP2. + destruct classic with (x0 = e) as [EQ | NEQ]. + { unfold ext_sb. + rewrite <- MAP2 in TR2. + apply seq_mapto in TR2. + { desf. + { rewrite seq_init in TR2. + { clear - TR2 NINIT2. + desf. } + desf. } + split. + { assert (TRH : tid (mapper + (ThreadEvent thread0 index0)) = t_2). + { rewrite TR2. + unfold tid; vauto. } + apply seq_thrd in TRH. + { unfold tid in *. desf. } + apply EQACTS in IN2. + destruct IN2 as [C1 | C2]; vauto. } + assert (LIAH : t_1_len <= index0). + { assert (TRH : tid (mapper + (ThreadEvent thread0 index0)) = t_2). + { rewrite TR2. + unfold tid; vauto. } + apply seq_index in TRH. + { unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. rewrite TRH. + assert (NINNIT : ~ is_init (mapper + (ThreadEvent thread0 index0))). + { intros FLS. + rewrite TR2 in FLS. + unfold is_init in FLS. + desf. } + lia. } + apply EQACTS in IN2. + destruct IN2 as [C1 | C2]; vauto. } + unfold Events.index in *. + lia. } + apply EQACTS in IN2. + destruct IN2 as [C1 | C2]; vauto. } + unfold ext_sb. + rewrite <- MAP2 in TR2. + apply seq_mapto in TR2. + { desf. + { rewrite seq_init in TR2. + { clear - TR2 NINIT2. + desf. } + desf. } + { rewrite seq_init in TR2. + { clear - TR2 NINIT2. + desf. } + desf. } + split. + { assert (TRH : tid (mapper + (ThreadEvent thread0 index0)) = t_2). + { rewrite TR2. + unfold tid; vauto. } + apply seq_thrd in TRH. + { unfold tid in *. desf. + { exfalso. clear - TR1 NINIT1. + apply NINIT1; vauto. } + destruct classic with (thread = t_2) as [EQ2 | NEQ2]. + { apply wf_threads in IN1; [| apply INV']. + unfold tid in IN1. + rewrite EQ2 in IN1. + destruct ADD. + apply add_event_threads in IN1. + desf. } + destruct classic with (thread = t_1) as [EQ3 | NEQ3]; vauto. + unfold mapper' in Heq. + rewrite updo in Heq; vauto. + assert (INEE : E_t (ThreadEvent thread index)). + { apply EQACTS in IN1. + destruct IN1 as [C1 | C2]; vauto. } + assert (TNEQQ : tid (mapper (ThreadEvent thread index)) <> t_2). + { rewrite Heq. unfold tid; vauto. } + apply seq_out in INEE; vauto. + rewrite Heq in INEE. + clear - INEE. basic_solver. } + apply EQACTS in IN2. + destruct IN2 as [C1 | C2]; vauto. } + assert (LIAH : t_1_len <= index0). + { assert (TRH : tid (mapper + (ThreadEvent thread0 index0)) = t_2). + { rewrite TR2. + unfold tid; vauto. } + apply seq_index in TRH. + { unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. rewrite TRH. + assert (NINNIT : ~ is_init (mapper + (ThreadEvent thread0 index0))). + { intros FLS. + rewrite TR2 in FLS. + unfold is_init in FLS. + desf. } + lia. } + apply EQACTS in IN2. + destruct IN2 as [C1 | C2]; vauto. } + assert (INDN : index < t_1_len). + { assert (INEE : E_t (ThreadEvent thread index)). + { apply EQACTS in IN1. + destruct IN1 as [C1 | C2]; vauto. } + unfold mapper' in TR1. + rewrite updo in TR1; vauto. + assert (TNEQQ : tid (mapper (ThreadEvent thread index)) <> t_2). + { rewrite TR1. rewrite TID. desf. } + apply seq_mapeq in INEE; vauto. + assert (TTDS : thread = t_1). + { rewrite INEE in TR1. + unfold tid in *; vauto. } + assert (INET : E_t (ThreadEvent thread index)). + { apply EQACTS in IN1. + destruct IN1 as [C1 | C2]; vauto. } + apply NNPP. intros FLS. + apply Compare_dec.not_lt in FLS. + apply seq_out_move in INET; vauto. + rewrite INEE in INET. + clear - INET THRDNEQ. + desf. } + lia. } + apply EQACTS in IN2. + destruct IN2 as [C1 | C2]; vauto. } + red; vauto. } + all : vauto. } + destruct COND as [x0 [y0 [[x1 [[EQ1 INE1] + [y1 [COND [EQ2 INE2]]]]] [M1 M2]]]]. + subst. + assert (INE1' : (acts_set G_s') (mapper' x1)). + { unfold G_s'; ins. + unfold set_collect. + exists x1; vauto. } + assert (INE2' : (acts_set G_s') (mapper' y0)). + { unfold G_s'; ins. + unfold set_collect. + exists y0; vauto. } + destruct classic with (tid (mapper' y0) = t_2) as [EQ1 | NEQ1]. + { destruct classic with (tid (mapper' x1) = t_1) as [EQ2 | NEQ2]. + { right. unfold po_seq. + split. + { split; vauto. + rewrite TID; vauto. } + split; vauto. } + left. + assert (TIDD2 : tid y0 = t_1). + { destruct classic with (y0 = e) as [EQ | NEQ]. + { subst y0; vauto. } + unfold mapper' in EQ1. + rewrite updo in EQ1. + { assert (EQ1' : tid (mapper y0) = t_2) by vauto. + apply (seq_thrd SIMREL) in EQ1'; vauto. + apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + vauto. } + destruct x1. + { unfold seq. exists (mapper' (InitEvent l0)); split. + { red; vauto. } + exists (mapper' y0); split. + { arewrite (mapper' (InitEvent l0) = mapper (InitEvent l0)). + { unfold mapper'. rewrite updo; vauto. + intros FLS. apply NINIT; vauto. } + rewrite (seq_init SIMREL). + { unfold ext_sb; vauto. + desf. } + vauto. } + red; vauto. } + assert (TIDD : thread = t_1). + { unfold ext_sb in COND. + desf. unfold tid in TIDD2. + rewrite <- TIDD2; vauto. + destruct COND; vauto. } + destruct y0. + { exfalso. unfold tid in TIDD2; vauto. } + unfold ext_sb in COND. + destruct COND as [COND1 COND2]. + unfold seq. + exists (mapper' (ThreadEvent thread index)); split. + { red; vauto. } + exists (mapper' (ThreadEvent thread0 index0)); split. + { assert (INDD : index >= t_1_len). + { apply NNPP. intros FLS. + apply Compare_dec.not_ge in FLS. + assert (INET : E_t (ThreadEvent thread index)). + { destruct classic with ((ThreadEvent thread index) = e) as [EQ | NEQ]. + { exfalso. unfold mapper' in NEQ2. + rewrite EQ in NEQ2. + rewrite upds in NEQ2; vauto. } + apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + apply (seq_out_snd SIMREL) in INET; vauto. + destruct classic with ((ThreadEvent t_1 index) = e) as [EQ | NEQ]. + { exfalso. unfold mapper' in NEQ2. + rewrite EQ in NEQ2. + rewrite upds in NEQ2; vauto. } + unfold mapper' in NEQ2. + rewrite updo in NEQ2; vauto. + rewrite INET in NEQ2. + desf. } + assert (INEE1 : E_t (ThreadEvent thread index)). + { destruct classic with ((ThreadEvent thread index) = e) as [EQ | NEQ]. + { exfalso. unfold mapper' in NEQ2. + rewrite EQ in NEQ2. + rewrite upds in NEQ2; vauto. } + apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + assert (INEE2 : E_t (ThreadEvent thread0 index0)). + { destruct classic with ((ThreadEvent thread0 index0) = e) as [EQ | NEQ]. + { exfalso. unfold mapper' in EQ1. + rewrite EQ in EQ1. + rewrite upds in EQ1; vauto. } + apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + apply (seq_out_move SIMREL) in INEE1, INEE2; vauto. + { assert (SWP1 : mapper' (ThreadEvent t_1 index) + = mapper (ThreadEvent t_1 index)). + { unfold mapper'. + destruct classic with (ThreadEvent t_1 index = e) as [EQ | NEQ]. + { exfalso. unfold mapper' in NEQ2. + rewrite EQ in NEQ2. + rewrite upds in NEQ2; vauto. } + rewrite updo; vauto. } + assert (SWP2 : mapper' (ThreadEvent t_1 index0) + = mapper (ThreadEvent t_1 index0)). + { unfold mapper'. + destruct classic with (ThreadEvent t_1 index0 = e) as [EQ | NEQ]. + { exfalso. rewrite EQ in THRDNEQ. + unfold mapper' in THRDNEQ. + rewrite upds in THRDNEQ; vauto. } + rewrite updo; vauto. } + rewrite SWP1, SWP2. + rewrite INEE1, INEE2. + unfold ext_sb. split; vauto. + unfold Events.index. + clear - COND2 INDD. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + red; vauto. } + destruct classic with (y0 = e) as [EQ | NEQ]. + { subst y0. left. + unfold seq. exists (mapper' x1); split; vauto. + exists (mapper' e); split; vauto. + destruct classic with (tid (mapper' x1) = t_2) as [EQ2 | NEQ2]. + { destruct classic with (x1 = e) as [EQ3 | NEQ3]. + { subst x1. unfold mapper'. + desf. } + assert (INEE : E_t x1). + { apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + apply (seq_index SIMREL) in INEE; vauto. + { exfalso. unfold ext_sb in COND. + desf. + { rewrite (seq_init SIMREL) in INEE; vauto. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + destruct COND as [COND1 COND2]. + unfold Events.index in INEE at 1. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + unfold Events.index in IND. + lia. } + unfold mapper'. rewrite updo; vauto. } + assert (INEE : E_t x1). + { destruct classic with (x1 = e) as [EQ3 | NEQ3]. + { subst x1. unfold ext_sb in COND. desf. + destruct COND as [COND1 COND2]. + exfalso. clear - COND2. lia. } + apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + apply (seq_mapeq SIMREL) in INEE; vauto. + { arewrite (mapper' x1 = mapper x1). + { unfold mapper'. rewrite updo; vauto. + intros FALSO. subst x1. + unfold ext_sb in COND. desf. + destruct COND as [COND1 COND2]. + exfalso. lia. } + rewrite INEE. + unfold mapper'. + rewrite upds; vauto. } + assert (SWP : mapper' x1 = mapper x1). + { unfold mapper'. rewrite updo; vauto. + intros FALSO. subst x1. + unfold ext_sb in COND. desf. } + rewrite SWP in NEQ2; vauto. } + destruct classic with (x1 = e) as [EQ2 | NEQ2]. + { subst x1. + left. + assert (SWP : mapper' y0 = mapper y0). + { unfold mapper'. rewrite updo; vauto. } + rewrite SWP in NEQ1; vauto. + assert (INEE : E_t y0). + { apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + apply (seq_mapeq SIMREL) in INEE; vauto. + unfold seq. exists (mapper' e); split; vauto. + exists (mapper' y0); split; vauto. + rewrite SWP, INEE. + unfold mapper'. + rewrite upds; vauto. } + left. + unfold seq. exists (mapper' x1); split; vauto. + exists (mapper' y0); split; vauto. + destruct classic with (tid (mapper' x1) = t_2) as [EQ3 | NEQ3]. + { unfold mapper' in EQ3. rewrite updo in EQ3. + { assert (INEE : E_t x1). + { apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + assert (INEE' : E_t x1) by vauto. + apply (seq_index SIMREL) in INEE. + { apply (seq_thrd SIMREL) in INEE'. + { destruct classic with (index y0 < t_1_len) as [LS | GT]. + assert (INEY : E_t y0). + { apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + unfold ext_sb in COND. + desf. + { unfold mapper' at 1. + rewrite updo; vauto. + rewrite (seq_init SIMREL); vauto. + unfold ext_sb; vauto. + desf. + unfold mapper' in Heq. + rewrite updo in Heq; vauto. + assert (REVV : mapper_rev (mapper (ThreadEvent thread index)) + = mapper_rev (InitEvent l1)). + { rewrite Heq; vauto. } + unfold compose in MAPREV. + rewrite MAPREV in REVV; vauto. + unfold id in REVV. + rewrite (seq_init_rev SIMREL) in REVV; vauto. } + { unfold mapper'. + rewrite !updo; vauto. + unfold Events.index in *. + destruct COND as [COND1 COND2]. + exfalso. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + exfalso. + apply Compare_dec.not_lt in GT. + assert (INEY : E_t y0). + { apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + apply (seq_out_move SIMREL) in INEY; vauto. + { unfold mapper' in NEQ1. + rewrite updo in NEQ1; vauto. + rewrite INEY in NEQ1. + desf. } + unfold ext_sb in COND. + desf. + { exfalso. + unfold tid in INEE'. + apply NINIT1; vauto. } + unfold tid in INEE'. + destruct COND as [COND1 COND2]. + unfold tid; vauto. } + vauto. } + vauto. } + vauto. } + assert (INEE : E_t x1). + { apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + assert (INEE' : E_t y0). + { apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + apply (seq_mapeq SIMREL) in INEE. + { apply (seq_mapeq SIMREL) in INEE'. + { unfold mapper'. + rewrite !updo; vauto. + rewrite INEE, INEE'; vauto. } + unfold mapper' in NEQ1. + rewrite updo in NEQ1; vauto. } + unfold mapper' in NEQ3. + rewrite updo in NEQ3; vauto. } + { rewrite (seq_threads SIMREL). + destruct ADD. rewrite add_event_threads; vauto. } + { unfold mapper'. intros x COND. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. rewrite upds; vauto. } + rewrite updo; vauto. + apply (seq_init SIMREL); vauto. } + { unfold mapper_rev'. intros x COND. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. rewrite upds; vauto. } + rewrite updo; vauto. + apply (seq_init_rev SIMREL); vauto. } + { intros e' INE TID2. + destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper'. rewrite upds; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_mapeq SIMREL); vauto. + { apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + unfold mapper' in TID2. rewrite updo in TID2; vauto. } + { intros x MAP TIDS. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper_rev'. rewrite upds; vauto. } + destruct MAP as [x0 [INE MAP]]. + unfold mapper_rev'. + rewrite updo; vauto. + unfold mapper'. + rewrite updo; vauto. + { unfold mapper' in TIDS. + rewrite updo in TIDS; vauto. + { destruct SIMREL. + apply seq_mapeq_rev in TIDS; vauto. + apply seq_acts. + red; exists x0; splits; vauto. + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. + apply seq_mapeq in TIDS; vauto. + { unfold mapper' in NEQ. + rewrite upds in NEQ. + desf. } + unfold mapper' in NEQ. + rewrite upds in NEQ. + desf. } + intros FLS. subst. + unfold mapper' in NEQ. + rewrite upds in NEQ. desf. } + intros FLS. subst. + unfold mapper' in NEQ. + rewrite upds in NEQ. desf. } + { intros e' INE TID2. + destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper' in TID2. + rewrite upds in TID2. exfalso. + clear - TID TID2 THRDNEQ. desf. } + assert (INE' : E_t e'). + { apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + assert (MAPEQQ : mapper' e' = mapper e'). + { unfold mapper'. rewrite updo; vauto. } + rewrite MAPEQQ. + apply (seq_mapto SIMREL) in INE'. + { rewrite TID; vauto. } + rewrite <- MAPEQQ; vauto. } + { intros e' INE TID2. + destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper' in TID2. + rewrite upds in TID2. exfalso. + clear - TID TID2 THRDNEQ. desf. } + assert (INE' : E_t e'). + { apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + assert (MAPEQQ : mapper' e' = mapper e'). + { unfold mapper'. rewrite updo; vauto. } + rewrite MAPEQQ. + apply (seq_index SIMREL) in INE'. + { rewrite TID; vauto. } + rewrite <- MAPEQQ; vauto. } + { intros x INE TID2. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper' in TID2. + rewrite upds in TID2. exfalso. + clear - TID TID2 THRDNEQ. desf. } + unfold mapper' in TID2. + rewrite updo in TID2. + { destruct SIMREL. + apply seq_thrd in TID2. + { rewrite TID2; vauto. } + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + vauto. } + { intros x INE TID2. + unfold mapper_rev'. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. exfalso. + clear - TID TID2 THRDNEQ. desf. } + rewrite updo; vauto. + rewrite (seq_maprev SIMREL); vauto. + { apply INDLEMMA; vauto. + unfold index. rewrite TID; lia. } + apply (seq_acts SIMREL). + apply MAPSUB. + unfold set_collect in INE. + destruct INE as [x0 [INE MAP]]. + apply EQACTS in INE. + destruct INE as [C1 | C2]. + { vauto. } + rewrite <- C2 in MAP. + assert (MAPNORM : mapper' e = e). + { rewrite set_collect_eq in MAPER_E. + apply MAPER_E; vauto. } + desf. } + { intros x INE TID2. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper'. + rewrite upds. exfalso. desf. } + unfold mapper'. + rewrite updo; vauto. + destruct SIMREL. + rewrite seq_out; vauto. + { apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + rewrite <- TID; vauto. } + { intros x INE TIDS IDXS. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper'. + rewrite upds. desf. } + unfold mapper'. + rewrite updo; vauto. + destruct SIMREL. + rewrite seq_out_snd; vauto. + { apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + { rewrite <- TID; vauto. } + rewrite <- TID; vauto. } + { intros x INE TIDS IDXS. + destruct classic with (x = e) as [EQ | NEQ]. + { subst. clear - IDXS IND TID. + exfalso. unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + rewrite TID in IDXS. + lia. } + unfold mapper'. + rewrite updo; vauto. + destruct SIMREL. + rewrite seq_out_move. + { rewrite <- TID; vauto. } + { apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + { rewrite <- TID; vauto. } + rewrite <- TID; vauto. } + { intros e' NINE. + destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper'. rewrite upds; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_rest SIMREL); vauto. + intros FALSE. apply NINE. + apply EQACTS. unfold set_union. + left; vauto. } + intros e' NINE. + destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper_rev'. rewrite upds; vauto. } + unfold mapper_rev'. rewrite updo; vauto. + apply (seq_rest_rev SIMREL); vauto. + intros FALSE. apply NINE. unfold set_collect. + exists (mapper_rev e'). split. + { apply EQACTS. left. apply MAPREVDOM. + basic_solver. } + unfold mapper'. rewrite updo; vauto. + { apply MAPREVR; vauto. } + intros FLS. + assert (WRG : E_t e). + { apply MAPREVDOM. basic_solver 4. } + desf. } + splits. + { rewrite <- TID; vauto. } + constructor. + { unfold WCore.add_event. + exists (option_map mapper' r), (mapper' ↑₁ R1), + (option_map mapper' w), + (mapper' ↑₁ W1), + (mapper' ↑₁ W2). + apply add_event_to_wf; simpl; vauto. + { apply sico_init_acts_s with + (X_t := X_t) (mapper := mapper). + { constructor. all : try apply SIMREL. + rewrite (seq_lab SIMREL); vauto. } + destruct ADD. apply add_event_init. } + { unfold mapper'. rewrite upds. exact NOTIN. } + { unfold mapper'. rewrite upds; vauto. } + { unfold mapper'. rewrite upds. + rewrite TID. basic_solver. } + { rewrite EQACTS. rewrite set_collect_union. + rewrite MAPER_E, MAPSUB. rewrite (seq_acts SIMREL). + unfold mapper'. rewrite upds. basic_solver. } + { destruct ADD. destruct SIMRELQ. + unfold mapper', mapper_rev'. + apply functional_extensionality; ins. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. rewrite !upds. vauto. + rewrite add_event_lab. + unfold compose. rewrite upds. + rewrite upds; vauto. } + rewrite !updo; vauto. + { rewrite add_event_lab. + unfold compose. rewrite updo; vauto. + { destruct SIMREL. + destruct classic with (E_s x) as [INN | NINN]. + { rewrite updo; vauto. + rewrite seq_lab_rev0; vauto. } + rewrite updo; vauto. + rewrite seq_rlab0; vauto. } + rewrite updo; vauto. + destruct classic with (E_s x) as [INN | NINN]. + { destruct SIMREL. + intros FALSE. + assert (STT : mapper (mapper_rev x) = mapper e) + by vauto. + unfold compose in MAPREVR. + rewrite MAPREVR in STT. + { unfold id in STT. + rewrite seq_rest0 in STT; vauto. } + vauto. } + destruct SIMREL. + rewrite seq_rest_rev0; vauto. } + rewrite upds; vauto. } + { destruct ADD. rewrite add_event_rf. + rewrite !collect_rel_union. + arewrite (mapper' ↑ rf_t ≡ mapper ↑ rf_t). + { apply collect_rel_eq_dom' with (s := E_t); ins. + apply (wf_rfE); vauto. } + rewrite (seq_rf SIMREL). + arewrite (mapper' ↑ WCore.rf_delta_R e w + ≡ WCore.rf_delta_R (mapper' e) + (option_map mapper' w)). + { unfold WCore.rf_delta_R. + rewrite collect_rel_cross. + apply cross_more. + { clear. unfold option_map. basic_solver. } + clear. unfold option_map. basic_solver. } + arewrite (mapper' ↑ WCore.rf_delta_W e R1 + ≡ WCore.rf_delta_W (mapper' e) (mapper' ↑₁ R1)). + { unfold WCore.rf_delta_W. + rewrite collect_rel_cross. + apply cross_more. + { clear. unfold option_map. basic_solver. } + clear. unfold option_map. basic_solver. } + vauto. } + { destruct ADD. rewrite add_event_co. + rewrite !collect_rel_union. + arewrite (mapper' ↑ co_t ≡ mapper ↑ co_t). + { apply collect_rel_eq_dom' with (s := E_t); ins. + apply (wf_coE); vauto. } + rewrite (seq_co SIMREL). + arewrite (mapper' ↑ WCore.co_delta e W1 W2 + ≡ WCore.co_delta (mapper' e) (mapper' ↑₁ W1) + (mapper' ↑₁ W2)). + { unfold WCore.co_delta. rewrite collect_rel_union. + apply union_more. + { rewrite collect_rel_cross. + apply cross_more; vauto. + clear. basic_solver. } + rewrite collect_rel_cross. + apply cross_more; vauto. + clear. basic_solver. } + vauto. } + { rewrite <- mapped_rmw_delta, (WCore.add_event_rmw ADD), + collect_rel_union. + arewrite (mapper' ↑ rmw_t ≡ mapper ↑ rmw_t). + { apply collect_rel_eq_dom' with (s := E_t); ins. + apply (wf_rmwE); vauto. } + now rewrite (seq_rmw SIMREL). } + { rewrite (seq_data SIMREL); vauto. } + { rewrite (seq_addr SIMREL); vauto. } + { rewrite (seq_ctrl SIMREL); vauto. } + { rewrite (seq_rmw_dep SIMREL); vauto. } + { assert (SBEQ1 : sb_s ≡ mapper ↑ sb_t \ po_seq X_s t_1 t_2). + { rewrite <- (seq_sb SIMREL). + rewrite minus_union_l. + rewrite minusK. split; [| basic_solver]. + intros x y COND. + left. split; vauto. + intros FLS. + unfold po_seq in FLS. + destruct FLS as [[TID1 INE1] [TID2 INE2]]. + unfold sb in COND. unfold ext_sb in COND. + clear - COND TID1 TID2 NINIT1 NINIT2 THRDNEQ. + destruct COND as [x0 [[EQQ1 INEE1] [x1 [COND2 [EQQ2 INEE2]]]]]. + subst. desf. basic_solver 42. } + assert (SBEQ2 : sb G_s' ≡ mapper' ↑ sb_t' \ po_seq X_s' t_1 t_2). + { rewrite <- (seq_sb SIMRELQ). + rewrite minus_union_l. rewrite TID. + rewrite minusK. split; [| basic_solver]. + intros x y COND. + left. split; vauto. + intros FLS. + unfold po_seq in FLS. + destruct FLS as [[TID1 INE1] [TID2 INE2]]. + unfold sb in COND. unfold ext_sb in COND. + clear - COND TID1 TID2 NINIT1 NINIT2 THRDNEQ. + destruct COND as [x0 [[EQQ1 INEE1] [x1 [COND2 [EQQ2 INEE2]]]]]. + subst. desf. basic_solver 42. } + rewrite SBEQ1, SBEQ2. + unfold WCore.sb_delta. + destruct ADD. rewrite add_event_sb. + admit. (* all the events except t_2 are stay on their + places, t_2 moves in order and delta-edges + are added respectively as well *) } + arewrite (G_s' = WCore.G X_s'). + apply wf_transition with (X_t := X_t') + (t_1 := t_1) (t_2 := t_2) + (mapper := mapper') (mapper_rev := mapper_rev') + (ptc_1 := ptc_1); vauto. + rewrite <- TID; vauto. } + { unfold rf_complete. + rewrite (seq_acts SIMRELQ), (seq_rf SIMRELQ). + unfold rf_complete in RFC. rewrite EQACTS. + rewrite !set_collect_union, MAPER_E, MAPSUB. + rewrite set_inter_union_l. + rewrite set_subset_union_l; split. + { unfold rf_complete in RFC. + rewrite <- set_collect_codom, <- RFC. + unfolder. intros x ((x' & INE & XEQ) & ISR). + exists x'. splits; try basic_solver. + { apply EQACTS; vauto. } + subst x. unfold is_r in *. + assert (CHNG : WCore.G X_s' = G_s') by vauto. + rewrite CHNG in ISR. unfold G_s' in ISR; ins. + unfold compose in ISR. + assert (NEQ : x' <> e). + { intros FALSE. subst x'. basic_solver 8. } + assert (NEQ' : mapper x' <> e). + { intros FALSE. destruct NOTIN. + rewrite <- FALSE. apply (seq_codom SIMREL); vauto. } + assert (EQQ : mapper_rev' (mapper x') = x'). + { unfold eq_dom in MAPREV. specialize MAPREV with x'. + apply MAPREV in INE. unfold compose in INE. + unfold mapper_rev'. rewrite updo; vauto. } + rewrite EQQ in ISR; vauto. } + rewrite <- set_collect_codom. rewrite <- RFC. + intros x (EQ & RD). subst x. + unfold set_collect. exists e. splits; vauto. + { split. + { apply EQACTS. basic_solver. } + assert (FEQ : WCore.G X_s' = G_s') by vauto. + rewrite FEQ in RD. unfold G_s' in RD. + simpl in RD. clear - RD. unfold compose in RD. + unfold is_r in RD. unfold mapper_rev' in RD. + rewrite upds in RD; vauto. } + unfold mapper'. rewrite upds. vauto. } + apply XmmCons.monoton_cons with (G_t := G_t') + (m := mapper'); vauto; try apply SIMRELQ. + { unfold rpo. unfold rpo_imm. + arewrite (WCore.G X_s' = G_s'). + destruct SIMRELQ. + assert (RESTR : ⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ sb_t' ⨾ ⦗F G_t' ∩₁ Acq G_t'⦘ ∪ ⦗Acq G_t'⦘ ⨾ sb_t' ∪ sb_t' ⨾ ⦗Rel G_t'⦘ + ∪ ⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ sb_t' ⨾ ⦗W_t' ∩₁ Rlx G_t'⦘ ≡ restr_rel E_t' ( + ⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ sb_t' ⨾ ⦗F G_t' ∩₁ Acq G_t'⦘ ∪ ⦗Acq G_t'⦘ ⨾ sb_t' ∪ sb_t' ⨾ ⦗Rel G_t'⦘ + ∪ ⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ sb_t' ⨾ ⦗W_t' ∩₁ Rlx G_t'⦘)). + { split. + { rewrite !restr_union. + repeat apply union_mori. + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] [x1 [COND [EQ2 CD2]]]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] COND]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x1 [COND [EQ2 CD2]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] [x1 [COND [EQ2 CD2]]]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + rewrite inclusion_restr; vauto. } + rewrite RESTR. + rewrite collect_rel_ct_inj. + { assert (MAPREVCOMP : eq_dom (acts_set G_s') (mapper' ∘ mapper_rev') id). + { intros x COND. + unfold G_s' in COND; ins. + destruct COND as [x0 [COND EQ]]; subst. + unfold compose. + destruct classic with (x0 = e) as [EQ1 | NEQ1]. + { subst x0. unfold mapper', mapper_rev'. + rewrite !upds; vauto. } + apply EQACTS in COND. + destruct COND as [C1 | C2]. + { unfold mapper', mapper_rev'. + unfold id. + arewrite (upd mapper e e x0 = mapper x0). + arewrite (upd mapper_rev e e (mapper x0) = mapper_rev (mapper x0)). + { destruct classic with (mapper x0 = e) as [EQ2 | NEQ2]. + { destruct SIMREL. + assert (INEE : E_s e). + { apply seq_acts0. + red; vauto. } + desf. } + rewrite updo; vauto. } + unfold compose in MAPREV. + rewrite MAPREV; vauto. + unfold id. rewrite updo; vauto. } + desf. } + assert (SBIN : sb G_s' ⊆ mapper' ↑ sb_t'). + { rewrite <- seq_sb; vauto. } + apply clos_trans_mori. + rewrite <- RESTR. + rewrite !collect_rel_union. + repeat apply union_mori. + { rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + arewrite (⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (F G_t' ∩₁ Acq G_t')⦘ ≡ + ⦗R_t' ∩₁ Rlx G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (F G_t' ∩₁ Acq G_t')⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [[ISR ISRLX] INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rlx, mod in ISRLX. + rewrite seq_lab_rev in ISRLX; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_r. unfold compose in ISRLX; vauto. } + { unfold is_rlx. unfold compose in ISRLX; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE [ISF ISA]]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_acq, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + { unfold is_r. unfold compose in ISA; vauto. } + unfold is_rlx. unfold compose in ISA; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + { rewrite wf_sbE. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + arewrite (⦗Acq G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t'⦘ ≡ + ⦗Acq G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t'⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [ISA INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_acq, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_acq. unfold compose in ISA; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ INE]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + { rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ INE]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE ISR]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rel, mod in ISR. + rewrite seq_lab_rev in ISR; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + unfold is_rel. unfold compose in ISR; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + arewrite (⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (W_t' ∩₁ Rlx G_t')⦘ ≡ + ⦗F G_t' ∩₁ Rel G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (W_t' ∩₁ Rlx G_t')⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [[ISF ISREL] INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rel, mod in ISREL. + rewrite seq_lab_rev in ISREL; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_r. unfold compose in ISREL; vauto. } + { unfold is_rlx. unfold compose in ISREL; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE [ISF ISA]]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rlx, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + { unfold is_r. unfold compose in ISA; vauto. } + unfold is_rlx. unfold compose in ISA; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + vauto. } + { rewrite <- (seq_lab SIMRELQ); vauto. } + { assert (SBEQ : sb G_s' ≡ mapper' ↑ sb_t' \ po_seq X_s' t_1 t_2). + { rewrite <- (seq_sb SIMRELQ). + rewrite minus_union_l. rewrite TID. + rewrite minusK. split; [| basic_solver]. + intros x y COND. + left. split; vauto. + intros FLS. + unfold po_seq in FLS. + destruct FLS as [[TID1 INE1] [TID2 INE2]]. + unfold sb in COND. unfold ext_sb in COND. + clear - COND TID1 TID2 NINIT1 NINIT2 THRDNEQ. + destruct COND as [x0 [[EQQ1 INEE1] [x1 [COND2 [EQQ2 INEE2]]]]]. + subst. desf. basic_solver 42. } + arewrite (WCore.G X_s' = G_s'). + rewrite SBEQ. + intros x y COND. + destruct COND as [[CDMAP POSEQ] COND2]. + destruct CDMAP as [x0 [x1 [CND [M1 M2]]]]. + unfold collect_rel. + exists x0, x1; split; vauto. + split; vauto. + unfold same_loc in *. + destruct SIMRELQ. + unfold loc. rewrite !seq_lab. + { unfold compose; vauto. } + all : apply wf_sbE in CND. + all : destruct CND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; vauto. } + { apply INV'. } + apply wf_transition with (X_t := X_t') + (t_1 := t_1) (t_2 := t_2) + (mapper := mapper') (mapper_rev := mapper_rev') + (ptc_1 := ptc_1); vauto. + rewrite <- TID; vauto. +Admitted. + +End SimrelStep. diff --git a/src/sequentialization/SequentExec2.v b/src/sequentialization/SequentExec2.v new file mode 100644 index 00000000..8f997df8 --- /dev/null +++ b/src/sequentialization/SequentExec2.v @@ -0,0 +1,1418 @@ +Require Import AuxDef. +Require Import Core. +Require Import AuxRel AuxRel2. +Require Import Srf Rhb. +Require Import SimrelCommon. +Require Import StepOps. +Require Import AuxInj. +Require Import xmm_s_hb. +Require Import Lia. +From xmm Require Import Reordering. +From xmm Require Import ThreadTrace. +From xmm Require Import Programs. +From xmm Require Import SequentBase. +From xmm Require Import SequentWf. +From xmm Require Import ConsistencyMonotonicity. + +From hahn Require Import Hahn. +From hahnExt Require Import HahnExt. +From imm Require Import Events Execution Execution_eco. +Require Import Setoid Morphisms Program.Basics. + +Open Scope program_scope. + +Set Implicit Arguments. + +Section SimrelStep. + +Variable X_t X_t' X_s : WCore.t. +Variable t_1 t_2 : thread_id. +Variable mapper : actid -> actid. +Variable mapper_rev : actid -> actid. + +Variable e : actid. +Variable l : label. + +Variable thrdle : relation thread_id. + +Variable ptc_1 ptc_2 : program_trace. + +Notation "'G_t'" := (WCore.G X_t). +Notation "'G_t''" := (WCore.G X_t'). +Notation "'G_s'" := (WCore.G X_s). + +Notation "'R' G" := (fun e => is_true (is_r (lab G) e)) (at level 1). +Notation "'F' G" := (fun e => is_true (is_f (lab G) e)) (at level 1). +Notation "'W' G" := (fun e => is_true (is_w (lab G) e)) (at level 1). +Notation "'Acq' G" := (fun e => is_true (is_acq (lab G) e)) (at level 1). +Notation "'Rlx' G" := (fun e => is_true (is_rlx (lab G) e)) (at level 1). +Notation "'Rel' G" := (fun e => is_true (is_rel (lab G) e)) (at level 1). + +Notation "'lab_t'" := (lab G_t). +Notation "'val_t'" := (val lab_t). +Notation "'loc_t'" := (loc lab_t). +Notation "'same_loc_t'" := (same_loc lab_t). +Notation "'E_t'" := (acts_set G_t). +Notation "'sb_t'" := (sb G_t). +Notation "'rf_t'" := (rf G_t). +Notation "'co_t'" := (co G_t). +Notation "'rmw_t'" := (rmw G_t). +Notation "'rpo_t'" := (rpo G_t). +Notation "'rmw_dep_t'" := (rmw_dep G_t). +Notation "'data_t'" := (data G_t). +Notation "'ctrl_t'" := (ctrl G_t). +Notation "'addr_t'" := (addr G_t). +Notation "'W_t'" := (fun x => is_true (is_w lab_t x)). +Notation "'R_t'" := (fun x => is_true (is_r lab_t x)). +Notation "'Loc_t_' l" := (fun e => loc_t e = l) (at level 1). + +Notation "'lab_t''" := (lab G_t'). +Notation "'val_t''" := (val lab_t'). +Notation "'loc_t''" := (loc lab_t'). +Notation "'same_loc_t''" := (same_loc lab_t'). +Notation "'E_t''" := (acts_set G_t'). +Notation "'sb_t''" := (sb G_t'). +Notation "'rf_t''" := (rf G_t'). +Notation "'co_t''" := (co G_t'). +Notation "'rmw_t''" := (rmw G_t'). +Notation "'rpo_t''" := (rpo G_t'). +Notation "'rmw_dep_t''" := (rmw_dep G_t'). +Notation "'data_t''" := (data G_t'). +Notation "'ctrl_t''" := (ctrl G_t'). +Notation "'addr_t''" := (addr G_t'). +Notation "'W_t''" := (fun x => is_true (is_w lab_t' x)). +Notation "'R_t''" := (fun x => is_true (is_r lab_t' x)). +Notation "'Loc_t_'' l" := (fun e => loc_t' e = l) (at level 1). + +Notation "'lab_s'" := (lab G_s). +Notation "'val_s'" := (val lab_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'same_loc_s'" := (same_loc lab_s). +Notation "'E_s'" := (acts_set G_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'sb_s'" := (sb G_s). +Notation "'rf_s'" := (rf G_s). +Notation "'co_s'" := (co G_s). +Notation "'rmw_s'" := (rmw G_s). +Notation "'rpo_s'" := (rpo G_s). +Notation "'rmw_dep_s'" := (rmw_dep G_s). +Notation "'data_s'" := (data G_s). +Notation "'ctrl_s'" := (ctrl G_s). +Notation "'addr_s'" := (addr G_s). +Notation "'W_s'" := (fun x => is_true (is_w lab_s x)). +Notation "'R_s'" := (fun x => is_true (is_r lab_s x)). +Notation "'F_s'" := (F G_s). + +Notation "'Tid_' t" := (fun e => tid e = t) (at level 1). + +Hypothesis MAPREV : eq_dom E_t (mapper_rev ∘ mapper) id. +Hypothesis MAPREVR : eq_dom E_s (mapper ∘ mapper_rev) id. +Hypothesis PROGSEQ : program_trace_sequented ptc_1 ptc_2 t_1 t_2. +Hypothesis WFT : Wf G_t. + +Definition t_12_len := length (ptc_2 t_1). +Definition t_1_len := length (ptc_1 t_1). +Definition t_2_len := length (ptc_1 t_2). + +Hypothesis INV : seq_simrel_inv X_t. +Hypothesis INV' : seq_simrel_inv X_t'. + +Lemma simrel_step_e_t2 + (T1 : tid e = t_1) + (IND: index e >= t_1_len) + (NINIT1 : t_1 <> tid_init) + (NINIT2 : t_2 <> tid_init) + (T2NOTIN : ~ threads_set G_t t_2) + (THRDNEQ : t_1 <> t_2) + (SIMREL : seq_simrel X_s X_t t_1 t_2 mapper mapper_rev ptc_1) + (STEP : WCore.exec_inst X_t X_t' e l) : + exists mapper' mapper_rev' X_s', + << SIMREL : seq_simrel X_s' X_t' t_1 t_2 mapper' mapper_rev' ptc_1 >> /\ + << STEP : WCore.exec_inst X_s X_s' (mapper' e) l >>. +Proof using. + destruct STEP as [ADD RFC CONS]. + destruct ADD as (r & R1 & w & W1 & W2 & ADD). + set (mapper' := upd mapper e (ThreadEvent t_2 (index e - t_1_len))). + set (mapper_rev' := upd mapper_rev (ThreadEvent t_2 (index e - t_1_len)) e). + assert (ENOTIN : ~E_t e) by apply ADD. + assert (EMAPNOTIN : ~E_s (ThreadEvent t_2 (index e - t_1_len))). + { intros FALSE. destruct ADD. + assert (CDD : (ThreadEvent t_2 (index e - t_1_len)) = mapper' e). + { unfold mapper'. rewrite upds; vauto. } + rewrite CDD in FALSE. + apply (seq_acts SIMREL) in FALSE. + destruct FALSE as [e' [C1 C2]]. + assert (C1' : E_t e') by vauto. + apply (seq_mapto SIMREL) in C1; vauto. + { assert (TID' : tid e' = t_1). + { apply (seq_tid_2 SIMREL) in C1'; vauto. + rewrite C1; vauto. } + rewrite <- CDD in C2. rewrite C1 in C2; vauto. + assert (INDEX : index e' = index e). + { unfold t_1_len in H0. + assert (index e' >= t_1_len). + { apply (seq_index SIMREL) in C1'. + { rewrite C1'. + unfold SequentBase.t_1_len, t_1_len. + clear. lia. } + rewrite C1; vauto. } + unfold SequentBase.t_1_len in H0. + clear - H0 H IND. unfold t_1_len in *. lia. } + assert (EQE : e' = e). + { clear - INDEX TID' T1 NINIT1. + destruct e', e; basic_solver 8. } + desf. } + rewrite C2; rewrite <- CDD. + vauto. } + assert (MAPEQ : eq_dom E_t mapper' mapper). + { subst mapper'. unfolder. intros x XINE. + clear - EMAPNOTIN ENOTIN XINE. rewrite updo; vauto. + all: congruence. } + assert (MAPREVEQ : eq_dom E_s mapper_rev' mapper_rev). + { subst mapper_rev'. unfolder. intros x XINE. + clear - EMAPNOTIN ENOTIN XINE. rewrite updo; vauto. + all: congruence. } + assert (MAPER_E : mapper' ↑₁ eq e ≡₁ eq (ThreadEvent t_2 (index e - t_1_len))). + { subst mapper'. rewrite set_collect_eq. now rupd. } + assert (MAPSUB : mapper' ↑₁ E_t ≡₁ mapper ↑₁ E_t). + { clear - MAPEQ. now apply set_collect_eq_dom. } + assert (MAPREVSUB : mapper_rev' ↑₁ E_s ≡₁ mapper_rev ↑₁ E_s). + { clear - MAPREVEQ. now apply set_collect_eq_dom. } + assert (EQACTS : E_t' ≡₁ E_t ∪₁ eq e) by apply ADD. + assert (NEWE : + << NINIT : ~is_init (ThreadEvent t_2 (index e - t_1_len)) >> /\ + << NINIT' : ~is_init e >> /\ + << NOTIN : ~E_s (ThreadEvent t_2 (index e - t_1_len)) >> /\ + << TID : tid (ThreadEvent t_2 (index e - t_1_len)) = t_2 >>). + { unfold NW; splits; vauto. + intros FLS. unfold is_init in FLS. + desf. unfold tid in T1. + apply NINIT1; vauto. } + unfold NW in NEWE. destruct NEWE as (NINIT & NINIT' & NOTIN & TID). + + set (G_s' := {| + acts_set := E_s ∪₁ eq (ThreadEvent t_2 (index e - t_1_len)); + threads_set := threads_set G_s; + lab := lab_t' ∘ mapper_rev'; + rf := mapper' ↑ rf_t'; + co := mapper' ↑ co_t'; + rmw := mapper' ↑ rmw_t'; + rmw_dep := ∅₂; + ctrl := ∅₂; + data := ∅₂; + addr := ∅₂; + |}). + set (X_s' := {| + WCore.sc := WCore.sc X_s; + WCore.G := G_s'; + |}). + + exists mapper', mapper_rev', X_s'. + assert (SIMRELQ : seq_simrel X_s' X_t' t_1 t_2 mapper' mapper_rev' ptc_1). + { constructor; vauto; simpl; try basic_solver 6. + { rewrite (WCore.add_event_acts ADD). apply inj_dom_union. + { clear - SIMREL MAPEQ. + unfolder. ins. apply (seq_inj SIMREL); ins. + now rewrite <- !MAPEQ. } + { clear. basic_solver. } + rewrite MAPER_E, MAPSUB, (seq_codom SIMREL). + unfold set_disjoint. intros x INE' INE. + assert (CC : E_t (mapper_rev' x)). + { rewrite <- INE. unfold mapper_rev'. + rewrite upds; vauto. } + destruct MAPREVSUB as [IN OUT]. + destruct IN with x. + { unfold set_collect. exists x; split; vauto. } + destruct H as [INEE MAPR]. + rewrite <- INE in CC. + unfold mapper_rev' in CC. + rewrite updo in CC; vauto. } + { intros ev INE' TIDCOND. + destruct classic with (ev = e) as [EQ | NEQ]. + { subst ev. unfold mapper'. rewrite upds; vauto. + unfold mapper' in TIDCOND. rewrite upds in TIDCOND; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_tid_1 SIMREL); vauto. + apply EQACTS in INE'. destruct INE' as [C1 | C2]; vauto. + unfold mapper' in TIDCOND. rewrite updo in TIDCOND; vauto. } + { intros ev INE' TIDCOND. destruct SIMREL. + destruct classic with (ev = e) as [EQ | NEQ]. + { subst e; vauto. } + assert (EINN : E_t ev). + { apply EQACTS in INE'. destruct INE' as [C1 | C2]; vauto. + clear - C2 NEQ. basic_solver. } + specialize seq_tid_2 with ev. + apply seq_tid_2 in EINN; vauto. + unfold mapper' in TIDCOND. rewrite updo in TIDCOND; vauto. } + { intros x COND. unfold compose. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper', mapper_rev'. + rewrite !upds; vauto. } + unfold mapper', mapper_rev'. + rewrite !updo; vauto. + { unfold compose in MAPREV. rewrite MAPREV. + { basic_solver. } + apply EQACTS in COND. + destruct COND as [C1 | C2]; vauto. } + rewrite updo; vauto. + assert (INE : E_t x). + { apply EQACTS in COND. + destruct COND as [C1 | C2]; vauto. } + intros FALSE. + assert (PROP : E_s (ThreadEvent t_2 (index e - t_1_len))). + { rewrite <- FALSE. + apply (seq_codom SIMREL); vauto. } + desf. } + { rewrite EQACTS. rewrite set_collect_union. + rewrite MAPER_E, MAPSUB, (seq_acts SIMREL); vauto. } + { rewrite set_collect_union. + rewrite MAPREVSUB. + unfold mapper_rev'. + rewrite set_collect_eq. + rewrite upds, EQACTS. + rewrite (seq_acts_rev SIMREL); vauto. } + { unfold sb. unfold G_s'; ins. + split; intros x y COND. + { destruct COND as [CD1 | CD2]. + { destruct CD1 as [x0 [[EQ1 INE1] [x1 [EXT [EQ2 INE2]]]]]; subst. + destruct INE1 as [CD1 | CD2]. + { destruct INE2 as [CD3 | CD4]. + { apply (seq_acts SIMREL) in CD1, CD3. + destruct CD1 as [x2 [IN1 MAP1]], CD3 as [x3 [IN2 MAP2]]. + unfold collect_rel. + exists x2, x3; splits. + { unfold seq. exists x2; split. + { red; split; vauto. + apply EQACTS; vauto. } + exists x3; split. + { subst. + destruct x2, x3; desf. + { rewrite !(seq_init SIMREL) in EXT; vauto. } + { assert (INIT1 : mapper (InitEvent l0) = InitEvent l0). + { rewrite (seq_init SIMREL); vauto. } + rewrite INIT1 in EXT; vauto. + exfalso. + unfold ext_sb in EXT. + desf. } + unfold ext_sb in EXT. desf. + { exfalso. + assert (REVVV : mapper_rev (mapper (ThreadEvent thread index)) = + mapper_rev (InitEvent l0)). + { rewrite Heq; vauto. } + unfold compose in MAPREV. + rewrite MAPREV in REVVV; vauto. + rewrite (seq_init_rev SIMREL) in REVVV; vauto. } + destruct EXT as [EXT1 EXT2]. + subst thread2. + destruct classic with (thread1 = t_2) as [TD2 | TN2]. + { subst thread1. + destruct SIMREL. + assert (TT1 : thread = t_1). + { apply seq_thrd in IN1; vauto. + rewrite Heq; unfold tid; vauto. } + assert (TT2 : thread0 = t_1). + { apply seq_thrd in IN2; vauto. + rewrite Heq0; unfold tid; vauto. } + assert (INDX : index < index0). + { apply seq_index in IN1. + { apply seq_index in IN2. + { rewrite Heq in IN1. + rewrite Heq0 in IN2. + unfold SequentBase.t_1_len, t_1_len in *. + clear - IN1 IN2 IND EXT2. + unfold Events.index in *. lia. } + rewrite Heq0. + unfold tid; vauto. } + rewrite Heq. + unfold tid; vauto. } + unfold ext_sb; vauto. } + assert (TRDS : thread = thread0). + { destruct SIMREL. + apply seq_mapeq in IN1, IN2. + { rewrite Heq in IN1. + rewrite Heq0 in IN2. + unfold tid in *; vauto. } + { rewrite Heq0; unfold tid; vauto. } + rewrite Heq; unfold tid; vauto. } + assert (INDX : index < index0). + { destruct SIMREL. + apply seq_mapeq in IN1, IN2. + { rewrite Heq in IN1. + rewrite Heq0 in IN2. + unfold tid in *; vauto. } + { rewrite Heq0; unfold tid; vauto. } + rewrite Heq; unfold tid; vauto. } + unfold ext_sb; vauto. } + red; split; vauto. + apply EQACTS; vauto. } + { unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + apply (seq_acts SIMREL) in CD1. + destruct CD1 as [x2 [IN1 MAP1]]. + unfold collect_rel. + exists x2, e; splits. + { unfold seq. exists x2; split. + { red; split; vauto. + apply EQACTS; vauto. } + exists e; split. + { destruct x2; desf. + { unfold ext_sb; desf. } + unfold ext_sb in EXT. + desf. + { exfalso. + assert (REVVV : mapper_rev (mapper (ThreadEvent thread index)) = + mapper_rev (InitEvent l0)). + { rewrite Heq; vauto. } + unfold compose in MAPREV. + rewrite MAPREV in REVVV; vauto. + rewrite (seq_init_rev SIMREL) in REVVV; vauto. } + destruct EXT as [EXT1 EXT2]. + assert (TT1 : thread = t_1). + { apply (seq_thrd SIMREL) in IN1; vauto. + rewrite Heq; unfold tid; vauto. } + assert (INDX : index < Events.index e). + { apply (seq_index SIMREL) in IN1. + { rewrite Heq in IN1. + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. lia. } + rewrite Heq; unfold tid; vauto. } + destruct e. + { exfalso. desf. } + unfold Events.index in *. + unfold ext_sb; vauto. } + red; split; vauto. + apply EQACTS; vauto. } + { unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + unfold mapper'. + rewrite upds; vauto. } + destruct INE2 as [C3 | C4]. + { apply (seq_acts SIMREL) in C3. + destruct C3 as [x2 [IN1 MAP1]]. + unfold collect_rel. + exists e, x2; splits. + { unfold seq. exists e; split. + { red; split; vauto. + apply EQACTS; vauto. } + exists x2; split. + { destruct x2; desf. + { rewrite (seq_init SIMREL) in EXT; vauto. } + unfold ext_sb in EXT. + desf. + destruct EXT as [EXT1 EXT2]. + assert (TT1 : thread = t_1). + { apply (seq_thrd SIMREL) in IN1; vauto. + rewrite Heq; unfold tid; vauto. } + assert (INDX : Events.index e < index). + { apply (seq_index SIMREL) in IN1. + { rewrite Heq in IN1. + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. lia. } + rewrite Heq; unfold tid; vauto. } + destruct e. + { exfalso. desf. } + unfold Events.index in *. + unfold ext_sb; vauto. } + red; split; vauto. + apply EQACTS; vauto. } + { unfold mapper'. + rewrite upds; vauto. } + unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + unfold ext_sb in EXT. + desf. lia. } + unfold po_seq in CD2. + destruct CD2 as [[TD1 INE1] [TD2 INE2]]. + assert (SWCH : WCore.G X_s' = G_s') by vauto. + rewrite SWCH in *. + unfold G_s' in INE1, INE2; ins. + destruct INE1 as [CD1 | CD2]. + { destruct INE2 as [CD3 | CD4]. + { destruct SIMREL. + apply seq_acts in CD1, CD3. + destruct CD1 as [x2 [IN1 MAP1]], CD3 as [x3 [IN2 MAP2]]. + unfold collect_rel. + exists x2, x3; splits. + { unfold seq. exists x2; split. + { red; split; vauto. + apply EQACTS; vauto. } + exists x3; split. + { subst. + destruct x2, x3; desf. + { rewrite seq_init in TD1; vauto. + unfold tid in TD1. + exfalso; apply NINIT1; vauto. } + { rewrite seq_init in NINIT2; vauto. } + assert (THRD1 : thread = t_1). + { apply seq_mapeq in IN1; vauto. + { rewrite IN1 in TD1. + unfold tid; vauto. } + rewrite TD1; unfold tid; vauto. } + assert (THRD2 : thread0 = t_1). + { apply seq_thrd in IN2; vauto. } + assert (INDX1 : index < t_1_len). + { apply NNPP. intros INDX'. + assert (INDX : index >= t_1_len) by lia. + apply seq_out_move in IN1. + { rewrite IN1 in TD1. + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. basic_solver. } + { unfold tid; vauto. } + unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + assert (INDX2 : index0 >= t_1_len). + { apply NNPP. intros INDX'. + assert (INDX : index0 < t_1_len) by lia. + apply seq_index in IN2. + { unfold Events.index in IN2. + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. lia. } + vauto. } + unfold ext_sb; split; vauto. + lia. } + red; split; vauto. + apply EQACTS; vauto. } + { unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + destruct SIMREL. + apply seq_acts in CD1. + destruct CD1 as [x2 [IN1 MAP1]]. + unfold collect_rel. + exists x2, e; splits. + { unfold seq. exists x2; split. + { red; split; vauto. + apply EQACTS; vauto. } + exists e; split. + { subst. + destruct x2, e; desf. + assert (THRD1 : thread = t_1). + { apply seq_mapeq in IN1; vauto. + { rewrite IN1 in TD1. + unfold tid; vauto. } + rewrite TD1; unfold tid; vauto. } + assert (THRD2 : thread0 = t_1). + { unfold tid in *; vauto. } + assert (INDX1 : index < t_1_len). + { apply NNPP. intros INDX'. + assert (INDX : index >= t_1_len) by lia. + apply seq_out_move in IN1. + { rewrite IN1 in TD1. + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. basic_solver. } + { unfold tid; vauto. } + unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + unfold ext_sb; split; vauto. + unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + red; split; vauto. + apply EQACTS; vauto. } + { unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + unfold mapper'. + rewrite upds; vauto. } + rewrite <- CD2 in TD1. + unfold tid in *. desf. } + destruct COND as [x0 [y0 [[x1 [[EQ1 INE1] + [y1 [COND [EQ2 INE2]]]]] [M1 M2]]]]. + subst. + apply EQACTS in INE1, INE2. + destruct INE1 as [C1 | C2], INE2 as [C3 | C4]. + { destruct x1, y0. + { desf. } + { left. unfold seq. + exists (mapper' (InitEvent l0)); split. + { red; split; vauto. + unfold mapper'. + rewrite updo; vauto. + { left. + apply (seq_acts SIMREL). + red; exists (InitEvent l0); split; vauto. } + intros FLS; subst; desf. } + exists (mapper' (ThreadEvent thread index)); split. + { unfold mapper'. + rewrite updo; vauto. + { rewrite (seq_init SIMREL); vauto. + unfold ext_sb; desf. + destruct classic with ((ThreadEvent thread index) = e) as [EQ | NEQ]. + { subst; vauto. } + rewrite updo in Heq; vauto. + assert (REVVV : mapper_rev (mapper (ThreadEvent thread index)) = + mapper_rev (InitEvent l1)). + { rewrite Heq; vauto. } + unfold compose in MAPREV. + rewrite MAPREV in REVVV; vauto. + rewrite (seq_init_rev SIMREL) in REVVV; vauto. } + intros FLS; subst; desf. } + red; split; vauto. + left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent thread index); split; vauto. + unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + { unfold ext_sb in COND; desf. } + unfold ext_sb in COND. + destruct COND as [COND1 COND2]. + subst thread0. + destruct classic with (thread = t_1) as [TD1 | TN1]. + { destruct classic with (index >= t_1_len) as [IDL | IDG']. + { left. + unfold seq. + exists (mapper' (ThreadEvent thread index)); split. + { red; split; vauto. + unfold mapper'. + rewrite updo; vauto. + { left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent t_1 index); split; vauto. } + intros FLS; subst; desf. } + exists (mapper' (ThreadEvent thread index0)); split. + { unfold mapper'. + rewrite !updo; vauto. + { destruct SIMREL. + apply seq_out_move in C1, C3. + all : try unfold tid; vauto. + { rewrite C1, C3. + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. + unfold ext_sb; desf. + desf. lia. } + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. + lia. } + { intros FLS; subst; desf. } + intros FLS; subst; desf. } + red; split; vauto. + left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent t_1 index0); split; vauto. + unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + assert (IDG : index < t_1_len) by lia. + destruct classic with (index0 >= t_1_len) as [IDL2 | IDG2']. + { right. + unfold po_seq. split. + { split. + { unfold mapper'. + rewrite updo; vauto. + { destruct SIMREL. + apply seq_out_snd in C1. + { rewrite C1. + unfold tid; vauto. } + { unfold tid; vauto. } + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. + lia. } + intros FLS; subst; desf. } + arewrite (WCore.G X_s' = G_s'). + unfold G_s'; ins. + left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent t_1 index); split; vauto. + unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + split. + { unfold mapper'. + rewrite updo; vauto. + { destruct SIMREL. + apply seq_out_move in C3. + { rewrite C3. + unfold tid; vauto. } + { unfold tid; vauto. } + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. + lia. } + intros FLS; subst; desf. } + arewrite (WCore.G X_s' = G_s'). + unfold G_s'; ins. + left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent thread index0); split; vauto. + unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + assert (IDG2 : index0 < t_1_len) by lia. + left. + unfold seq. + exists (mapper' (ThreadEvent thread index)); split. + { red; split; vauto. + unfold mapper'. + rewrite updo; vauto. + { left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent t_1 index); split; vauto. } + intros FLS; subst; desf. } + exists (mapper' (ThreadEvent thread index0)); split. + { unfold mapper'. + rewrite !updo; vauto. + { destruct SIMREL. + apply seq_out_snd in C1, C3. + all : try unfold tid; vauto. + rewrite C1, C3. + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. + unfold ext_sb; desf. } + all : intros FLS; subst; desf. } + red; split; vauto. + left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent t_1 index0); split; vauto. + unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + left. + unfold seq. + exists (mapper' (ThreadEvent thread index)); split. + { red; split; vauto. + unfold mapper'. + rewrite updo; vauto. + { left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent thread index); split; vauto. } + intros FLS; subst; desf. } + exists (mapper' (ThreadEvent thread index0)); split. + { unfold mapper'. + rewrite !updo; vauto. + { destruct SIMREL. + apply seq_out in C1, C3. + all : try unfold tid; vauto. + rewrite C1, C3. + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. + unfold ext_sb; desf. } + all : intros FLS; subst; desf. } + red; split; vauto. + left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent thread index0); split; vauto. + unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + { subst y0. + destruct x1. + { left. unfold seq. + exists (mapper' (InitEvent l0)); split. + { red; split; vauto. + unfold mapper'. + rewrite updo; vauto. + { left. + apply (seq_acts SIMREL). + red; exists (InitEvent l0); split; vauto. } + intros FLS; subst; desf. } + exists (mapper' e); split. + { unfold mapper'. + rewrite updo; vauto. + { rewrite (seq_init SIMREL); vauto. + unfold ext_sb; desf. + rewrite upds in Heq; vauto. } + intros FLS; subst; desf. } + red; split; vauto. + right. + unfold mapper'. + rewrite upds; vauto. } + assert (TRD1 : thread = t_1). + { destruct e. + { desf. } + unfold ext_sb in COND; desf. } + subst thread. + destruct classic with (index < t_1_len) as [INDX | INDX']. + { right. + unfold po_seq. split. + { split. + { unfold mapper'. + rewrite updo; vauto. + { destruct SIMREL. + apply seq_out_snd in C1. + { rewrite C1. + unfold tid; vauto. } + { unfold tid; vauto. } + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. + lia. } + intros FLS; subst; desf. } + arewrite (WCore.G X_s' = G_s'). + unfold G_s'; ins. + left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent t_1 index); split; vauto. + unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + split. + { unfold mapper'. + rewrite upds; vauto. } + arewrite (WCore.G X_s' = G_s'). + unfold G_s'; ins. + right. + unfold mapper'. + rewrite upds; vauto. } + assert (INDX : index >= t_1_len) by lia. + left. + unfold seq. + exists (mapper' (ThreadEvent t_1 index)); split. + { red; split; vauto. + unfold mapper'. + rewrite updo; vauto. + { left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent t_1 index); split; vauto. } + intros FLS; subst; desf. } + exists (mapper' e); split. + { unfold mapper'. + rewrite updo; vauto. + { rewrite upds. + destruct SIMREL. + apply seq_out_move in C1. + { rewrite C1. + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. + unfold ext_sb; desf. + split; vauto. + unfold ext_sb in COND. desf. lia. } + { unfold tid; vauto. } + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. + lia. } + intros FLS; subst; desf. } + red; split; vauto. + right. + unfold mapper'. + rewrite upds; vauto. } + { subst x1. + unfold ext_sb in COND; desf. + destruct COND as [COND1 COND2]. + left. + unfold seq. + exists (mapper' (ThreadEvent thread index)); split. + { red; split; vauto. + unfold mapper'. + rewrite upds; vauto. } + exists (mapper' (ThreadEvent thread0 index0)); split. + { unfold mapper'. + rewrite upds. rewrite updo. + { destruct SIMREL. + apply seq_out_move in C3. + { rewrite C3. + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. + unfold ext_sb; desf. + split; vauto. + unfold ext_sb in COND2. desf. lia. } + { unfold tid; vauto. } + unfold SequentBase.t_1_len, t_1_len in *. + unfold Events.index in *. + lia. } + intros FLS; subst; desf. } + red; split; vauto. + left. + apply (seq_acts SIMREL). + red; exists (ThreadEvent thread0 index0); split; vauto. + unfold mapper'. + rewrite updo; vauto. + intros FLS; subst; desf. } + subst x1 y0; unfold ext_sb in COND. + exfalso. desf. + lia. } + { rewrite (seq_threads SIMREL). + destruct ADD. rewrite add_event_threads; vauto. } + { unfold mapper'. intros x COND. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. clear - T1 COND NINIT1. + unfold tid in T1. unfold is_init in COND. + desf. basic_solver 8. } + rewrite updo; vauto. + apply (seq_init SIMREL); vauto. } + { unfold mapper_rev'. intros x COND. + destruct classic with (x = (ThreadEvent t_2 (index e - t_1_len))) as [EQ | NEQ]. + { subst x. clear - T1 COND NINIT1. + unfold tid in T1. unfold is_init in COND. + desf. } + rewrite updo; vauto. + apply (seq_init_rev SIMREL); vauto. } + { rewrite EQACTS. rewrite set_collect_union. + rewrite MAPER_E, MAPSUB, (seq_acts SIMREL); vauto. } + { intros e' INE NTID2. + apply EQACTS in INE. + destruct INE as [C1 | C2]. + { destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper'. rewrite upds; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_mapeq SIMREL) in C1; vauto. + unfold mapper' in NTID2. rewrite updo in NTID2; vauto. } + subst e'. unfold mapper'. rewrite upds; vauto. + unfold mapper' in NTID2. rewrite upds in NTID2; vauto. } + { intros x MAP TIDS. + destruct classic with (x = (ThreadEvent t_2 (index e - t_1_len))) as [EQ | NEQ]. + { subst x. unfold mapper_rev'. rewrite upds; vauto. } + destruct MAP as [INE | MAP]. + { unfold mapper_rev'. + rewrite updo; vauto. + apply (seq_mapeq_rev SIMREL) in INE; vauto. } + unfold mapper_rev'. + rewrite updo; vauto. } + { intros e' INE TID2. + apply EQACTS in INE. + destruct INE as [C1 | C2]. + { destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper'. rewrite upds; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_mapto SIMREL) in C1; vauto. + unfold mapper' in TID2. rewrite updo in TID2; vauto. } + subst e'. unfold mapper'. rewrite upds; vauto. } + { intros e' INE TID2. + apply EQACTS in INE. + destruct INE as [C1 | C2]. + { destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper'. rewrite upds; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_index SIMREL) in C1; vauto. + unfold mapper' in TID2. rewrite updo in TID2; vauto. } + subst e'. unfold mapper'. rewrite upds; vauto. + simpl. unfold SequentBase.t_1_len. + unfold t_1_len in *. clear - IND. lia. } + { intros x INE TID2. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x; vauto. } + unfold mapper' in TID2. + rewrite updo in TID2. + { destruct SIMREL. + apply seq_thrd in TID2. + { rewrite TID2; vauto. } + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + vauto. } + { intros x INE TID2. + unfold mapper_rev'. + destruct classic with (x = (ThreadEvent t_2 (index e - t_1_len))) as [EQ | NEQ]. + { subst x. rewrite upds. + destruct e. + { desf. } + unfold tid in T1. rewrite T1. + unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + assert (INDEQ : index = index - length (ptc_1 t_1) + length (ptc_1 t_1)). + { lia. } + rewrite INDEQ at 1; vauto. } + rewrite updo. + { apply (seq_maprev SIMREL); vauto. + destruct INE; vauto. + exfalso. apply NEQ; vauto. } + vauto. } + { intros x INE TID2. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper'. + rewrite upds. exfalso. desf. } + unfold mapper'. + rewrite updo; vauto. + destruct SIMREL. + rewrite seq_out; vauto. + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + { intros x INE TIDS IDXS. + destruct classic with (x = e) as [EQ | NEQ]. + { unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + subst x. exfalso. + lia. } + unfold mapper'. + rewrite updo; vauto. + apply (seq_out_snd SIMREL); vauto. + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + { intros x INE TIDS IDXS. + destruct classic with (x = e) as [EQ | NEQ]. + { unfold mapper'. subst x. + rewrite upds. + unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + vauto. } + unfold mapper'. + rewrite updo; vauto. + apply (seq_out_move SIMREL); vauto. + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + { intros e' NINE. + destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. exfalso. apply NINE. + apply EQACTS; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_rest SIMREL); vauto. + intros INN. apply NINE. + apply EQACTS; vauto. } + intros e' NINE. + destruct classic with (e' = (ThreadEvent t_2 (index e - t_1_len))) as [EQ | NEQ]. + { subst e'. exfalso. + apply NINE; vauto. } + unfold mapper_rev'. rewrite updo; vauto. + apply (seq_rest_rev SIMREL); vauto. + intros FALSE. apply NINE; vauto. } + splits; vauto. + constructor. + { unfold WCore.add_event. + exists (option_map mapper' r), (mapper' ↑₁ R1), + (option_map mapper' w), + (mapper' ↑₁ W1), + (mapper' ↑₁ W2). + apply add_event_to_wf; simpl; vauto. + { apply sico_init_acts_s with + (X_t := X_t) (mapper := mapper). + { constructor. all : try apply SIMREL. + rewrite (seq_lab SIMREL); vauto. } + destruct ADD. apply add_event_init. } + { unfold mapper'. rewrite upds; vauto. } + { unfold mapper'. rewrite upds; vauto. } + { unfold mapper'. rewrite upds. + clear - NINIT2. unfold tid; vauto. } + { unfold mapper'. rewrite upds. basic_solver. } + { destruct ADD. destruct SIMRELQ. + unfold mapper', mapper_rev'. + apply functional_extensionality; ins. + destruct classic with (x = (ThreadEvent t_2 (index e - t_1_len))) as [EQ | NEQ]. + { subst x. rewrite !upds. vauto. + rewrite add_event_lab. + unfold compose. rewrite upds. + rewrite upds; vauto. } + rewrite upds; vauto. + rewrite add_event_lab. + unfold compose. + destruct SIMREL. + assert (SWITCH : upd mapper_rev (ThreadEvent t_2 (index e - t_1_len)) e x + = mapper_rev x). + { rewrite updo; vauto. } + rewrite SWITCH. + assert (SWITCH2 : upd lab_s (ThreadEvent t_2 (index e - t_1_len)) l x + = lab_s x). + { rewrite updo; vauto. } + rewrite SWITCH2. + destruct classic with (E_s x) as [INNE | NINNE]. + { assert (INNE' : E_s x) by vauto. + apply seq_lab_rev0 in INNE'. + rewrite updo; vauto. + intros FLS. + assert (FF : E_t e). + { apply seq_acts_rev0. + red; vauto. } + desf. } + assert (NINNE' : ~ E_s x) by vauto. + apply seq_rlab0 in NINNE. + rewrite NINNE. + admit. (* labels out of act_set are irrelevant *) } + { destruct ADD. rewrite add_event_rf. + rewrite !collect_rel_union. + arewrite (mapper' ↑ rf_t ≡ mapper ↑ rf_t). + { apply collect_rel_eq_dom' with (s := E_t); ins. + apply (wf_rfE); vauto. } + rewrite (seq_rf SIMREL). + arewrite (mapper' ↑ WCore.rf_delta_R e w + ≡ WCore.rf_delta_R (mapper' e) + (option_map mapper' w)). + { unfold WCore.rf_delta_R. + rewrite collect_rel_cross. + apply cross_more. + { clear. unfold option_map. basic_solver. } + clear. unfold option_map. basic_solver. } + arewrite (mapper' ↑ WCore.rf_delta_W e R1 + ≡ WCore.rf_delta_W (mapper' e) (mapper' ↑₁ R1)). + { unfold WCore.rf_delta_W. + rewrite collect_rel_cross. + apply cross_more. + { clear. unfold option_map. basic_solver. } + clear. unfold option_map. basic_solver. } + vauto. } + { destruct ADD. rewrite add_event_co. + rewrite !collect_rel_union. + arewrite (mapper' ↑ co_t ≡ mapper ↑ co_t). + { apply collect_rel_eq_dom' with (s := E_t); ins. + apply (wf_coE); vauto. } + rewrite (seq_co SIMREL). + arewrite (mapper' ↑ WCore.co_delta e W1 W2 + ≡ WCore.co_delta (mapper' e) (mapper' ↑₁ W1) + (mapper' ↑₁ W2)). + { unfold WCore.co_delta. rewrite collect_rel_union. + apply union_more. + { rewrite collect_rel_cross. + apply cross_more; vauto. + clear. basic_solver. } + rewrite collect_rel_cross. + apply cross_more; vauto. + clear. basic_solver. } + vauto. } + { rewrite <- mapped_rmw_delta, (WCore.add_event_rmw ADD), + collect_rel_union. + arewrite (mapper' ↑ rmw_t ≡ mapper ↑ rmw_t). + { apply collect_rel_eq_dom' with (s := E_t); ins. + apply (wf_rmwE); vauto. } + now rewrite (seq_rmw SIMREL). } + { rewrite (seq_data SIMREL); vauto. } + { rewrite (seq_addr SIMREL); vauto. } + { rewrite (seq_ctrl SIMREL); vauto. } + { rewrite (seq_rmw_dep SIMREL); vauto. } + { admit. (* all the events except t_2 are stay on their + places, t_2 moves in order and delta-edges + are added respectively as well *) } + arewrite (G_s' = WCore.G X_s'). + apply wf_transition with (X_t := X_t') + (t_1 := t_1) (t_2 := t_2) + (mapper := mapper') (mapper_rev := mapper_rev') + (ptc_1 := ptc_1); vauto. } + { unfold rf_complete. + rewrite (seq_acts SIMRELQ), (seq_rf SIMRELQ). + unfold rf_complete in RFC. rewrite EQACTS. + rewrite !set_collect_union, MAPER_E, MAPSUB. + rewrite set_inter_union_l. + rewrite set_subset_union_l; split. + { unfold rf_complete in RFC. + rewrite <- set_collect_codom, <- RFC. + unfolder. intros x ((x' & INE & XEQ) & ISR). + exists x'. splits; try basic_solver. + { apply EQACTS; vauto. } + subst x. unfold is_r in *. + assert (CHNG : WCore.G X_s' = G_s') by vauto. + rewrite CHNG in ISR. unfold G_s' in ISR; ins. + unfold compose in ISR. + assert (NEQ : x' <> e). + { intros FALSE. subst x'. basic_solver 8. } + assert (NEQ' : mapper x' <> (ThreadEvent t_2 (index e - t_1_len))). + { intros FALSE. destruct NOTIN. + rewrite <- FALSE. apply (seq_codom SIMREL); vauto. } + assert (EQQ : mapper_rev' (mapper x') = x'). + { unfold eq_dom in MAPREV. specialize MAPREV with x'. + apply MAPREV in INE. unfold compose in INE. + unfold mapper_rev'. rewrite updo; vauto. } + rewrite EQQ in ISR; vauto. } + rewrite <- set_collect_codom. rewrite <- RFC. + intros x (EQ & RD). subst x. + unfold set_collect. exists e. splits; vauto. + { split. + { apply EQACTS. basic_solver. } + assert (FEQ : WCore.G X_s' = G_s') by vauto. + rewrite FEQ in RD. unfold G_s' in RD. + simpl in RD. clear - RD. unfold compose in RD. + unfold is_r in RD. unfold mapper_rev' in RD. + rewrite upds in RD; vauto. } + unfold mapper'. rewrite upds. vauto. } + apply XmmCons.monoton_cons with (G_t := G_t') + (m := mapper'); vauto; try apply SIMRELQ. + { unfold rpo. unfold rpo_imm. + arewrite (WCore.G X_s' = G_s'). + destruct SIMRELQ. + assert (RESTR : ⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ sb_t' ⨾ ⦗F G_t' ∩₁ Acq G_t'⦘ ∪ ⦗Acq G_t'⦘ ⨾ sb_t' ∪ sb_t' ⨾ ⦗Rel G_t'⦘ + ∪ ⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ sb_t' ⨾ ⦗W_t' ∩₁ Rlx G_t'⦘ ≡ restr_rel E_t' ( + ⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ sb_t' ⨾ ⦗F G_t' ∩₁ Acq G_t'⦘ ∪ ⦗Acq G_t'⦘ ⨾ sb_t' ∪ sb_t' ⨾ ⦗Rel G_t'⦘ + ∪ ⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ sb_t' ⨾ ⦗W_t' ∩₁ Rlx G_t'⦘)). + { split. + { rewrite !restr_union. + repeat apply union_mori. + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] [x1 [COND [EQ2 CD2]]]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] COND]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x1 [COND [EQ2 CD2]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] [x1 [COND [EQ2 CD2]]]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + rewrite inclusion_restr; vauto. } + rewrite RESTR. + rewrite collect_rel_ct_inj. + { assert (MAPREVCOMP : eq_dom (acts_set G_s') (mapper' ∘ mapper_rev') id). + { intros x COND. + unfold G_s' in COND; ins. + destruct COND as [COND1 | COND2]. + { destruct SIMREL. + apply seq_acts0 in COND1. + destruct COND1 as [x0 [COND1 EQ1]]; subst. + unfold compose. + unfold mapper', mapper_rev'. + rewrite !updo; vauto. + { unfold compose in MAPREV. + rewrite MAPREV; vauto. } + { intros FLS. + assert (FF : E_s (ThreadEvent t_2 (index e - t_1_len))). + { apply seq_acts0. + red; vauto. } + desf. } + intros FLS. + rewrite updo in FLS. + { unfold compose in MAPREV. + rewrite MAPREV in FLS; vauto. } + intros FLSS. + assert (FF : E_s (ThreadEvent t_2 (index e - t_1_len))). + { apply seq_acts0. + red; vauto. } + desf. } + unfold compose. + unfold mapper', mapper_rev'. + destruct classic with (x = (ThreadEvent t_2 (index e - t_1_len))) as [EQ1 | NEQ1]. + { subst x. rewrite !upds; vauto. } + rewrite !updo; vauto. } + assert (SBIN : sb G_s' ⊆ mapper' ↑ sb_t'). + { rewrite <- seq_sb; vauto. } + apply clos_trans_mori. + rewrite <- RESTR. + rewrite !collect_rel_union. + repeat apply union_mori. + { rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + arewrite (⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (F G_t' ∩₁ Acq G_t')⦘ ≡ + ⦗R_t' ∩₁ Rlx G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (F G_t' ∩₁ Acq G_t')⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [[ISR ISRLX] INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rlx, mod in ISRLX. + rewrite seq_lab_rev in ISRLX; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_r. unfold compose in ISRLX; vauto. } + { unfold is_rlx. unfold compose in ISRLX; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE [ISF ISA]]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_acq, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + { unfold is_r. unfold compose in ISA; vauto. } + unfold is_rlx. unfold compose in ISA; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + { rewrite wf_sbE. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + arewrite (⦗Acq G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t'⦘ ≡ + ⦗Acq G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t'⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [ISA INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_acq, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_acq. unfold compose in ISA; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ INE]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + { rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ INE]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE ISR]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rel, mod in ISR. + rewrite seq_lab_rev in ISR; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + unfold is_rel. unfold compose in ISR; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + arewrite (⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (W_t' ∩₁ Rlx G_t')⦘ ≡ + ⦗F G_t' ∩₁ Rel G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (W_t' ∩₁ Rlx G_t')⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [[ISF ISREL] INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rel, mod in ISREL. + rewrite seq_lab_rev in ISREL; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_r. unfold compose in ISREL; vauto. } + { unfold is_rlx. unfold compose in ISREL; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE [ISF ISA]]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rlx, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + { unfold is_r. unfold compose in ISA; vauto. } + unfold is_rlx. unfold compose in ISA; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + vauto. } + { rewrite <- (seq_lab SIMRELQ); vauto. } + { assert (SBEQ : sb G_s' ≡ mapper' ↑ sb_t' \ po_seq X_s' t_1 t_2). + { rewrite <- (seq_sb SIMRELQ). + rewrite minus_union_l. + rewrite minusK. split; [| basic_solver]. + intros x y COND. + left. split; vauto. + intros FLS. + unfold po_seq in FLS. + destruct FLS as [[TID1 INE1] [TID2 INE2]]. + unfold sb in COND. unfold ext_sb in COND. + clear - COND TID1 TID2 NINIT1 NINIT2 THRDNEQ. + destruct COND as [x0 [[EQQ1 INEE1] [x1 [COND2 [EQQ2 INEE2]]]]]. + subst. desf; basic_solver 42. } + arewrite (WCore.G X_s' = G_s'). + rewrite SBEQ. + intros x y COND. + destruct COND as [[CDMAP POSEQ] COND2]. + destruct CDMAP as [x0 [x1 [CND [M1 M2]]]]. + unfold collect_rel. + exists x0, x1; split; vauto. + split; vauto. + unfold same_loc in *. + destruct SIMRELQ. + unfold loc. rewrite !seq_lab. + { unfold compose; vauto. } + all : apply wf_sbE in CND. + all : destruct CND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; vauto. } + { apply INV'. } + apply wf_transition with (X_t := X_t') + (t_1 := t_1) (t_2 := t_2) + (mapper := mapper') (mapper_rev := mapper_rev') + (ptc_1 := ptc_1); vauto. +Admitted. + +End SimrelStep. diff --git a/src/sequentialization/SequentExec3.v b/src/sequentialization/SequentExec3.v new file mode 100644 index 00000000..97458f26 --- /dev/null +++ b/src/sequentialization/SequentExec3.v @@ -0,0 +1,1459 @@ +Require Import AuxDef. +Require Import Core. +Require Import AuxRel AuxRel2. +Require Import Srf Rhb. +Require Import SimrelCommon. +Require Import StepOps. +Require Import AuxInj. +Require Import xmm_s_hb. +Require Import Lia. +From xmm Require Import Reordering. +From xmm Require Import ThreadTrace. +From xmm Require Import Programs. +From xmm Require Import SequentBase. +From xmm Require Import SequentWf. +From xmm Require Import ConsistencyMonotonicity. + +From hahn Require Import Hahn. +From hahnExt Require Import HahnExt. +From imm Require Import Events Execution Execution_eco. +Require Import Setoid Morphisms Program.Basics. + +Open Scope program_scope. + +Set Implicit Arguments. + +Section SimrelStep. + +Variable X_t X_t' X_s : WCore.t. +Variable t_1 t_2 : thread_id. +Variable mapper : actid -> actid. +Variable mapper_rev : actid -> actid. + +Variable e : actid. +Variable l : label. + +Variable thrdle : relation thread_id. + +Variable ptc_1 ptc_2 : program_trace. + +Notation "'G_t'" := (WCore.G X_t). +Notation "'G_t''" := (WCore.G X_t'). +Notation "'G_s'" := (WCore.G X_s). + +Notation "'R' G" := (fun e => is_true (is_r (lab G) e)) (at level 1). +Notation "'F' G" := (fun e => is_true (is_f (lab G) e)) (at level 1). +Notation "'W' G" := (fun e => is_true (is_w (lab G) e)) (at level 1). +Notation "'Acq' G" := (fun e => is_true (is_acq (lab G) e)) (at level 1). +Notation "'Rlx' G" := (fun e => is_true (is_rlx (lab G) e)) (at level 1). +Notation "'Rel' G" := (fun e => is_true (is_rel (lab G) e)) (at level 1). + +Notation "'lab_t'" := (lab G_t). +Notation "'val_t'" := (val lab_t). +Notation "'loc_t'" := (loc lab_t). +Notation "'same_loc_t'" := (same_loc lab_t). +Notation "'E_t'" := (acts_set G_t). +Notation "'sb_t'" := (sb G_t). +Notation "'rf_t'" := (rf G_t). +Notation "'co_t'" := (co G_t). +Notation "'rmw_t'" := (rmw G_t). +Notation "'rpo_t'" := (rpo G_t). +Notation "'rmw_dep_t'" := (rmw_dep G_t). +Notation "'data_t'" := (data G_t). +Notation "'ctrl_t'" := (ctrl G_t). +Notation "'addr_t'" := (addr G_t). +Notation "'W_t'" := (fun x => is_true (is_w lab_t x)). +Notation "'R_t'" := (fun x => is_true (is_r lab_t x)). +Notation "'Loc_t_' l" := (fun e => loc_t e = l) (at level 1). + +Notation "'lab_t''" := (lab G_t'). +Notation "'val_t''" := (val lab_t'). +Notation "'loc_t''" := (loc lab_t'). +Notation "'same_loc_t''" := (same_loc lab_t'). +Notation "'E_t''" := (acts_set G_t'). +Notation "'sb_t''" := (sb G_t'). +Notation "'rf_t''" := (rf G_t'). +Notation "'co_t''" := (co G_t'). +Notation "'rmw_t''" := (rmw G_t'). +Notation "'rpo_t''" := (rpo G_t'). +Notation "'rmw_dep_t''" := (rmw_dep G_t'). +Notation "'data_t''" := (data G_t'). +Notation "'ctrl_t''" := (ctrl G_t'). +Notation "'addr_t''" := (addr G_t'). +Notation "'W_t''" := (fun x => is_true (is_w lab_t' x)). +Notation "'R_t''" := (fun x => is_true (is_r lab_t' x)). +Notation "'Loc_t_'' l" := (fun e => loc_t' e = l) (at level 1). + +Notation "'lab_s'" := (lab G_s). +Notation "'val_s'" := (val lab_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'same_loc_s'" := (same_loc lab_s). +Notation "'E_s'" := (acts_set G_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'sb_s'" := (sb G_s). +Notation "'rf_s'" := (rf G_s). +Notation "'co_s'" := (co G_s). +Notation "'rmw_s'" := (rmw G_s). +Notation "'rpo_s'" := (rpo G_s). +Notation "'rmw_dep_s'" := (rmw_dep G_s). +Notation "'data_s'" := (data G_s). +Notation "'ctrl_s'" := (ctrl G_s). +Notation "'addr_s'" := (addr G_s). +Notation "'W_s'" := (fun x => is_true (is_w lab_s x)). +Notation "'R_s'" := (fun x => is_true (is_r lab_s x)). +Notation "'F_s'" := (F G_s). + +Notation "'Tid_' t" := (fun e => tid e = t) (at level 1). + +Hypothesis MAPREV : eq_dom E_t (mapper_rev ∘ mapper) id. +Hypothesis MAPREVR : eq_dom E_s (mapper ∘ mapper_rev) id. +Hypothesis PROGSEQ : program_trace_sequented ptc_1 ptc_2 t_1 t_2. +Hypothesis WFT : Wf G_t. + +Definition t_12_len := length (ptc_2 t_1). +Definition t_1_len := length (ptc_1 t_1). +Definition t_2_len := length (ptc_1 t_2). + +Hypothesis INV : seq_simrel_inv X_t. +Hypothesis INV' : seq_simrel_inv X_t'. + +Lemma simrel_step_e_else + (T1 : tid e <> t_1) + (NINIT1 : t_1 <> tid_init) + (NINIT2 : t_2 <> tid_init) + (T2NOTIN : ~ threads_set G_t t_2) + (THRDNEQ : t_1 <> t_2) + (SIMREL : seq_simrel X_s X_t t_1 t_2 mapper mapper_rev ptc_1 ) + (STEP : WCore.exec_inst X_t X_t' e l) : + exists mapper' mapper_rev' X_s', + << SIMREL : seq_simrel X_s' X_t' t_1 t_2 mapper' mapper_rev' ptc_1 >> /\ + << STEP : WCore.exec_inst X_s X_s' (mapper' e) l >>. +Proof using. + destruct STEP as [ADD RFC CONS]. + destruct ADD as (r & R1 & w & W1 & W2 & ADD). + set (mapper' := upd mapper e e). + set (mapper_rev' := upd mapper_rev e e). + assert (ENOTIN : ~E_t e) by apply ADD. + assert (MAPEQ : eq_dom E_t mapper' mapper). + { subst mapper'. unfolder. intros x XINE. + clear - ENOTIN XINE. rewrite updo. + all: congruence. } + assert (MAPER_E : mapper' ↑₁ eq e ≡₁ eq e). + { subst mapper'. rewrite set_collect_eq. now rupd. } + assert (MAPSUB : mapper' ↑₁ E_t ≡₁ mapper ↑₁ E_t). + { clear - MAPEQ. now apply set_collect_eq_dom. } + assert (EQACTS : E_t' ≡₁ E_t ∪₁ eq e) by apply ADD. + assert (MAPREVDOM : E_t ≡₁ mapper_rev ↑₁ E_s). + { rewrite (seq_acts SIMREL). split. + { unfolder. intros x XINE. + exists (mapper x). splits; vauto. + apply MAPREV; vauto. } + unfolder. intros x (y & XINE & YEQ). + destruct XINE as (x0 & (INE & MAPPED)). + rewrite <- MAPPED in YEQ. rewrite <- YEQ. + assert (INE' : E_t x0) by vauto. + apply MAPREV in INE. clear - INE INE'. + unfold compose in INE. rewrite INE. + basic_solver. } + assert (MEPERREV_E : mapper_rev' ↑₁ eq e ≡₁ eq e). + { subst mapper_rev'. rewrite set_collect_eq. now rupd. } + assert (NEWE : + << NINIT : ~is_init e >> /\ + << NOTIN : ~E_s e >> /\ + << TID : tid e <> t_1 >>). + { unfold NW; splits; vauto. + { intro FALSO. unfold is_init in FALSO. + destruct ADD; vauto. } + intro FALSO. destruct ADD. + assert (CDD : e = mapper' e). + { unfold mapper'. rewrite upds; vauto. } + rewrite CDD in FALSO. + apply (seq_acts SIMREL) in FALSO. + destruct FALSO as [e' [C1 C2]]. + assert (C1' : E_t e') by vauto. + apply (seq_mapeq SIMREL) in C1; vauto. + { assert (EQQ : e' = e). + { rewrite CDD. rewrite <- C2. vauto. } + subst e'; desf. } + rewrite C2; rewrite <- CDD. + symmetry in add_event_threads. + assert (T2NOTIN' : ~ threads_set G_t' t_2). + { intros FALSE. apply add_event_threads in FALSE; vauto. } + assert (INEN : E_t' e). + { apply EQACTS. basic_solver. } + intros FALSE; desf. } + unfold NW in NEWE. destruct NEWE as (NINIT & NOTIN & TID). + + set (G_s' := {| + acts_set := mapper' ↑₁ E_t'; + threads_set := threads_set G_s; + lab := lab_t' ∘ mapper_rev'; + rf := mapper' ↑ rf_t'; + co := mapper' ↑ co_t'; + rmw := mapper' ↑ rmw_t'; + rmw_dep := ∅₂; + ctrl := ∅₂; + data := ∅₂; + addr := ∅₂; + |}). + set (X_s' := {| + WCore.sc := WCore.sc X_s; + WCore.G := G_s'; + |}). + + exists mapper', mapper_rev', X_s'. + assert (SIMRELQ : seq_simrel X_s' X_t' t_1 t_2 mapper' mapper_rev' ptc_1). + { constructor; vauto; simpl; try basic_solver 6. + { rewrite (WCore.add_event_acts ADD). apply inj_dom_union. + { clear - SIMREL MAPEQ. + unfolder. ins. apply (seq_inj SIMREL); ins. + now rewrite <- !MAPEQ. } + { clear. basic_solver. } + rewrite MAPER_E, MAPSUB, (seq_codom SIMREL). + clear - NOTIN. basic_solver. } + { intros ev INE' TIDCOND. + destruct classic with (ev = e) as [EQ | NEQ]. + { subst ev. unfold mapper'. rewrite upds; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_tid_1 SIMREL); vauto. + apply EQACTS in INE'. destruct INE' as [C1 | C2]; vauto. + unfold mapper' in TIDCOND. rewrite updo in TIDCOND; vauto. } + { intros ev INE' TIDCOND. + destruct classic with (ev = e) as [EQ | NEQ]. + { unfold mapper' in TIDCOND. + rewrite EQ in TIDCOND. + rewrite upds in TIDCOND. + subst ev. apply EQACTS in INE'. + destruct INE' as [C1 | C2]. + { desf. } + assert (INEN : E_t' e). + { apply EQACTS. basic_solver. } + exfalso. + destruct ADD. symmetry in add_event_threads. + assert (T2NOTIN' : ~ threads_set G_t' t_2). + { intros FALSE. apply add_event_threads in FALSE; vauto. } + desf. } + destruct SIMREL. + assert (NINE : E_t ev). + { apply EQACTS in INE'. destruct INE' as [C1 | C2]; vauto. } + specialize seq_tid_2 with ev. + apply seq_tid_2 in NINE; vauto. + unfold mapper'. rewrite updo; vauto. } + { intros x COND. unfold compose. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper', mapper_rev'. + rewrite !upds; vauto. } + unfold mapper', mapper_rev'. + rewrite !updo; vauto. + { unfold compose in MAPREV. rewrite MAPREV. + { basic_solver. } + apply EQACTS in COND. + destruct COND as [C1 | C2]; vauto. } + rewrite updo; vauto. + assert (INE : E_t x). + { apply EQACTS in COND. + destruct COND as [C1 | C2]; vauto. } + intros FALSE. + assert (PROP : E_s e). + { rewrite <- FALSE. + apply (seq_codom SIMREL); vauto. } + desf. } + { rewrite EQACTS. + rewrite set_collect_union. + rewrite set_collect_union. + apply set_union_more. + { split. + { intros x COND. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper'. + desf. } + unfold set_collect. + exists (mapper' x). splits; vauto. + unfold mapper'. + rewrite updo; vauto. + unfold mapper_rev'. + rewrite updo; vauto. + { apply MAPREV; vauto. } + intros FALSE. + assert (INE : E_s e). + { destruct SIMREL. + apply seq_acts. + red; vauto. } + desf. } + intros x COND. + destruct COND as [x0 [[x1 [INE MAP1]] MAP2]]. + apply MAPREVDOM. + unfold set_collect. + exists x0; splits; vauto. + { destruct classic with (x1 = e) as [EQ | NEQ]. + { subst x1. unfold mapper'. + desf. } + unfold mapper'. + rewrite updo; vauto. + destruct SIMREL. + apply seq_acts. + red; vauto. } + unfold mapper'. + rewrite updo. + { unfold mapper_rev'. + rewrite updo; vauto. + intros FALSE. + assert (INES : E_s e). + { destruct SIMREL. + apply seq_acts. + red; vauto. } + desf. } + intros FALSE. desf. } + rewrite MAPER_E. + rewrite MEPERREV_E; vauto. } + { unfold sb. unfold G_s'; ins. + split; intros x y COND. + { destruct COND as [CD1 | CD2]. + { destruct CD1 as [x0 [[EQ1 [x' [INE1 M1]]] + [x1 [EXT [EQ2 [y' [INE2 M2]]]]]]]; subst. + unfold collect_rel. exists x', y'; splits; vauto. + unfold seq. exists x'; splits; vauto. + exists y'; splits; vauto. + unfold ext_sb in EXT. + destruct classic with (x' = e) as [EQ | NEQ]. + { subst. destruct e. + { clear - NINIT. desf. } + destruct classic with (thread = t_2) as [EQ | NEQ]. + { subst. apply wf_threads in INE1; [| apply INV']. + unfold tid in INE1. exfalso. + destruct ADD. desf. } + unfold mapper' in EXT. rewrite upds in EXT. + destruct y'. + { destruct SIMREL. + clear - EXT seq_init. + unfold upd in EXT. desf. + rewrite seq_init in Heq; desf. } + destruct classic with (thread0 = t_2) as [EQ' | NEQ']. + { subst. destruct ADD. + exfalso. apply T2NOTIN. + apply add_event_threads; vauto. + apply wf_threads with (G := G_t') + (e := (ThreadEvent t_2 index0)); vauto. + apply INV'. } + desf. unfold upd in Heq. desf. + assert (MIND : index0 = index1). + { rewrite (seq_mapeq SIMREL) in Heq; vauto. + { apply EQACTS in INE2. + clear - INE2 n. + destruct INE2 as [C1 | C2]; vauto. } + intros FALSE. + rewrite <- (seq_tid_1 SIMREL) in FALSE; vauto. + { apply EQACTS in INE2. + clear - INE2 n. + destruct INE2 as [C1 | C2]; vauto. } + rewrite Heq in NEQ. desf. } + assert (MTID : thread0 = thread1). + { rewrite (seq_mapeq SIMREL) in Heq; vauto. + { apply EQACTS in INE2. + clear - INE2 n. + destruct INE2 as [C1 | C2]; vauto. } + intros FALSE. + rewrite <- (seq_tid_1 SIMREL) in FALSE; vauto. + { apply EQACTS in INE2. + clear - INE2 n. + destruct INE2 as [C1 | C2]; vauto. } + rewrite Heq in NEQ. desf. } + basic_solver 21. } + unfold mapper' in EXT. rewrite updo in EXT; vauto. + destruct x'. + { destruct SIMREL. + clear - seq_init EXT. + unfold upd in EXT. desf. + { destruct y'. + { rewrite seq_init in Heq0; desf. } + unfold ext_sb; basic_solver. } + destruct y'. + { rewrite seq_init in Heq0; desf. } + unfold ext_sb; basic_solver. } + destruct classic with (thread = t_2) as [EQ' | NEQ']. + { subst. destruct ADD. + exfalso. apply T2NOTIN. + apply add_event_threads; vauto. + apply wf_threads with (G := G_t') + (e := (ThreadEvent t_2 index)); vauto. + apply INV'. } + destruct classic with (y' = e) as [EQY | NEQY]. + { subst. unfold mapper' in EXT. rewrite upds in EXT. + desf. + { rewrite (seq_mapeq SIMREL) in Heq; vauto. + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + intros FALSE. + rewrite <- (seq_tid_1 SIMREL) in FALSE; vauto. + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite Heq in NEQ'. + unfold tid in NEQ'. destruct SIMREL. + assert (HLP : mapper_rev (InitEvent l0) = ThreadEvent thread index). + { rewrite <- Heq. apply MAPREV. + apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite seq_init_rev in HLP; vauto. } + destruct classic with (thread0 = t_2) as [EQT | NEQT]. + { subst. destruct ADD. + exfalso. apply T2NOTIN. + apply add_event_threads; vauto. + apply wf_threads with (G := G_t') + (e := (ThreadEvent t_2 index1)); vauto. + { apply INV'. } + destruct EXT; vauto. } + rewrite (seq_mapeq SIMREL) in Heq; vauto. + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite Heq. basic_solver. } + unfold mapper' in EXT. rewrite updo in EXT; vauto. + destruct y'. + { desf. + { destruct SIMREL. + clear - seq_init Heq0. + rewrite seq_init in Heq0; desf. } + destruct SIMREL. + clear - seq_init Heq0. + rewrite seq_init in Heq0; desf. } + desf. + { assert (HLP : mapper_rev (InitEvent l0) = ThreadEvent thread index). + { rewrite <- Heq. apply MAPREV. + apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite seq_init_rev in HLP; vauto. } + destruct EXT; subst. + destruct classic with (thread2 = t_2) as [EQT | NEQT]. + { subst. + assert (MIND1 : thread = t_1). + { rewrite <- (seq_tid_2 SIMREL) + with (e := (ThreadEvent thread index)); vauto. + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite Heq; vauto. } + assert (MIND2 : thread0 = t_1). + { rewrite <- (seq_tid_2 SIMREL) + with (e := (ThreadEvent thread0 index0)); vauto. + { apply EQACTS in INE2. + clear - INE2 NEQY. + destruct INE2 as [C1 | C2]; vauto. } + rewrite Heq0; vauto. } + assert (INDLESS : Events.index (ThreadEvent thread index) + < Events.index (ThreadEvent thread0 index0)). + { rewrite (seq_index SIMREL) + with (e := (ThreadEvent thread0 index0)). + { rewrite (seq_index SIMREL) + with (e := (ThreadEvent thread index)). + { rewrite Heq, Heq0. ins. + lia. } + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite Heq; vauto. } + { apply EQACTS in INE2. + clear - INE2 NEQY. + destruct INE2 as [C1 | C2]; vauto. } + rewrite Heq0; vauto. } + clear - MIND1 MIND2 INDLESS. + unfold ext_sb. basic_solver 21. } + rewrite (seq_mapeq SIMREL) in Heq; vauto. + { rewrite (seq_mapeq SIMREL) in Heq0; vauto. + { apply EQACTS in INE2. + clear - INE2 NEQY. + destruct INE2 as [C1 | C2]; vauto. } + rewrite Heq0; vauto. } + { apply EQACTS in INE1. + clear - INE1 NEQ. + destruct INE1 as [C1 | C2]; vauto. } + rewrite Heq; vauto. } + unfold po_seq in CD2. + change (WCore.G X_s') with G_s' in CD2. + unfold G_s' in CD2. ins. + destruct CD2 as [C1 C2]. + destruct C1 as [TR1 [x0 [IN1 MAP1]]]. + destruct C2 as [TR2 [y0 [IN2 MAP2]]]. + unfold collect_rel. exists x0, y0; splits. + { unfold seq. exists x0; splits. + { red; vauto. } + exists y0; splits. + { destruct SIMREL. + assert (NEQ1 : y0 <> e). + { intros FLS. subst y0. + unfold mapper' in MAP2. + rewrite upds in MAP2. + subst e. + apply wf_threads in IN2; [| apply INV']. + rewrite TR2 in IN2. + destruct ADD. desf. } + assert (EQQ : mapper' y0 = mapper y0). + { unfold mapper'. rewrite updo; vauto. } + rewrite EQQ in MAP2. + destruct classic with (x0 = e) as [EQ | NEQ]. + { unfold mapper' in MAP1. subst x0. + rewrite upds in MAP1; subst x. + desf. } + apply EQACTS in IN1. + destruct IN1 as [C1 | C2]. + { apply EQACTS in IN2. + destruct IN2 as [C3 | C4]. + { destruct x0, y0. + { unfold ext_sb. + rewrite seq_init in MAP2; vauto. } + { unfold ext_sb; vauto. } + { unfold ext_sb. + rewrite seq_init in MAP2; vauto. } + destruct classic with (index < SequentBase.t_1_len (tid + (mapper' (ThreadEvent thread index))) ptc_1) as [LT | GT]. + { assert (TEQ : thread = thread0). + { apply seq_thrd in C3. + { apply seq_mapeq in C1. + { unfold tid in C3. + subst thread0. + unfold mapper' in MAP1. + rewrite updo in MAP1. + { rewrite MAP1 in C1. + rewrite C1 in TR1. + unfold tid in TR1; vauto. } + vauto. } + unfold mapper' in MAP1. + rewrite updo in MAP1. + { rewrite MAP1; vauto. } + vauto. } + vauto. } + assert (IEQ : index < index0). + { apply seq_index in C3. + { unfold Events.index in *. + unfold mapper' in LT. + rewrite updo in LT. + { unfold mapper' in MAP1. + rewrite updo in MAP1. + { rewrite MAP1 in LT. + rewrite TR1 in LT. + lia. } + vauto. } + vauto. } + unfold mapper' in MAP2. + rewrite MAP2; vauto. } + desf; vauto. } + assert (GT' : index >= SequentBase.t_1_len (tid + (mapper' (ThreadEvent thread index))) ptc_1). + { lia. } + unfold mapper' in MAP1. + rewrite updo in MAP1. + { assert (C1' : E_t (ThreadEvent thread index)) by vauto. + apply seq_mapeq in C1. + { assert (TDD : thread = t_1). + { rewrite <- MAP1 in TR1. + rewrite C1 in TR1. + unfold tid in TR1; vauto. } + apply seq_out_move in C1'. + { exfalso. + rewrite MAP1 in C1'. + rewrite C1' in TR1. + unfold tid in TR1; vauto. } + { unfold tid; vauto. } + unfold Events.index in *. + unfold mapper' in GT'. + rewrite updo in GT'. + { rewrite MAP1 in GT'. + rewrite TR1 in GT'. + lia. } + vauto. } + rewrite MAP1; vauto. } + vauto. } + desf. } + desf. } + red; vauto. } + all : vauto. } + destruct COND as [x0 [y0 [[x1 [[EQ1 INE1] + [y1 [COND [EQ2 INE2]]]]] [M1 M2]]]]. + subst. + assert (INE1' : (acts_set G_s') (mapper' x1)). + { unfold G_s'; ins. + unfold set_collect. + exists x1; vauto. } + assert (INE2' : (acts_set G_s') (mapper' y0)). + { unfold G_s'; ins. + unfold set_collect. + exists y0; vauto. } + destruct classic with (tid (mapper' y0) = t_2) as [EQ1 | NEQ1]. + { destruct classic with (tid (mapper' x1) = t_1) as [EQ2 | NEQ2]. + { right. unfold po_seq. + split. + { split; vauto. } + split; vauto. } + left. + assert (TIDD2 : tid y0 = t_1). + { destruct classic with (y0 = e) as [EQ | NEQ]. + { subst y0. + unfold mapper' in EQ1. + rewrite upds in EQ1. + apply wf_threads in INE2; [| apply INV']. + destruct ADD. + apply add_event_threads in INE2. + desf. } + unfold mapper' in EQ1. + rewrite updo in EQ1. + { assert (EQ1' : tid (mapper y0) = t_2) by vauto. + apply (seq_thrd SIMREL) in EQ1'; vauto. + apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + vauto. } + destruct x1. + { unfold seq. exists (mapper' (InitEvent l0)); split. + { red; vauto. } + exists (mapper' y0); split. + { arewrite (mapper' (InitEvent l0) = mapper (InitEvent l0)). + { unfold mapper'. rewrite updo; vauto. + intros FLS. apply NINIT; vauto. } + rewrite (seq_init SIMREL). + { unfold ext_sb; vauto. + desf. } + vauto. } + red; vauto. } + assert (TIDD : thread = t_1). + { unfold ext_sb in COND. + desf. unfold tid. + destruct COND as [COND1 COND2]. + vauto. } + destruct y0. + { exfalso. unfold tid in TIDD2; vauto. } + unfold ext_sb in COND. + destruct COND as [COND1 COND2]. + unfold seq. + exists (mapper' (ThreadEvent thread index)); split. + { red; vauto. } + exists (mapper' (ThreadEvent thread0 index0)); split. + { assert (INDD : index >= t_1_len). + { apply NNPP. intros FLS. + apply Compare_dec.not_ge in FLS. + assert (INET : E_t (ThreadEvent thread index)). + { destruct classic with ((ThreadEvent thread index) = e) as [EQ | NEQ]. + { exfalso. unfold mapper' in NEQ2. + rewrite EQ in NEQ2. + rewrite upds in NEQ2; vauto. } + apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + apply (seq_out_snd SIMREL) in INET; vauto. + destruct classic with ((ThreadEvent t_1 index) = e) as [EQ | NEQ]. + { exfalso. unfold mapper' in NEQ2. + rewrite EQ in NEQ2. + rewrite upds in NEQ2; vauto. } + unfold mapper' in NEQ2. + rewrite updo in NEQ2; vauto. + rewrite INET in NEQ2. + desf. } + assert (INEE1 : E_t (ThreadEvent thread index)). + { destruct classic with ((ThreadEvent thread index) = e) as [EQ | NEQ]. + { exfalso. unfold mapper' in NEQ2. + rewrite EQ in NEQ2. + rewrite upds in NEQ2; vauto. } + apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + assert (INEE2 : E_t (ThreadEvent thread0 index0)). + { destruct classic with ((ThreadEvent thread0 index0) = e) as [EQ | NEQ]. + { exfalso. unfold mapper' in EQ1. + rewrite EQ in EQ1. + rewrite upds in EQ1; vauto. } + apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + apply (seq_out_move SIMREL) in INEE1, INEE2; vauto. + { assert (SWP1 : mapper' (ThreadEvent t_1 index) + = mapper (ThreadEvent t_1 index)). + { unfold mapper'. + destruct classic with (ThreadEvent t_1 index = e) as [EQ | NEQ]. + { exfalso. unfold mapper' in NEQ2. + rewrite EQ in NEQ2. + rewrite upds in NEQ2; vauto. } + rewrite updo; vauto. } + assert (SWP2 : mapper' (ThreadEvent t_1 index0) + = mapper (ThreadEvent t_1 index0)). + { unfold mapper'. + destruct classic with (ThreadEvent t_1 index0 = e) as [EQ | NEQ]. + { exfalso. rewrite EQ in THRDNEQ. + unfold mapper' in THRDNEQ. + rewrite upds in THRDNEQ; vauto. } + rewrite updo; vauto. } + rewrite SWP1, SWP2. + rewrite INEE1, INEE2. + unfold ext_sb. split; vauto. + unfold Events.index. + clear - COND2 INDD. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + red; vauto. } + destruct classic with (y0 = e) as [EQ | NEQ]. + { subst y0. left. + unfold seq. exists (mapper' x1); split; vauto. + exists (mapper' e); split; vauto. + destruct classic with (tid (mapper' x1) = t_2) as [EQ2 | NEQ2]. + { destruct classic with (x1 = e) as [EQ3 | NEQ3]. + { subst x1. unfold mapper'. + desf. } + assert (INEE : E_t x1). + { apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. + apply (seq_index SIMREL) in INEE; vauto. + { unfold ext_sb in COND. + desf. + { unfold mapper'. + rewrite updo; vauto. + rewrite upds; vauto. + rewrite (seq_init SIMREL); vauto. } + unfold mapper'. + rewrite upds; vauto. + rewrite updo; vauto. + rewrite (seq_out SIMREL); vauto. + unfold tid. + destruct COND as [COND1 COND2]. + vauto. } + unfold mapper'. rewrite updo; vauto. } + assert (INEE : E_t x1). + { destruct classic with (x1 = e) as [EQ3 | NEQ3]. + { subst x1. unfold ext_sb in COND. desf. + destruct COND as [COND1 COND2]. + exfalso. clear - COND2. lia. } + apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + apply (seq_mapeq SIMREL) in INEE; vauto. + { arewrite (mapper' x1 = mapper x1). + { unfold mapper'. rewrite updo; vauto. + intros FALSO. subst x1. + unfold ext_sb in COND. desf. + destruct COND as [COND1 COND2]. + exfalso. lia. } + rewrite INEE. + unfold mapper'. + rewrite upds; vauto. } + assert (SWP : mapper' x1 = mapper x1). + { unfold mapper'. rewrite updo; vauto. + intros FALSO. subst x1. + unfold ext_sb in COND. desf. } + rewrite SWP in NEQ2; vauto. } + destruct classic with (x1 = e) as [EQ2 | NEQ2]. + { subst x1. + left. + assert (SWP : mapper' y0 = mapper y0). + { unfold mapper'. rewrite updo; vauto. } + rewrite SWP in NEQ1; vauto. + assert (INEE : E_t y0). + { apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + apply (seq_mapeq SIMREL) in INEE; vauto. + unfold seq. exists (mapper' e); split; vauto. + exists (mapper' y0); split; vauto. + rewrite SWP, INEE. + unfold mapper'. + rewrite upds; vauto. } + left. + unfold seq. exists (mapper' x1); split; vauto. + exists (mapper' y0); split; vauto. + destruct classic with (tid (mapper' x1) = t_2) as [EQ3 | NEQ3]. + { unfold mapper' in EQ3. rewrite updo in EQ3. + { assert (INEE : E_t x1). + { apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + assert (INEE' : E_t x1) by vauto. + apply (seq_index SIMREL) in INEE. + { apply (seq_thrd SIMREL) in INEE'. + { destruct classic with (index y0 < t_1_len) as [LS | GT]. + assert (INEY : E_t y0). + { apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + unfold ext_sb in COND. + desf. + { unfold mapper' at 1. + rewrite updo; vauto. + rewrite (seq_init SIMREL); vauto. + unfold ext_sb; vauto. + desf. + unfold mapper' in Heq. + rewrite updo in Heq; vauto. + assert (REVV : mapper_rev (mapper (ThreadEvent thread index)) + = mapper_rev (InitEvent l1)). + { rewrite Heq; vauto. } + unfold compose in MAPREV. + rewrite MAPREV in REVV; vauto. + unfold id in REVV. + rewrite (seq_init_rev SIMREL) in REVV; vauto. } + { unfold mapper'. + rewrite !updo; vauto. + unfold Events.index in *. + destruct COND as [COND1 COND2]. + exfalso. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + exfalso. + apply Compare_dec.not_lt in GT. + assert (INEY : E_t y0). + { apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + apply (seq_out_move SIMREL) in INEY; vauto. + { unfold mapper' in NEQ1. + rewrite updo in NEQ1; vauto. + rewrite INEY in NEQ1. + desf. } + unfold ext_sb in COND. + desf. + { exfalso. + unfold tid in INEE'. + apply NINIT1; vauto. } + unfold tid in INEE'. + destruct COND as [COND1 COND2]. + unfold tid; vauto. } + vauto. } + vauto. } + vauto. } + assert (INEE : E_t x1). + { apply EQACTS in INE1. + destruct INE1 as [C1 | C2]; vauto. } + assert (INEE' : E_t y0). + { apply EQACTS in INE2. + destruct INE2 as [C1 | C2]; vauto. } + apply (seq_mapeq SIMREL) in INEE. + { apply (seq_mapeq SIMREL) in INEE'. + { unfold mapper'. + rewrite !updo; vauto. + rewrite INEE, INEE'; vauto. } + unfold mapper' in NEQ1. + rewrite updo in NEQ1; vauto. } + unfold mapper' in NEQ3. + rewrite updo in NEQ3; vauto. } + { rewrite (seq_threads SIMREL). + destruct ADD. rewrite add_event_threads; vauto. } + { unfold mapper'. intros x COND. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. rewrite upds; vauto. } + rewrite updo; vauto. + apply (seq_init SIMREL); vauto. } + { unfold mapper_rev'. intros x COND. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. rewrite upds; vauto. } + rewrite updo; vauto. + apply (seq_init_rev SIMREL); vauto. } + { intros e' INE NTID2. + apply EQACTS in INE. + destruct INE as [C1 | C2]. + { destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper'. rewrite upds; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_mapeq SIMREL) in C1; vauto. + unfold mapper' in NTID2. rewrite updo in NTID2; vauto. } + subst e'. unfold mapper'. rewrite upds; vauto. } + { intros x MAP TIDS. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper_rev'. rewrite upds; vauto. } + destruct MAP as [x0 [INE MAP]]. + unfold mapper_rev'. + rewrite updo; vauto. + unfold mapper'. + rewrite updo; vauto. + { unfold mapper' in TIDS. + rewrite updo in TIDS; vauto. + { destruct SIMREL. + apply seq_mapeq_rev in TIDS; vauto. + apply seq_acts. + red; exists x0; splits; vauto. + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. + apply seq_mapeq in TIDS; vauto. + { unfold mapper' in NEQ. + rewrite upds in NEQ. + desf. } + unfold mapper' in NEQ. + rewrite upds in NEQ. + desf. } + intros FLS. subst. + unfold mapper' in NEQ. + rewrite upds in NEQ. desf. } + intros FLS. subst. + unfold mapper' in NEQ. + rewrite upds in NEQ. desf. } + { intros e' INE TID2. + apply EQACTS in INE. + destruct INE as [C1 | C2]. + { destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper'. rewrite upds; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_mapto SIMREL) in C1; vauto. + unfold mapper'. rewrite updo; vauto. } + subst e'. unfold mapper' in TID2. + rewrite upds in TID2. + assert (INEN : E_t' e). + { apply EQACTS. basic_solver. } + exfalso. + destruct ADD. symmetry in add_event_threads. + assert (T2NOTIN' : ~ threads_set G_t' t_2). + { intros FALSE. apply add_event_threads in FALSE; vauto. } + desf. } + { intros e' INE TID2. + apply EQACTS in INE. + destruct INE as [C1 | C2]. + { destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper'. rewrite upds; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_index SIMREL) in C1; vauto. + unfold mapper'. rewrite updo; vauto. } + subst e'. unfold mapper' in TID2. + rewrite upds in TID2. + assert (INEN : E_t' e). + { apply EQACTS. basic_solver. } + exfalso. + destruct ADD. symmetry in add_event_threads. + assert (T2NOTIN' : ~ threads_set G_t' t_2). + { intros FALSE. apply add_event_threads in FALSE; vauto. } + desf. } + { intros x INE TID2. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper' in TID2. + rewrite upds in TID2. exfalso. + apply wf_threads in INE; [ | apply INV']. + destruct ADD. apply add_event_threads in INE. + apply T2NOTIN; vauto. } + unfold mapper' in TID2. + rewrite updo in TID2. + { destruct SIMREL. + apply seq_thrd in TID2. + { rewrite TID2; vauto. } + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + vauto. } + { intros x INE TID2. + unfold mapper_rev'. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper' in INE. + destruct INE as [x0 [INE MAP]]. + rewrite upds. + destruct classic with (x0 = e) as [EQ1 | NEQ1]. + { subst x0. apply wf_threads in INE; [ | apply INV']. + destruct ADD. apply add_event_threads in INE. + exfalso. apply T2NOTIN; vauto. } + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. + apply wf_threads in C1; [ | apply INV]. + destruct ADD. apply add_event_threads in C1. + exfalso. apply T2NOTIN; vauto. } + rewrite updo; vauto. + rewrite (seq_maprev SIMREL); vauto. + apply (seq_acts SIMREL). + apply MAPSUB. + unfold set_collect in INE. + destruct INE as [x0 [INE MAP]]. + apply EQACTS in INE. + destruct INE as [C1 | C2]. + { vauto. } + rewrite <- C2 in MAP. + assert (MAPNORM : mapper' e = e). + { rewrite set_collect_eq in MAPER_E. + apply MAPER_E; vauto. } + desf. } + { intros x INE TID2. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper'. + rewrite upds; vauto. } + unfold mapper'. + rewrite updo; vauto. + destruct SIMREL. + rewrite seq_out; vauto. + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + { intros x INE TIDS IDXS. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. unfold mapper'. + rewrite upds. desf. } + unfold mapper'. + rewrite updo; vauto. + destruct SIMREL. + rewrite seq_out_snd; vauto. + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + { intros x INE TIDS IDXS. + destruct classic with (x = e) as [EQ | NEQ]. + { subst. clear - IDXS TID. + exfalso. unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + lia. } + unfold mapper'. + rewrite updo; vauto. + destruct SIMREL. + rewrite seq_out_move; vauto. + apply EQACTS in INE. + destruct INE as [C1 | C2]; vauto. } + { intros e' NINE. + destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper'. rewrite upds; vauto. } + unfold mapper'. rewrite updo; vauto. + apply (seq_rest SIMREL); vauto. + intros FALSE. apply NINE. + apply EQACTS. unfold set_union. + left; vauto. } + intros e' NINE. + destruct classic with (e' = e) as [EQ | NEQ]. + { subst e'. unfold mapper_rev'. rewrite upds; vauto. } + unfold mapper_rev'. rewrite updo; vauto. + apply (seq_rest_rev SIMREL); vauto. + intros FALSE. apply NINE. unfold set_collect. + exists (mapper_rev e'). split. + { apply EQACTS. left. apply MAPREVDOM. + basic_solver. } + unfold mapper'. rewrite updo; vauto. + { apply MAPREVR; vauto. } + intros FLS. + assert (WRG : E_t e). + { apply MAPREVDOM. basic_solver 4. } + desf. } + split; vauto. constructor. + { unfold WCore.add_event. + exists (option_map mapper' r), (mapper' ↑₁ R1), + (option_map mapper' w), + (mapper' ↑₁ W1), + (mapper' ↑₁ W2). + apply add_event_to_wf; simpl; vauto. + { apply sico_init_acts_s with + (X_t := X_t) (mapper := mapper). + { constructor. all : try apply SIMREL. + rewrite (seq_lab SIMREL); vauto. } + destruct ADD. apply add_event_init. } + { unfold mapper'. rewrite upds. exact NOTIN. } + { unfold mapper'. rewrite upds; vauto. } + { unfold mapper'. rewrite upds. + destruct ADD; vauto. } + { rewrite EQACTS. rewrite set_collect_union. + rewrite MAPER_E, MAPSUB. rewrite (seq_acts SIMREL). + unfold mapper'. rewrite upds. basic_solver. } + { destruct ADD. destruct SIMRELQ. + unfold mapper', mapper_rev'. + apply functional_extensionality; ins. + destruct classic with (x = e) as [EQ | NEQ]. + { subst x. rewrite !upds. vauto. + rewrite add_event_lab. + unfold compose. rewrite upds. + rewrite upds; vauto. } + rewrite !updo; vauto. + { rewrite add_event_lab. + unfold compose. rewrite updo; vauto. + { destruct SIMREL. + destruct classic with (E_s x) as [INN | NINN]. + { rewrite updo; vauto. + rewrite seq_lab_rev0; vauto. } + rewrite updo; vauto. + rewrite seq_rlab0; vauto. } + rewrite updo; vauto. + destruct classic with (E_s x) as [INN | NINN]. + { destruct SIMREL. + intros FALSE. + assert (STT : mapper (mapper_rev x) = mapper e) + by vauto. + unfold compose in MAPREVR. + rewrite MAPREVR in STT. + { unfold id in STT. + rewrite seq_rest0 in STT; vauto. } + vauto. } + destruct SIMREL. + rewrite seq_rest_rev0; vauto. } + rewrite upds; vauto. } + { destruct ADD. rewrite add_event_rf. + rewrite !collect_rel_union. + arewrite (mapper' ↑ rf_t ≡ mapper ↑ rf_t). + { apply collect_rel_eq_dom' with (s := E_t); ins. + apply (wf_rfE); vauto. } + rewrite (seq_rf SIMREL). + arewrite (mapper' ↑ WCore.rf_delta_R e w + ≡ WCore.rf_delta_R (mapper' e) + (option_map mapper' w)). + { unfold WCore.rf_delta_R. + rewrite collect_rel_cross. + apply cross_more. + { clear. unfold option_map. basic_solver. } + clear. unfold option_map. basic_solver. } + arewrite (mapper' ↑ WCore.rf_delta_W e R1 + ≡ WCore.rf_delta_W (mapper' e) (mapper' ↑₁ R1)). + { unfold WCore.rf_delta_W. + rewrite collect_rel_cross. + apply cross_more. + { clear. unfold option_map. basic_solver. } + clear. unfold option_map. basic_solver. } + vauto. } + { destruct ADD. rewrite add_event_co. + rewrite !collect_rel_union. + arewrite (mapper' ↑ co_t ≡ mapper ↑ co_t). + { apply collect_rel_eq_dom' with (s := E_t); ins. + apply (wf_coE); vauto. } + rewrite (seq_co SIMREL). + arewrite (mapper' ↑ WCore.co_delta e W1 W2 + ≡ WCore.co_delta (mapper' e) (mapper' ↑₁ W1) + (mapper' ↑₁ W2)). + { unfold WCore.co_delta. rewrite collect_rel_union. + apply union_more. + { rewrite collect_rel_cross. + apply cross_more; vauto. + clear. basic_solver. } + rewrite collect_rel_cross. + apply cross_more; vauto. + clear. basic_solver. } + vauto. } + { rewrite <- mapped_rmw_delta, (WCore.add_event_rmw ADD), + collect_rel_union. + arewrite (mapper' ↑ rmw_t ≡ mapper ↑ rmw_t). + { apply collect_rel_eq_dom' with (s := E_t); ins. + apply (wf_rmwE); vauto. } + now rewrite (seq_rmw SIMREL). } + { rewrite (seq_data SIMREL); vauto. } + { rewrite (seq_addr SIMREL); vauto. } + { rewrite (seq_ctrl SIMREL); vauto. } + { rewrite (seq_rmw_dep SIMREL); vauto. } + { admit. (* all the events except t_2 are stay on their + places, t_2 moves in order and delta-edges + are added respectively as well *) } + arewrite (G_s' = WCore.G X_s'). + apply wf_transition with (X_t := X_t') + (t_1 := t_1) (t_2 := t_2) + (mapper := mapper') (mapper_rev := mapper_rev') + (ptc_1 := ptc_1); vauto. } + { unfold rf_complete. + rewrite (seq_acts SIMRELQ), (seq_rf SIMRELQ). + unfold rf_complete in RFC. rewrite EQACTS. + rewrite !set_collect_union, MAPER_E, MAPSUB. + rewrite set_inter_union_l. + rewrite set_subset_union_l; split. + { unfold rf_complete in RFC. + rewrite <- set_collect_codom, <- RFC. + unfolder. intros x ((x' & INE & XEQ) & ISR). + exists x'. splits; try basic_solver. + { apply EQACTS; vauto. } + subst x. unfold is_r in *. + assert (CHNG : WCore.G X_s' = G_s') by vauto. + rewrite CHNG in ISR. unfold G_s' in ISR; ins. + unfold compose in ISR. + assert (NEQ : x' <> e). + { intros FALSE. subst x'. basic_solver 8. } + assert (NEQ' : mapper x' <> e). + { intros FALSE. destruct NOTIN. + rewrite <- FALSE. apply (seq_codom SIMREL); vauto. } + assert (EQQ : mapper_rev' (mapper x') = x'). + { unfold eq_dom in MAPREV. specialize MAPREV with x'. + apply MAPREV in INE. unfold compose in INE. + unfold mapper_rev'. rewrite updo; vauto. } + rewrite EQQ in ISR; vauto. } + rewrite <- set_collect_codom. rewrite <- RFC. + intros x (EQ & RD). subst x. + unfold set_collect. exists e. splits; vauto. + { split. + { apply EQACTS. basic_solver. } + assert (FEQ : WCore.G X_s' = G_s') by vauto. + rewrite FEQ in RD. unfold G_s' in RD. + simpl in RD. clear - RD. unfold compose in RD. + unfold is_r in RD. unfold mapper_rev' in RD. + rewrite upds in RD; vauto. } + unfold mapper'. rewrite upds. vauto. } + apply XmmCons.monoton_cons with (G_t := G_t') + (m := mapper'); vauto; try apply SIMRELQ. + { unfold rpo. unfold rpo_imm. + arewrite (WCore.G X_s' = G_s'). + destruct SIMRELQ. + assert (RESTR : ⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ sb_t' ⨾ ⦗F G_t' ∩₁ Acq G_t'⦘ ∪ ⦗Acq G_t'⦘ ⨾ sb_t' ∪ sb_t' ⨾ ⦗Rel G_t'⦘ + ∪ ⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ sb_t' ⨾ ⦗W_t' ∩₁ Rlx G_t'⦘ ≡ restr_rel E_t' ( + ⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ sb_t' ⨾ ⦗F G_t' ∩₁ Acq G_t'⦘ ∪ ⦗Acq G_t'⦘ ⨾ sb_t' ∪ sb_t' ⨾ ⦗Rel G_t'⦘ + ∪ ⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ sb_t' ⨾ ⦗W_t' ∩₁ Rlx G_t'⦘)). + { split. + { rewrite !restr_union. + repeat apply union_mori. + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] [x1 [COND [EQ2 CD2]]]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] COND]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x1 [COND [EQ2 CD2]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] [x1 [COND [EQ2 CD2]]]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + rewrite inclusion_restr; vauto. } + rewrite RESTR. + rewrite collect_rel_ct_inj. + { assert (MAPREVCOMP : eq_dom (acts_set G_s') (mapper' ∘ mapper_rev') id). + { intros x COND. + unfold G_s' in COND; ins. + destruct COND as [x0 [COND EQ]]; subst. + unfold compose. + destruct classic with (x0 = e) as [EQ1 | NEQ1]. + { subst x0. unfold mapper', mapper_rev'. + rewrite !upds; vauto. } + apply EQACTS in COND. + destruct COND as [C1 | C2]. + { unfold mapper', mapper_rev'. + unfold id. + arewrite (upd mapper e e x0 = mapper x0). + arewrite (upd mapper_rev e e (mapper x0) = mapper_rev (mapper x0)). + { destruct classic with (mapper x0 = e) as [EQ2 | NEQ2]. + { destruct SIMREL. + assert (INEE : E_s e). + { apply seq_acts0. + red; vauto. } + desf. } + rewrite updo; vauto. } + unfold compose in MAPREV. + rewrite MAPREV; vauto. + unfold id. rewrite updo; vauto. } + desf. } + assert (SBIN : sb G_s' ⊆ mapper' ↑ sb_t'). + { rewrite <- seq_sb; vauto. } + apply clos_trans_mori. + rewrite <- RESTR. + rewrite !collect_rel_union. + repeat apply union_mori. + { rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + arewrite (⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (F G_t' ∩₁ Acq G_t')⦘ ≡ + ⦗R_t' ∩₁ Rlx G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (F G_t' ∩₁ Acq G_t')⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [[ISR ISRLX] INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rlx, mod in ISRLX. + rewrite seq_lab_rev in ISRLX; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_r. unfold compose in ISRLX; vauto. } + { unfold is_rlx. unfold compose in ISRLX; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE [ISF ISA]]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_acq, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + { unfold is_r. unfold compose in ISA; vauto. } + unfold is_rlx. unfold compose in ISA; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + { rewrite wf_sbE. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + arewrite (⦗Acq G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t'⦘ ≡ + ⦗Acq G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t'⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [ISA INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_acq, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_acq. unfold compose in ISA; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ INE]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + { rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ INE]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE ISR]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rel, mod in ISR. + rewrite seq_lab_rev in ISR; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + unfold is_rel. unfold compose in ISR; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + arewrite (⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (W_t' ∩₁ Rlx G_t')⦘ ≡ + ⦗F G_t' ∩₁ Rel G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (W_t' ∩₁ Rlx G_t')⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [[ISF ISREL] INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rel, mod in ISREL. + rewrite seq_lab_rev in ISREL; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_r. unfold compose in ISREL; vauto. } + { unfold is_rlx. unfold compose in ISREL; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE [ISF ISA]]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rlx, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + { unfold is_r. unfold compose in ISA; vauto. } + unfold is_rlx. unfold compose in ISA; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + vauto. } + { rewrite <- (seq_lab SIMRELQ); vauto. } + { assert (SBEQ : sb G_s' ≡ mapper' ↑ sb_t' \ po_seq X_s' t_1 t_2). + { rewrite <- (seq_sb SIMRELQ). + rewrite minus_union_l. + rewrite minusK. split; [| basic_solver]. + intros x y COND. + left. split; vauto. + intros FLS. + unfold po_seq in FLS. + destruct FLS as [[TID1 INE1] [TID2 INE2]]. + unfold sb in COND. unfold ext_sb in COND. + clear - COND TID1 TID2 NINIT1 NINIT2 THRDNEQ. + destruct COND as [x0 [[EQQ1 INEE1] [x1 [COND2 [EQQ2 INEE2]]]]]. + subst. desf. basic_solver 42. } + arewrite (WCore.G X_s' = G_s'). + rewrite SBEQ. + intros x y COND. + destruct COND as [[CDMAP POSEQ] COND2]. + destruct CDMAP as [x0 [x1 [CND [M1 M2]]]]. + unfold collect_rel. + exists x0, x1; split; vauto. + split; vauto. + unfold same_loc in *. + destruct SIMRELQ. + unfold loc. rewrite !seq_lab. + { unfold compose; vauto. } + all : apply wf_sbE in CND. + all : destruct CND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; vauto. } + { apply INV'. } + apply wf_transition with (X_t := X_t') + (t_1 := t_1) (t_2 := t_2) + (mapper := mapper') (mapper_rev := mapper_rev') + (ptc_1 := ptc_1); vauto. +Admitted. + +End SimrelStep. diff --git a/src/sequentialization/SequentProgs.v b/src/sequentialization/SequentProgs.v new file mode 100644 index 00000000..c3e4104c --- /dev/null +++ b/src/sequentialization/SequentProgs.v @@ -0,0 +1,276 @@ +Require Import AuxDef. +Require Import Core. +Require Import AuxRel AuxRel2. +Require Import Srf Rhb. +Require Import SimrelCommon. +Require Import StepOps. +Require Import AuxInj. +Require Import xmm_s_hb. +Require Import Lia. +From xmm Require Import Reordering. +From xmm Require Import ThreadTrace. +From xmm Require Import Programs. +From xmm Require Import SequentBase. +From xmm Require Import SequentExec. +From xmm Require Import SequentExec2. +From xmm Require Import SequentExec3. +From xmm Require Import SequentReexec. + +From hahn Require Import Hahn. +From hahnExt Require Import HahnExt. +From imm Require Import Events Execution Execution_eco. +Require Import Setoid Morphisms Program.Basics. + +Open Scope program_scope. + +Set Implicit Arguments. + +Section SimrelGen. + +Variable X_t X_t' X_s : WCore.t. +Variable t_1 t_2 : thread_id. +Variable mapper : actid -> actid. +Variable mapper_rev : actid -> actid. + +Variable ptc_1 ptc_2 : program_trace. + +Variable dtrmt_t cmt_t : actid -> Prop. +Variable thrdle : relation thread_id. + +Notation "'G_t'" := (WCore.G X_t). +Notation "'G_t''" := (WCore.G X_t'). +Notation "'G_s'" := (WCore.G X_s). + +Notation "'R' G" := (fun e => is_true (is_r (lab G) e)) (at level 1). +Notation "'F' G" := (fun e => is_true (is_f (lab G) e)) (at level 1). +Notation "'W' G" := (fun e => is_true (is_w (lab G) e)) (at level 1). +Notation "'Acq' G" := (fun e => is_true (is_acq (lab G) e)) (at level 1). +Notation "'Rlx' G" := (fun e => is_true (is_rlx (lab G) e)) (at level 1). +Notation "'Rel' G" := (fun e => is_true (is_rel (lab G) e)) (at level 1). + +Notation "'lab_t'" := (lab G_t). +Notation "'val_t'" := (val lab_t). +Notation "'loc_t'" := (loc lab_t). +Notation "'same_loc_t'" := (same_loc lab_t). +Notation "'E_t'" := (acts_set G_t). +Notation "'sb_t'" := (sb G_t). +Notation "'rf_t'" := (rf G_t). +Notation "'co_t'" := (co G_t). +Notation "'rmw_t'" := (rmw G_t). +Notation "'rpo_t'" := (rpo G_t). +Notation "'rmw_dep_t'" := (rmw_dep G_t). +Notation "'data_t'" := (data G_t). +Notation "'ctrl_t'" := (ctrl G_t). +Notation "'addr_t'" := (addr G_t). +Notation "'W_t'" := (fun x => is_true (is_w lab_t x)). +Notation "'R_t'" := (fun x => is_true (is_r lab_t x)). +Notation "'Loc_t_' l" := (fun e => loc_t e = l) (at level 1). + +Notation "'lab_t''" := (lab G_t'). +Notation "'val_t''" := (val lab_t'). +Notation "'loc_t''" := (loc lab_t'). +Notation "'same_loc_t''" := (same_loc lab_t'). +Notation "'E_t''" := (acts_set G_t'). +Notation "'sb_t''" := (sb G_t'). +Notation "'rf_t''" := (rf G_t'). +Notation "'co_t''" := (co G_t'). +Notation "'rmw_t''" := (rmw G_t'). +Notation "'rpo_t''" := (rpo G_t'). +Notation "'rmw_dep_t''" := (rmw_dep G_t'). +Notation "'data_t''" := (data G_t'). +Notation "'ctrl_t''" := (ctrl G_t'). +Notation "'addr_t''" := (addr G_t'). +Notation "'W_t''" := (fun x => is_true (is_w lab_t' x)). +Notation "'R_t''" := (fun x => is_true (is_r lab_t' x)). +Notation "'Loc_t_'' l" := (fun e => loc_t' e = l) (at level 1). + +Notation "'lab_s'" := (lab G_s). +Notation "'val_s'" := (val lab_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'same_loc_s'" := (same_loc lab_s). +Notation "'E_s'" := (acts_set G_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'sb_s'" := (sb G_s). +Notation "'rf_s'" := (rf G_s). +Notation "'co_s'" := (co G_s). +Notation "'rmw_s'" := (rmw G_s). +Notation "'rpo_s'" := (rpo G_s). +Notation "'rmw_dep_s'" := (rmw_dep G_s). +Notation "'data_s'" := (data G_s). +Notation "'ctrl_s'" := (ctrl G_s). +Notation "'addr_s'" := (addr G_s). +Notation "'W_s'" := (fun x => is_true (is_w lab_s x)). +Notation "'R_s'" := (fun x => is_true (is_r lab_s x)). +Notation "'F_s'" := (F G_s). + +Notation "'Tid_' t" := (fun e => tid e = t) (at level 1). + +Lemma seq_step_gen + (NINIT1 : t_1 <> tid_init) + (NINIT2 : t_2 <> tid_init) + (THRDNEQ : t_1 <> t_2) + (STEP : xmm_step X_t X_t') + (SIMREL : seq_simrel X_s X_t t_1 t_2 mapper mapper_rev ptc_1) : + exists X_s' mapper' mapper_rev', + << SIMREL : seq_simrel X_s' X_t' t_1 t_2 mapper' mapper_rev' ptc_1 >> /\ + << STEP : xmm_step⁺ X_s X_s' >>. +Proof using. + admit. +Admitted. + +End SimrelGen. + +Section BehaviorGraph. + +Variable G_1 G_2 : execution. + +Notation "'E_1'" := (acts_set G_1). + +Notation "'lab'" := (lab G_1). +Notation "'loc'" := (loc lab). +Notation "'val'" := (val lab). + +Definition graph_locations (G : execution) : Set := + { l : location | exists e, acts_set G e /\ loc e = Some l }. + +Definition same_behaviors (G_1 G_2 : execution) : Prop := + behavior_spec G_1 = behavior_spec G_2. + +End BehaviorGraph. + +Section SimrelMain. + +Variable X_t_init X_s_init X_t : WCore.t. +Variable t_1 t_2 : thread_id. +Variable ptc_1 ptc_2 : program_trace. + +Notation "'G_t_init'" := (WCore.G X_t_init). +Notation "'G_s_init'" := (WCore.G X_s_init). +Notation "'G_t'" := (WCore.G X_t). + +Notation "'R' G" := (fun e => is_true (is_r (lab G) e)) (at level 1). +Notation "'F' G" := (fun e => is_true (is_f (lab G) e)) (at level 1). +Notation "'W' G" := (fun e => is_true (is_w (lab G) e)) (at level 1). +Notation "'Acq' G" := (fun e => is_true (is_acq (lab G) e)) (at level 1). +Notation "'Rlx' G" := (fun e => is_true (is_rlx (lab G) e)) (at level 1). +Notation "'Rel' G" := (fun e => is_true (is_rel (lab G) e)) (at level 1). + +Notation "'lab_t_init'" := (lab G_t_init). +Notation "'val_t_init'" := (val lab_t_init). +Notation "'loc_t_init'" := (loc lab_t_init). +Notation "'same_loc_t_init'" := (same_loc lab_t_init). +Notation "'E_t_init'" := (acts_set G_t_init). +Notation "'sb_t_init'" := (sb G_t_init). +Notation "'rf_t_init'" := (rf G_t_init). +Notation "'co_t_init'" := (co G_t_init). +Notation "'rmw_t_init'" := (rmw G_t_init). +Notation "'rpo_t_init'" := (rpo G_t_init). +Notation "'rmw_dep_t_init'" := (rmw_dep G_t_init). +Notation "'data_t_init'" := (data G_t_init). +Notation "'ctrl_t_init'" := (ctrl G_t_init). +Notation "'addr_t_init'" := (addr G_t_init). +Notation "'W_t_init'" := (fun x => is_true (is_w lab_t_init x)). +Notation "'R_t_init'" := (fun x => is_true (is_r lab_t_init x)). +Notation "'Loc_t_init_' l" := (fun e => loc_t_init e = l) (at level 1). + +Notation "'lab_s_init'" := (lab G_s_init). +Notation "'val_s_init'" := (val lab_s_init). +Notation "'loc_s_init'" := (loc lab_s_init). +Notation "'same_loc_s_init'" := (same_loc lab_s_init). +Notation "'E_s_init'" := (acts_set G_s_init). +Notation "'loc_s_init'" := (loc lab_s_init). +Notation "'sb_s_init'" := (sb G_s_init). +Notation "'rf_s_init'" := (rf G_s_init). +Notation "'co_s_init'" := (co G_s_init). +Notation "'rmw_s_init'" := (rmw G_s_init). +Notation "'rpo_s_init'" := (rpo G_s_init). +Notation "'rmw_dep_s_init'" := (rmw_dep G_s_init). +Notation "'data_s_init'" := (data G_s_init). +Notation "'ctrl_s_init'" := (ctrl G_s_init). +Notation "'addr_s_init'" := (addr G_s_init). +Notation "'W_s_init'" := (fun x => is_true (is_w lab_s_init x)). +Notation "'R_s_init'" := (fun x => is_true (is_r lab_s_init x)). +Notation "'Loc_s_init_' l" := (fun e => loc_s_init e = l) (at level 1). + +Notation "'lab_t'" := (lab G_t). +Notation "'val_t'" := (val lab_t). +Notation "'loc_t'" := (loc lab_t). +Notation "'same_loc_t'" := (same_loc lab_t). +Notation "'E_t'" := (acts_set G_t). +Notation "'sb_t'" := (sb G_t). +Notation "'rf_t'" := (rf G_t). +Notation "'co_t'" := (co G_t). +Notation "'rmw_t'" := (rmw G_t). +Notation "'rpo_t'" := (rpo G_t). +Notation "'rmw_dep_t'" := (rmw_dep G_t). +Notation "'data_t'" := (data G_t). +Notation "'ctrl_t'" := (ctrl G_t). +Notation "'addr_t'" := (addr G_t). +Notation "'W_t'" := (fun x => is_true (is_w lab_t x)). +Notation "'R_t'" := (fun x => is_true (is_r lab_t x)). +Notation "'Loc_t_' l" := (fun e => loc_t e = l) (at level 1). + +Notation "'Tid_' t" := (fun e => tid e = t) (at level 1). + +Lemma simrel_main + (NINIT1 : t_1 <> tid_init) + (NINIT2 : t_2 <> tid_init) + (THRDNEQ : t_1 <> t_2) + (TARGETPTH : xmm_step* X_t_init X_t) : + exists X_s mapper mapper_rev, + << SIMREL : seq_simrel X_s X_t t_1 t_2 mapper mapper_rev ptc_1>> /\ + << STEP : xmm_step* X_s_init X_s >> /\ + << BEHRS : same_behaviors (WCore.G X_s) G_t >>. +Proof using. + admit. +Admitted. + +End SimrelMain. + +Section ProgMain. + +Variable X_t : WCore.t. +Variable t_1 t_2 : thread_id. +Variable threads : thread_id -> Prop. +Variable ptc_1 ptc_2 : program_trace. + +Variable p1 p2 : program. + +Definition X_t_init : WCore.t := WCore.Build_t (WCore.init_exec threads) ∅₂. +Definition X_s_init : WCore.t := WCore.Build_t (WCore.init_exec (threads ∪₁ eq t_2)) ∅₂. + +Hypothesis PROGSEQ : program_sequented p1 p2 t_1 t_2. + +Lemma prog_supp : + exists X_s mapper mapper_rev, + << SIMREL : seq_simrel X_s X_t t_1 t_2 mapper mapper_rev ptc_1>> /\ + << STEP : xmm_step* X_s_init X_s >> /\ + << BEHRS : same_behaviors (WCore.G X_s) (WCore.G X_t) >>. +Proof using. + admit. +Admitted. + +Lemma prog_helper X_s mapper mapper_rev : + seq_simrel X_s X_t t_1 t_2 mapper mapper_rev ptc_1 -> + exec_sequent X_s X_t p1 p2 t_1 t_2. +Proof using. + intros SIMREL. + constructor; vauto. + intros tr_1 tr2 TR1 TR2 CR1 CR2. + constructor. all : admit. +Admitted. + +Lemma prog_main : + exists X_s, + << SEQUED : exec_sequent X_s X_t p1 p2 t_1 t_2 >> /\ + << STEP : xmm_step* X_s_init X_s >> /\ + << BEHRS : same_behaviors (WCore.G X_s) (WCore.G X_t) >>. +Proof using. + destruct prog_supp as (X_s & mapper & mapper_rev & SIMREL & STEP & BEHRS). + exists X_s; splits; auto. + apply prog_helper with (mapper := mapper) + (mapper_rev := mapper_rev). + vauto. +Admitted. + +End ProgMain. diff --git a/src/sequentialization/SequentReexec.v b/src/sequentialization/SequentReexec.v new file mode 100644 index 00000000..da8e1d4f --- /dev/null +++ b/src/sequentialization/SequentReexec.v @@ -0,0 +1,2620 @@ +Require Import AuxDef. +Require Import Core. +Require Import AuxRel AuxRel2. +Require Import Srf Rhb. +Require Import SimrelCommon. +Require Import SubToFullExec. +Require Import StepOps. +Require Import AuxInj. +Require Import xmm_s_hb. +Require Import Lia. +From xmm Require Import Reordering. +From xmm Require Import ThreadTrace. +From xmm Require Import Programs. +From xmm Require Import SequentBase. +From xmm Require Import SequentWf. +From xmm Require Import ConsistencyMonotonicity. + +From hahn Require Import Hahn. +From hahnExt Require Import HahnExt. +From imm Require Import Events Execution Execution_eco SubExecution. +Require Import Setoid Morphisms Program.Basics. + +Open Scope program_scope. + +Set Implicit Arguments. + +Section SequentReexec. + +Variable X_t X_t' X_s : WCore.t. +Variable t_1 t_2 : thread_id. +Variable mapper : actid -> actid. +Variable mapper_rev : actid -> actid. + +Variable dtrmt_t cmt_t : actid -> Prop. +Variable thrdle : relation thread_id. +Variable f_t : actid -> actid. + +Variable ptc_1 ptc_2 : program_trace. + +Notation "'G_t'" := (WCore.G X_t). +Notation "'G_t''" := (WCore.G X_t'). +Notation "'G_s'" := (WCore.G X_s). + +Notation "'R' G" := (fun e => is_true (is_r (lab G) e)) (at level 1). +Notation "'F' G" := (fun e => is_true (is_f (lab G) e)) (at level 1). +Notation "'W' G" := (fun e => is_true (is_w (lab G) e)) (at level 1). +Notation "'Acq' G" := (fun e => is_true (is_acq (lab G) e)) (at level 1). +Notation "'Rlx' G" := (fun e => is_true (is_rlx (lab G) e)) (at level 1). +Notation "'Rel' G" := (fun e => is_true (is_rel (lab G) e)) (at level 1). + +Notation "'lab_t'" := (lab G_t). +Notation "'val_t'" := (val lab_t). +Notation "'loc_t'" := (loc lab_t). +Notation "'same_loc_t'" := (same_loc lab_t). +Notation "'E_t'" := (acts_set G_t). +Notation "'sb_t'" := (sb G_t). +Notation "'rf_t'" := (rf G_t). +Notation "'co_t'" := (co G_t). +Notation "'rmw_t'" := (rmw G_t). +Notation "'rpo_t'" := (rpo G_t). +Notation "'rmw_dep_t'" := (rmw_dep G_t). +Notation "'data_t'" := (data G_t). +Notation "'ctrl_t'" := (ctrl G_t). +Notation "'addr_t'" := (addr G_t). +Notation "'W_t'" := (fun x => is_true (is_w lab_t x)). +Notation "'R_t'" := (fun x => is_true (is_r lab_t x)). +Notation "'Loc_t_' l" := (fun e => loc_t e = l) (at level 1). + +Notation "'lab_t''" := (lab G_t'). +Notation "'val_t''" := (val lab_t'). +Notation "'loc_t''" := (loc lab_t'). +Notation "'same_loc_t''" := (same_loc lab_t'). +Notation "'E_t''" := (acts_set G_t'). +Notation "'sb_t''" := (sb G_t'). +Notation "'rf_t''" := (rf G_t'). +Notation "'co_t''" := (co G_t'). +Notation "'rmw_t''" := (rmw G_t'). +Notation "'rpo_t''" := (rpo G_t'). +Notation "'rmw_dep_t''" := (rmw_dep G_t'). +Notation "'data_t''" := (data G_t'). +Notation "'ctrl_t''" := (ctrl G_t'). +Notation "'addr_t''" := (addr G_t'). +Notation "'W_t''" := (fun x => is_true (is_w lab_t' x)). +Notation "'R_t''" := (fun x => is_true (is_r lab_t' x)). +Notation "'Loc_t_'' l" := (fun e => loc_t' e = l) (at level 1). + +Notation "'lab_s'" := (lab G_s). +Notation "'val_s'" := (val lab_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'same_loc_s'" := (same_loc lab_s). +Notation "'E_s'" := (acts_set G_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'sb_s'" := (sb G_s). +Notation "'rf_s'" := (rf G_s). +Notation "'co_s'" := (co G_s). +Notation "'rmw_s'" := (rmw G_s). +Notation "'rpo_s'" := (rpo G_s). +Notation "'rmw_dep_s'" := (rmw_dep G_s). +Notation "'data_s'" := (data G_s). +Notation "'ctrl_s'" := (ctrl G_s). +Notation "'addr_s'" := (addr G_s). +Notation "'W_s'" := (fun x => is_true (is_w lab_s x)). +Notation "'R_s'" := (fun x => is_true (is_r lab_s x)). +Notation "'F_s'" := (F G_s). + +Notation "'Tid_' t" := (fun e => tid e = t) (at level 1). + +Hypothesis MAPREV : eq_dom E_t (mapper_rev ∘ mapper) id. +Hypothesis PROGSEQ : program_trace_sequented ptc_1 ptc_2 t_1 t_2. +Hypothesis STEP : WCore.reexec_gen X_t X_t' f_t dtrmt_t cmt_t thrdle. + +Definition t_12_len := length (ptc_2 t_2). +Definition t_1_len := length (ptc_1 t_1). +Definition t_2_len := length (ptc_1 t_2). + +(* Definition cmt' := mapper ↑₁ cmt_t. +Definition dtrmt' := mapper ↑₁ dtrmt_t. *) + +Hypothesis INTREADS : forall (x : actid), + tid x = tid_init <-> is_init x. + +Definition relation_lowering (A : Type) (r : relation A) (P : A -> Prop) : relation A := + fun x y => r x y /\ P x /\ P y. + +Lemma codom_ct_union (A : Type) (r r' : relation A) : + codom_rel ((r ∪ r')⁺) ≡₁ codom_rel r ∪₁ codom_rel r'. +Proof using. + rewrite codom_ct. + unfold codom_rel; basic_solver. +Qed. + +Lemma rel_low (A : Type) (r : relation A) (P : A -> Prop) : + relation_lowering r P ≡ r ∩ (P × P). +Proof using. + unfold relation_lowering. basic_solver. +Qed. + +Lemma codom_crossed (A : Type) (P P' : A -> Prop) : + codom_rel (P × P') ⊆₁ P'. +Proof using. + unfold codom_rel. basic_solver. +Qed. + +Lemma codom_rel_low (A : Type) (r : relation A) (P : A -> Prop) : + codom_rel (relation_lowering r P) ⊆₁ codom_rel r ∩₁ P. +Proof using. + rewrite rel_low. basic_solver. +Qed. + +Hypothesis THRLEE : thrdle ≡ ⦗threads_set G_t⦘ ⨾ thrdle ⨾ ⦗threads_set G_t⦘. + +Definition thrdle' := thrdle ∪ eq t_2 × eq t_1 ∪ dom_rel (thrdle ⨾ ⦗eq t_1⦘) × eq t_2 + ∪ eq t_2 × codom_rel (⦗eq t_1⦘ ⨾ thrdle) + ∪ eq tid_init × codom_rel (thrdle). + +Hypothesis INV : seq_simrel_inv X_t. +Hypothesis INV' : seq_simrel_inv X_t'. + +Lemma simrel_step_reex + (NINIT1 : t_1 <> tid_init) + (NINIT2 : t_2 <> tid_init) + (T2NOTIN : ~ threads_set G_t t_2) + (THRDNEQ : t_1 <> t_2) + (SIMREL : seq_simrel X_s X_t t_1 t_2 mapper mapper_rev ptc_1) : + exists (X_s' : WCore.t) (mapper' : actid -> actid) (mapper_rev' : actid -> actid) + (dtrmt' : actid -> Prop) (cmt' : actid -> Prop), + << SIMREL : seq_simrel X_s' X_t' t_1 t_2 mapper' mapper_rev' ptc_1 >> /\ + << REX : WCore.reexec X_s X_s' (mapper ∘ f_t ∘ mapper_rev') dtrmt' cmt' >>. +Proof using. + + set (mapper' := fun x => ifP (~ E_t' x) then x else + (ifP ((tid x) <> t_1) then x + else (ifP index x < t_1_len then x + else ThreadEvent t_2 (index x - t_1_len)))). + + set (G_s' := {| + acts_set := mapper' ↑₁ E_t'; + threads_set := threads_set G_s; + lab := lab_t' ∘ (fun x => ifP (~ (mapper' ↑₁ E_t') x) then x else + ( ifP ((tid x) <> t_2) then x + else ThreadEvent t_1 (t_1_len + index x))); + rf := mapper' ↑ rf_t'; + co := mapper' ↑ co_t'; + rmw := mapper' ↑ rmw_t'; + rmw_dep := ∅₂; + ctrl := ∅₂; + data := ∅₂; + addr := ∅₂; + |}). + set (X_s' := {| + WCore.sc := WCore.sc X_s; + WCore.G := G_s'; + |}). + + set (mapper_rev' := fun x => ifP (~ (acts_set G_s') x) then x else + ( ifP ((tid x) <> t_2) then x + else ThreadEvent t_1 (t_1_len + index x))). + + set (dtrmt' := mapper' ↑₁ dtrmt_t). + set (cmt' := mapper' ↑₁ cmt_t). + + exists X_s', mapper', mapper_rev', dtrmt', cmt'. + assert (threads_set G_t ≡₁ threads_set G_t') as TSET. + { symmetry. apply reex_thrd_preserve with (f := f_t) + (dtrmt := dtrmt_t) (cmt := cmt_t) + (thrdle := thrdle); vauto. } + + assert (INDLEMMA : forall x y (NNIT : tid x <> tid_init) (EQT : tid x = tid y) (EQI : index x = index y), + x = y). + { clear. intros x y NNIT EQT EQI. + destruct x; destruct y; desf; ins. + desf. } + + assert (DTRSAME : forall x, dtrmt_t x -> + mapper x = mapper' x). + { intros x COND. + destruct classic with (tid (mapper + x) = t_2) as [TID2 | TID2]. + { assert (TID2' : tid (mapper x) = t_2) by vauto. + assert (TID2S : tid (mapper x) = t_2) by vauto. + destruct SIMREL. + apply seq_index in TID2. + apply seq_thrd in TID2'. + { apply INDLEMMA. + { unfold mapper'. desf. } + { unfold mapper'. + rewrite TID2S. clear TID2S. + desf. + { destruct STEP. + apply dtrmt_cmt in COND. + apply reexec_embd_dom in COND; vauto. } + symmetry in TID2. + rewrite <- TID2 in l. + exfalso. unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + unfold mapper'. + rewrite TID2. clear TID2. + desf. + { destruct STEP. + apply dtrmt_cmt in COND. + apply reexec_embd_dom in COND; vauto. } + { exfalso. unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + unfold Events.index in *. + unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + lia. } + { destruct STEP. apply rexec_acts; vauto. } + destruct STEP. apply rexec_acts; vauto. } + assert (TID2' : tid (mapper x) <> t_2) by vauto. + assert (TID2S : tid (mapper x) <> t_2) by vauto. + apply (seq_mapeq SIMREL) in TID2. + { rewrite TID2. clear TID2. + unfold mapper'. desf. + apply INDLEMMA. + { unfold not in n0. + apply NNPP in n0. + rewrite n0; vauto. } + { unfold tid. + unfold not in n0. + apply NNPP in n0. + apply (seq_out_move SIMREL) in n0; vauto. + { apply (seq_mapeq SIMREL) in TID2S; vauto. + rewrite TID2S in n0. + desf. + destruct STEP. apply rexec_acts; vauto. } + { destruct STEP. apply rexec_acts; vauto. } + unfold Events.index in *. + unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + lia. } + unfold Events.index in *. + unfold not in n0. + apply NNPP in n0. + apply (seq_out_move SIMREL) in n0; vauto. + { apply (seq_mapeq SIMREL) in TID2S; vauto. + { rewrite TID2S in n0. + desf. } + destruct STEP. apply rexec_acts; vauto. } + { destruct STEP. apply rexec_acts; vauto. } + unfold Events.index in *. + unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + lia. } + destruct STEP. apply rexec_acts; vauto. } + + assert (EXTSBL : forall x y, E_t' x -> E_t' y -> + ext_sb (mapper' x) (mapper' y) -> + ext_sb x y). + { intros x y INE1 INE2 PTH. + unfold mapper' in PTH. desf; vauto. + { unfold not in n2. + apply NNPP in n2. + unfold ext_sb in PTH. desf. + { basic_solver. } + unfold ext_sb. desf. + { clear - n2 NINIT1. + desf. } + split. + { apply wf_threads in INE1. + { unfold tid in INE1. + apply TSET in INE1. + exfalso. desf. } + apply INV'. } + unfold Events.index in *. + lia. } + { unfold not in n2, n0. + apply NNPP in n2, n0. + unfold ext_sb. desf. + { clear - n2 NINIT1. + desf. } + split. + { unfold tid in n2, n0; vauto. } + unfold Events.index in *. + lia. } + { unfold not in n0. + apply NNPP in n0. + unfold ext_sb. desf. + unfold ext_sb in PTH. desf. + exfalso. unfold Events.index in *. + apply wf_threads in INE2. + { unfold tid in INE2. + apply TSET in INE2. + exfalso. desf. } + apply INV'. } + { unfold not in n0, n3. + apply NNPP in n0, n3. + unfold ext_sb. desf. + unfold tid in *. + unfold Events.index in *. + split; vauto. + unfold ext_sb in PTH. + destruct PTH as [EQ IND]. + desf. } + unfold not in n0, n3. + apply NNPP in n0, n3. + unfold ext_sb. desf. + { unfold tid in *. + clear - n0 NINIT1. desf. } + { unfold tid in *. + clear - n3 NINIT1. desf. } + unfold tid in *. + unfold Events.index in *. + split; vauto. + unfold ext_sb in PTH. + destruct PTH as [EQ IND]. + lia. } + + assert (MAPCOMP : eq_dom E_t' (mapper_rev' ∘ mapper') id). + { unfold mapper', mapper_rev'. + unfold eq_dom. intros x INE. + unfold compose. desf; vauto. + { exfalso. + apply n. unfold set_collect. + exists x; split; vauto. + unfold mapper'. desf; vauto. } + { unfold not in n0. apply NNPP in n0. + unfold tid in *. + apply wf_threads in INE; vauto. + { apply TSET in INE. + exfalso. desf. } + apply INV'. } + { unfold not in n0. apply NNPP in n0. + clear - n0 INE TSET T2NOTIN INV'. + apply wf_threads in INE; vauto. + { exfalso. apply TSET in INE. + desf. } + apply INV'. } + unfold not in n0, n2. apply NNPP in n0, n2. + clear - n0 n2 n3 THRDNEQ NINIT1. + destruct x. + { clear - n2 NINIT1. + exfalso; desf. } + unfold Events.index in *. + unfold tid in n0. subst. + unfold id. + assert (HLP : (t_1_len + (index - t_1_len)) = index). + { lia. } + basic_solver. } + assert (MAPREVCOMP : eq_dom (acts_set G_s') (mapper' ∘ mapper_rev') id). + { intros x COND. + unfold G_s' in COND; ins. + destruct COND as [x0 [INE MAP]]. + rewrite <- MAP. unfold compose in *. + rewrite MAPCOMP; vauto. } + + assert (SIMRELQ : seq_simrel X_s' X_t' t_1 t_2 + mapper' mapper_rev' ptc_1). + + { constructor; vauto. + { unfold inj_dom. intros x y INX INY MAP. + unfold mapper' in MAP. desf; vauto. + { apply wf_threads in INX. + { unfold tid in INX. + apply TSET in INX. + exfalso. desf. } + apply INV'. } + { apply wf_threads in INX. + { unfold tid in INX. + apply TSET in INX. + exfalso. desf. } + apply INV'. } + { apply wf_threads in INY. + { unfold tid in INY. + apply TSET in INY. + exfalso. desf. } + apply INV'. } + { apply wf_threads in INY. + { unfold tid in INY. + apply TSET in INY. + exfalso. desf. } + apply INV'. } + destruct x, y. + { clear - n0 n3 NINIT1. + unfold not in n0, n3. apply NNPP in n0, n3. + desf. } + { clear - n0 n3 NINIT1. + unfold not in n0, n3. apply NNPP in n0, n3. + desf. } + { clear - n0 n3 NINIT1. + unfold not in n0, n3. apply NNPP in n0, n3. + destruct n3. desf. } + clear - n0 n3 n1 n4 H0. + unfold not in n0, n3. + apply NNPP in n0, n3. + unfold tid in n0, n3. + assert (INDEQ : index = index0). + { unfold Events.index in *. lia. } + basic_solver. } + { intros e INE TIDE. + unfold mapper' in TIDE. + desf. + { unfold mapper'. desf. } + unfold mapper'. desf; vauto. } + { intros e INE TIDE. + unfold mapper' in TIDE. + desf. + { assert (FLSTID : threads_set G_t' (tid e)). + { apply wf_threads in INE; vauto. + apply INV'. } + clear - FLSTID TSET T2NOTIN. + exfalso. apply TSET in FLSTID. + basic_solver. } + { assert (FLSTID : threads_set G_t' (tid e)). + { apply wf_threads in INE; vauto. + apply INV'. } + unfold not in n0. + apply NNPP in n0. + rewrite n0 in FLSTID. + apply TSET in FLSTID. + clear - FLSTID T2NOTIN n0. + exfalso. desf. } + clear - n0. + unfold not in n0. + apply NNPP in n0. + desf. } + { unfold X_s'; ins. + arewrite ((fun x : actid => + ifP ~ (mapper' ↑₁ E_t') x then x + else (ifP tid x <> t_2 then x + else + ThreadEvent t_1 + (t_1_len + index x))) = mapper_rev'). + clear - MAPCOMP. + unfold eq_dom in *. + intros x INE. unfold compose. + apply MAPCOMP in INE. + unfold compose in INE. + rewrite INE. basic_solver. } + { unfold X_s'; ins. + clear - MAPCOMP. + unfold eq_dom in *. + split. + { intros x INE. unfold set_collect. + exists (mapper' x); split; vauto. + apply MAPCOMP in INE. + basic_solver 8. } + intros x INE. unfold set_collect in INE. + destruct INE as [x0 [EQ MAP1]]. + destruct EQ as [x1 [EQ MAP2]]. + subst. + assert (EQ' : E_t' x1) by vauto. + apply MAPCOMP in EQ. + unfold compose in EQ. + rewrite EQ. basic_solver. } + { unfold po_seq. + arewrite (WCore.G X_s' = G_s'). + unfold G_s' at 2. simpls. + split. + { apply inclusion_union_l. + { unfold sb. unfold G_s'; ins. + rewrite <- collect_rel_eqv. + intros x y PTH. + destruct PTH as [x0 [E1 [xm [PTH E2]]]]. + destruct E1 as [x2 [x3 [[EQ1 INE1] [M1 M2]]]]; subst. + destruct E2 as [x4 [x5 [[EQ2 INE2] [M3 M4]]]]; subst. + unfold collect_rel. + exists x3, x5; split; vauto. + unfold seq. exists x3; split; vauto. + exists x5; split; vauto. + apply EXTSBL; vauto. } + intros x y PTH. + destruct PTH as [[T1 [x0 [EQ1 M1]]] + [T2 [x1 [EQ2 M2]]]]. + unfold collect_rel. + exists x0, x1; split; vauto. + unfold sb. unfold seq. + exists x0; split; vauto. + exists x1; split; vauto. + unfold ext_sb. desf. + { unfold mapper' in M2. desf. + unfold not in n0. + apply NNPP in n0. + unfold tid in *. + clear - n0 NINIT1. desf. } + { unfold mapper' in M2. desf. + unfold not in n0. + apply NNPP in n0. + unfold tid in *. + clear - n0 NINIT1. desf. } + unfold mapper' in M2. desf. + { unfold mapper' in T1. desf. + unfold not in n2. + apply NNPP in n2. + unfold tid in *. + apply wf_threads in EQ2; vauto. + { apply TSET in EQ2. + unfold tid in EQ2. + desf. } + apply INV'. } + { unfold mapper' in T1. desf. + { unfold not in n0, n2. + apply NNPP in n0, n2. + unfold tid in *. desf. } + unfold not in n0, n2. + apply NNPP in n0, n2. + unfold tid in *. desf. } + unfold mapper' in T1. desf. + { unfold not in n0, n2. + apply NNPP in n0, n2. + unfold tid in *. desf. + split; vauto. unfold Events.index in *. + lia. } + unfold not in n0, n2. + apply NNPP in n0, n2. + unfold tid in *. desf. } + intros x y PTH. + destruct PTH as [x0 [x1 [SB [M1 M2]]]]. + unfold sb in SB. + destruct SB as [x2 [[EQ1 INE1] + [x3 [PTH [EQ2 INE2]]]]]; subst. + destruct x2. + { unfold mapper' at 3. + desf. all : left. + { unfold sb, G_s'; simpl. + unfold seq; exists (InitEvent l); split; vauto. + { red; split; vauto. + unfold set_collect. + exists (InitEvent l); split; vauto. + unfold mapper'. desf; vauto. } + exists (mapper' x1); split; vauto. + unfold ext_sb. desf. + unfold mapper' in Heq. desf. } + { unfold sb, G_s'; simpl. + unfold seq; exists (InitEvent l); split; vauto. + { red; split; vauto. + unfold set_collect. + exists (InitEvent l); split; vauto. + unfold mapper'. desf; vauto. } + exists (mapper' x1); split; vauto. + unfold ext_sb. desf. + unfold mapper' in Heq. desf. } + unfold not in n0. + apply NNPP in n0. + unfold tid in *. + clear - n0 NINIT1. + symmetry in n0. desf. } + destruct x1. + { unfold ext_sb in PTH; vauto. } + unfold ext_sb in PTH. + destruct PTH as [THRD IND]; subst. + destruct classic with (thread0 = t_1) as [THRD1 | THRD1]. + { destruct classic with (index < t_1_len) as [IND1 | IND1]. + { destruct classic with (index0 < t_1_len) as [IND2 | IND2]. + { unfold mapper'. subst; ins. + left. desf. + unfold sb. + unfold G_s'; ins. + unfold seq. exists (ThreadEvent t_1 index); split; vauto. + { red. split; vauto. + unfold set_collect. + exists (ThreadEvent t_1 index); split; vauto. + unfold mapper'. desf; vauto. } + exists (ThreadEvent t_1 index0); split; vauto. + red. split; vauto. + unfold set_collect. + exists (ThreadEvent t_1 index0); split; vauto. + unfold mapper'. desf; vauto. } + subst. right. unfold mapper' at 3 4. + unfold tid, Events.index. + unfold tid in *. + desf. split; split; vauto. + { unfold set_collect. + exists (ThreadEvent t_1 index); split; vauto. + unfold mapper'. desf; vauto. } + unfold set_collect. + exists (ThreadEvent t_1 index0); split; vauto. + unfold mapper'. desf; vauto. } + destruct classic with (index0 < t_1_len) as [IND2 | IND2]. + { exfalso. clear - IND IND1 IND2. + apply IND1. lia. } + left. desf. + unfold sb. unfold G_s'; ins. + unfold seq. exists (ThreadEvent t_2 (index - t_1_len)); split. + { apply collect_rel_eqv. + unfold collect_rel. + exists (ThreadEvent t_1 index), + (ThreadEvent t_1 index); splits; vauto. + unfold mapper'. desf. } + exists (ThreadEvent t_2 (index0 - t_1_len)); split. + { clear - IND IND1 IND2. + unfold ext_sb; splits; vauto. + lia. } + apply collect_rel_eqv. + unfold collect_rel. + exists (ThreadEvent t_1 index0), + (ThreadEvent t_1 index0); splits; vauto. + unfold mapper'. unfold tid. + desf. } + left. + unfold sb. unfold G_s'; ins. + unfold seq. exists (ThreadEvent thread0 index); splits; vauto. + { apply collect_rel_eqv. + unfold collect_rel. + exists (ThreadEvent thread0 index), + (ThreadEvent thread0 index); splits; vauto. + unfold mapper'. + desf. } + exists (ThreadEvent thread0 index0); splits; vauto. + apply collect_rel_eqv. + unfold collect_rel. + exists (ThreadEvent thread0 index0), + (ThreadEvent thread0 index0); splits; vauto. + unfold mapper'. + desf. } + { arewrite (WCore.G X_s' = G_s'). + unfold G_s'; ins. rewrite <- TSET. + apply SIMREL. } + { unfold fixset. intros e INIT. + unfold mapper'. + desf. + unfold not in n0. + apply NNPP in n0. + clear - n0 NINIT1 INIT. + unfold is_init in INIT. + exfalso. desf. } + { unfold fixset. intros e INIT. + unfold mapper_rev'. + desf. + unfold not in n0. + apply NNPP in n0. + clear - n0 NINIT2 INIT. + unfold is_init in INIT. + exfalso. desf. } + { intros e INE TID2. + unfold mapper'. + desf; vauto. + unfold mapper' in TID2. + unfold not in n0. + apply NNPP in n0. + desf. } + { arewrite (WCore.G X_s' = G_s'). + intros e INE TID2. + unfold mapper_rev'. + desf; vauto. } + { intros e INE TID2. + unfold mapper'. desf. + { unfold mapper' in TID2. + desf. + apply wf_threads in INE. + { clear - INE T2NOTIN TSET. + apply TSET in INE. + exfalso. desf. } + apply INV'. } + unfold mapper' in TID2. + desf. + unfold not in n0, n2. + apply NNPP in n0, n2. + apply wf_threads in INE. + { clear - INE T2NOTIN TSET. + apply TSET in INE. + exfalso. desf. } + apply INV'. } + { intros e INE TID2. + unfold mapper'. desf. + { unfold mapper' in TID2. + desf. + apply wf_threads in INE. + { clear - INE T2NOTIN TSET. + apply TSET in INE. + exfalso. desf. } + apply INV'. } + { unfold mapper' in TID2. + desf. + unfold not in n0, n2. + apply NNPP in n0, n2. + apply wf_threads in INE. + { clear - INE T2NOTIN TSET. + apply TSET in INE. + exfalso. desf. } + apply INV'. } + unfold mapper' in TID2. + desf. + unfold not in n0, n3. + apply NNPP in n0, n3. + unfold index in *. + unfold t_1_len in *. unfold SequentBase.t_1_len. + desf. unfold tid in *. + lia. } + { intros e INE COND. + unfold mapper' in COND. desf. + { apply wf_threads in INE. + { exfalso. apply TSET in INE. desf. } + apply INV'. } + { unfold not in n0. + apply NNPP in n0; vauto. } + unfold not in n0. + apply NNPP in n0; vauto. } + { intros e INE COND. + unfold mapper_rev'. desf. + unfold t_1_len, SequentBase.t_1_len. + apply INDLEMMA; vauto. + unfold index. desf. + lia. } + { intros e NINE. + unfold mapper'; desf. } + { intros e INE TID. + unfold mapper'. + desf; vauto. } + { intros e INE TID IND. + unfold mapper'. + desf; vauto. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. lia. } + { intros e NINE. + unfold mapper'; desf. } + intros e NINE. + unfold mapper_rev'; desf. } + split; red. + { apply SIMRELQ. } + + assert (MAPS : forall x y, E_t' x -> E_t y -> + mapper' x = mapper y -> x = y). + { unfold mapper'. ins; desf. + { destruct classic with (tid (mapper y) = t_2) as [TID2 | TID2]. + 2: { apply (seq_mapeq SIMREL) in TID2; vauto. } + apply wf_threads in H. + { rewrite TID2 in H. + apply TSET in H. + exfalso. desf. } + apply INV'. } + { apply (seq_mapeq SIMREL); vauto. + clear - n0 THRDNEQ. + intros FLS. unfold not in n0. + apply n0. desf. intros FLS'. + desf. } + destruct classic with (tid (mapper y) = t_2) as [TID2 | TID2]. + 2: { rewrite <- H1 in TID2. desf. } + apply NNPP in n0. + apply INDLEMMA. + { rewrite n0; vauto. } + { apply (seq_thrd SIMREL) in TID2; vauto. + rewrite TID2; vauto. } + apply (seq_index SIMREL) in TID2; vauto. + rewrite <- H1 in TID2. + simpl in *. unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + lia. } + + assert (RPOIN : rpo G_s' ⊆ mapper' ↑ rpo_t'). + { unfold rpo. unfold rpo_imm. + destruct SIMRELQ. + assert (RESTR : ⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ sb_t' ⨾ ⦗F G_t' ∩₁ Acq G_t'⦘ ∪ ⦗Acq G_t'⦘ ⨾ sb_t' ∪ sb_t' ⨾ ⦗Rel G_t'⦘ + ∪ ⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ sb_t' ⨾ ⦗W_t' ∩₁ Rlx G_t'⦘ ≡ restr_rel E_t' ( + ⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ sb_t' ⨾ ⦗F G_t' ∩₁ Acq G_t'⦘ ∪ ⦗Acq G_t'⦘ ⨾ sb_t' ∪ sb_t' ⨾ ⦗Rel G_t'⦘ + ∪ ⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ sb_t' ⨾ ⦗W_t' ∩₁ Rlx G_t'⦘)). + { split. + { rewrite !restr_union. + repeat apply union_mori. + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] [x1 [COND [EQ2 CD2]]]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] COND]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + { intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x1 [COND [EQ2 CD2]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + intros x y COND. + unfold restr_rel; split; vauto. + destruct COND as [x0 [[EQ1 CD1] [x1 [COND [EQ2 CD2]]]]]; subst. + apply wf_sbE in COND. + clear - COND. destruct COND as [x2 [[EQ1 CD1] [x3 [COND [EQ2 CD2]]]]]; subst. + basic_solver. } + rewrite inclusion_restr; vauto. } + rewrite RESTR. + rewrite collect_rel_ct_inj. + { assert (SBIN : sb G_s' ⊆ mapper' ↑ sb_t'). + { rewrite <- seq_sb; vauto. } + apply clos_trans_mori. + rewrite <- RESTR. + rewrite !collect_rel_union. + repeat apply union_mori. + { rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + arewrite (⦗R_t' ∩₁ Rlx G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (F G_t' ∩₁ Acq G_t')⦘ ≡ + ⦗R_t' ∩₁ Rlx G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (F G_t' ∩₁ Acq G_t')⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [[ISR ISRLX] INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rlx, mod in ISRLX. + rewrite seq_lab_rev in ISRLX; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_r. unfold compose in ISRLX; vauto. } + { unfold is_rlx. unfold compose in ISRLX; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE [ISF ISA]]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_acq, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + { unfold is_r. unfold compose in ISA; vauto. } + unfold is_rlx. unfold compose in ISA; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + { rewrite wf_sbE. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + arewrite (⦗Acq G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t'⦘ ≡ + ⦗Acq G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t'⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [ISA INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_acq, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_acq. unfold compose in ISA; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ INE]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + { rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ INE]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE ISR]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rel, mod in ISR. + rewrite seq_lab_rev in ISR; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + unfold is_rel. unfold compose in ISR; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. rewrite !seqA. + rewrite <- id_inter. + rewrite <- seqA. + rewrite <- id_inter. + rewrite SBIN. + rewrite wf_sbE at 2. + rewrite !seqA. + rewrite <- id_inter. + arewrite (⦗F G_t' ∩₁ Rel G_t'⦘ ⨾ ⦗E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (W_t' ∩₁ Rlx G_t')⦘ ≡ + ⦗F G_t' ∩₁ Rel G_t' ∩₁ E_t'⦘ ⨾ sb_t' ⨾ ⦗E_t' ∩₁ (W_t' ∩₁ Rlx G_t')⦘). + { rewrite <- seqA. + rewrite <- id_inter; vauto. } + rewrite !collect_rel_seq. + { repeat apply seq_mori; vauto. + { intros x y COND. + destruct COND as [EQ [[ISF ISREL] INE]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rel, mod in ISREL. + rewrite seq_lab_rev in ISREL; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { unfold is_r. unfold compose in ISREL; vauto. } + { unfold is_rlx. unfold compose in ISREL; vauto. } + apply seq_acts_rev; red; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + intros x y COND. + destruct COND as [EQ [INE [ISF ISA]]]; subst. + assert (SUB : G_s' = WCore.G X_s') by vauto. + rewrite SUB in *. + unfold is_rlx, mod in ISA. + rewrite seq_lab_rev in ISA; vauto. + red. exists (mapper_rev' y), (mapper_rev' y); splits. + { red; split; vauto. + repeat split. + { apply seq_acts_rev; red; vauto. } + { unfold is_r. unfold compose in ISA; vauto. } + unfold is_rlx. unfold compose in ISA; vauto. } + { unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + unfold compose in MAPREVCOMP. + rewrite MAPREVCOMP; vauto. } + { rewrite wf_sbE. + rewrite !codom_seq. + clear - seq_inj. + basic_solver 8. } + rewrite wf_sbE. + clear - seq_inj. + basic_solver 8. } + vauto. } + + assert (SBSEQ : sb (WCore.G X_s') ≡ mapper' ↑ sb_t' \ po_seq X_s' t_1 t_2). + { destruct SIMRELQ. + assert (HLP : (sb (WCore.G X_s') ∪ po_seq X_s' t_1 t_2) + \ po_seq X_s' t_1 t_2 ≡ mapper' ↑ sb_t' \ po_seq X_s' t_1 t_2). + { apply minus_rel_more; vauto. } + rewrite <- HLP. + rewrite minus_union_l. + rewrite minusK. + rewrite minus_disjoint; [basic_solver |]. + split; vauto. + intros x y COND. + destruct COND as [COND1 COND2]. + unfold po_seq in COND2. + destruct COND2 as [[TID1 IN1] [TID2 IN2]]. + unfold sb in COND1. + destruct COND1 as [x0 [[EQ1 INE1] [x1 [COND [EQ2 INE2]]]]]. + subst x0 x1. + unfold ext_sb in COND. + desf. + { unfold tid in TID1. apply NINIT1; vauto. } + unfold tid in *. desf. } + + assert (WFSTART : WCore.wf (WCore.X_start X_s dtrmt') X_s' cmt'). + { constructor; ins. + { apply sub_WF with (G := G_s) (sc := ∅₂) (sc' := ∅₂). + { ins. + assert (INITDER : (fun a : actid => is_init a) ⊆₁ dtrmt_t). + { destruct STEP; vauto. } + arewrite ((fun a : actid => is_init a) ⊆₁ mapper' ↑₁ + (fun a : actid => is_init a)). + { destruct SIMRELQ. clear- seq_init. + unfold fixset in seq_init. + basic_solver. } + rewrite INITDER. + unfold dtrmt'; vauto. } + { apply wf_transition with (X_t := X_t) + (t_1 := t_1) (t_2 := t_2) + (mapper := mapper) (mapper_rev := mapper_rev) + (ptc_1 := ptc_1); vauto. } + apply restrict_sub; [basic_solver |]. + unfold dtrmt'. + destruct SIMREL. + rewrite seq_acts. + intros x COND. + unfold set_collect in COND. + destruct COND as [x0 [COND EQ]]. + unfold set_collect. + exists x0; split; vauto. + { destruct STEP. + apply rexec_acts; vauto. } + destruct classic with (tid (mapper + x0) = t_2) as [TID2 | TID2]. + { assert (TID2' : tid (mapper x0) = t_2) by vauto. + assert (TID2S : tid (mapper x0) = t_2) by vauto. + apply seq_index in TID2. + apply seq_thrd in TID2'. + { apply INDLEMMA. + { unfold mapper'. desf. } + { unfold mapper'. + rewrite TID2S. clear TID2S. + desf. + { destruct STEP. + apply dtrmt_cmt in COND. + apply reexec_embd_dom in COND; vauto. } + symmetry in TID2. + rewrite <- TID2 in l. + exfalso. unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + unfold mapper'. + rewrite TID2. clear TID2. + desf. + { destruct STEP. + apply dtrmt_cmt in COND. + apply reexec_embd_dom in COND; vauto. } + { exfalso. unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + unfold Events.index in *. + unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + lia. } + { destruct STEP. apply rexec_acts; vauto. } + destruct STEP. apply rexec_acts; vauto. } + assert (TID2' : tid (mapper x0) <> t_2) by vauto. + assert (TID2S : tid (mapper x0) <> t_2) by vauto. + apply seq_mapeq in TID2. + { rewrite TID2. clear TID2. + unfold mapper'. desf. + apply INDLEMMA. + { unfold not in n0. + apply NNPP in n0. + rewrite n0; vauto. } + { unfold tid. + unfold not in n0. + apply NNPP in n0. + apply seq_out_move in n0; vauto. + { apply seq_mapeq in TID2S; vauto. + rewrite TID2S in n0. + desf. + destruct STEP. apply rexec_acts; vauto. } + { destruct STEP. apply rexec_acts; vauto. } + unfold Events.index in *. + unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + lia. } + unfold Events.index in *. + unfold not in n0. + apply NNPP in n0. + apply seq_out_move in n0; vauto. + { apply seq_mapeq in TID2S; vauto. + { rewrite TID2S in n0. + desf. } + destruct STEP. apply rexec_acts; vauto. } + { destruct STEP. apply rexec_acts; vauto. } + unfold Events.index in *. + unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + lia. } + destruct STEP. apply rexec_acts; vauto. } + { constructor. + { unfold WCore.X_start; ins. + destruct SIMRELQ. + unfold dtrmt'. + unfold cmt'. + rewrite <- !set_interA. + split. + { arewrite (mapper' ↑₁ dtrmt_t ⊆₁ mapper' ↑₁ E_t'). + apply set_subset_collect. + { destruct STEP. + rewrite dtrmt_cmt. + rewrite reexec_embd_dom; vauto. } + clear. basic_solver 8. } + clear. basic_solver 8. } + { unfold WCore.X_start; ins. } + { unfold WCore.X_start; ins. + arewrite ((fun x : actid => + ifP ~ (mapper' ↑₁ E_t') x then x + else (ifP tid x <> t_2 then x + else ThreadEvent t_1 + (t_1_len + index x))) = mapper_rev'). + unfold eq_dom. intros x COND. + destruct SIMREL. + rewrite seq_lab_rev. + { destruct STEP. + destruct reexec_start_wf. + destruct wf_ereq. + unfold compose. + rewrite <- ereq_lab. + { unfold WCore.X_start; ins. + assert (EQQ: mapper_rev x = mapper_rev' x). + { unfold mapper_rev'. desf. + { apply seq_rest_rev. + clear - n COND reexec_embd_dom. + destruct n. + unfold cmt' in COND. + destruct COND as [CND [x0 [IN1 IN2]]]. + unfold set_collect. + exists x0; split; vauto. + apply reexec_embd_dom; vauto. } + { apply NNPP in n. + apply seq_mapeq_rev; vauto. + clear - COND. + destruct COND as [[DTT ES] RST]; vauto. } + unfold not in n0. + apply NNPP in n0. + rewrite seq_maprev; vauto. + { apply INDLEMMA; vauto. + unfold index. + unfold SequentBase.t_1_len, t_1_len. + lia. } + destruct COND as [[DTT ES] RST]; vauto. } + rewrite EQQ; vauto. } + unfold WCore.X_start; ins. + destruct COND as [[DTT ES] RST]. + apply seq_acts in ES. + unfold dtrmt', cmt' in *. + split. + { split. + { destruct DTT as [x0 [DTT M1]]. + rewrite <- M1. + unfold compose in MAPCOMP. + rewrite MAPCOMP; vauto. + apply dtrmt_cmt in DTT. + apply reexec_embd_dom in DTT; vauto. } + destruct DTT as [x1 [DTT M1]]. + rewrite <- M1. + unfold compose in MAPCOMP. + rewrite MAPCOMP. + { apply rexec_acts; vauto. } + apply dtrmt_cmt in DTT. + apply reexec_embd_dom in DTT; vauto. } + destruct RST as [x1 [RST M1]]. + rewrite <- M1. + unfold compose in MAPCOMP. + rewrite MAPCOMP. + { unfold id; vauto. } + apply reexec_embd_dom in RST; vauto. } + destruct COND as [[DTT ES] RST]; vauto. } + { unfold WCore.X_start; ins. + destruct STEP. + destruct reexec_start_wf. + destruct wf_ereq. + split. + { intros x y COND. + unfold restr_rel in *. + destruct COND as [CD1 [CD2 CD3]]. + split; vauto. + destruct CD1 as [x0 [[EQ1 DT1] + [x1 [RF [EQ2 DT2]]]]]; subst. + destruct ereq_rf as [IN OUT]. + destruct DT1 as [x2 [DT1 M1]]. + destruct DT2 as [x3 [DT2 M2]]. + destruct IN with x2 x3. + { unfold WCore.X_start; ins. + apply (seq_rf SIMREL) in RF. + unfold collect_rel in RF. + destruct RF as [x5 [x6 [RF [EQ3 EQ4]]]]. + splits. + { unfold seq. + exists x2; split; vauto. + exists x3; split; vauto. + assert (EQQ1 : x5 = x2). + { assert (MEQ : mapper' x2 = mapper x2). + { apply DTRSAME in DT1; vauto. } + rewrite MEQ in EQ3. + apply (seq_inj SIMREL) in EQ3; vauto. + { apply wf_rfE in RF; [|apply INV]. + destruct RF as [x4 [[INE EQQ] RF2]]; vauto. } + apply rexec_acts; vauto. } + assert (EQQ2 : x6 = x3). + { assert (MEQ : mapper' x3 = mapper x3). + { apply DTRSAME in DT2; vauto. } + rewrite MEQ in M2. + apply (seq_inj SIMREL) in M2; vauto. + { apply rexec_acts; vauto. } + apply wf_rfE in RF; [|apply INV]. + destruct RF as [x4 [[INE EQQ] + [x7 [RF [EQR INER]]]]]; vauto. } + subst; vauto. } + { split. + { split; vauto. + apply rexec_acts; vauto. } + apply dtrmt_cmt in DT1; vauto. } + split. + { split; vauto. + apply rexec_acts; vauto. } + apply dtrmt_cmt in DT2; vauto. } + unfold collect_rel. + exists x2, x3; splits; vauto. } + intros x y COND. + unfold restr_rel in *. + destruct COND as [CD1 [CD2 CD3]]. + destruct CD1 as [x0 [x1 [CDD [M1 M2]]]]. + splits. + { unfold seq. exists x; split. + { red; split; vauto. + destruct CD2 as [[CD1 CD2] CD4]; vauto. } + exists y; split. + { apply (seq_rf SIMREL). + destruct ereq_rf as [IN OUT]. + unfold collect_rel. + exists x0, x1; splits; vauto. + { destruct OUT with x0 x1. + { split; vauto. + unfold WCore.X_start; ins. split. + { split. + { split. + { destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rfE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] RF2]]; vauto. } + destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { apply rexec_acts. + subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rfE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] RF2]]; vauto. } + destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. + apply dtrmt_cmt in DTT1; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rfE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] RF2]]; vauto. } + split. + { split. + { destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rfE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { apply rexec_acts. + subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rfE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. + apply dtrmt_cmt in DTT1; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rfE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + unfold WCore.X_start in H; ins. + destruct H as [x2 [[EQ1 DT1] [x3 [RF [EQ2 DT2]]]]]. + subst; vauto. } + { destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst. + apply DTRSAME; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rfE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst. + apply DTRSAME; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rfE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + red; split; vauto. + destruct CD3 as [[CD1 CD3] CD4]; vauto. } + all : vauto. } + { unfold WCore.X_start; ins. + destruct STEP. + destruct reexec_start_wf. + destruct wf_ereq. + split. + { intros x y COND. + unfold restr_rel in *. + destruct COND as [CD1 [CD2 CD3]]. + split; vauto. + destruct CD1 as [x0 [[EQ1 DT1] + [x1 [RF [EQ2 DT2]]]]]; subst. + destruct ereq_co as [IN OUT]. + destruct DT1 as [x2 [DT1 M1]]. + destruct DT2 as [x3 [DT2 M2]]. + destruct IN with x2 x3. + { unfold WCore.X_start; ins. + apply (seq_co SIMREL) in RF. + unfold collect_rel in RF. + destruct RF as [x5 [x6 [RF [EQ3 EQ4]]]]. + splits. + { unfold seq. + exists x2; split; vauto. + exists x3; split; vauto. + assert (EQQ1 : x5 = x2). + { assert (MEQ : mapper' x2 = mapper x2). + { apply DTRSAME in DT1; vauto. } + rewrite MEQ in EQ3. + apply (seq_inj SIMREL) in EQ3; vauto. + { apply wf_coE in RF; [|apply INV]. + destruct RF as [x4 [[INE EQQ] RF2]]; vauto. } + apply rexec_acts; vauto. } + assert (EQQ2 : x6 = x3). + { assert (MEQ : mapper' x3 = mapper x3). + { apply DTRSAME in DT2; vauto. } + rewrite MEQ in M2. + apply (seq_inj SIMREL) in M2; vauto. + { apply rexec_acts; vauto. } + apply wf_coE in RF; [|apply INV]. + destruct RF as [x4 [[INE EQQ] + [x7 [RF [EQR INER]]]]]; vauto. } + subst; vauto. } + { split. + { split; vauto. + apply rexec_acts; vauto. } + apply dtrmt_cmt in DT1; vauto. } + split. + { split; vauto. + apply rexec_acts; vauto. } + apply dtrmt_cmt in DT2; vauto. } + unfold collect_rel. + exists x2, x3; splits; vauto. } + intros x y COND. + unfold restr_rel in *. + destruct COND as [CD1 [CD2 CD3]]. + destruct CD1 as [x0 [x1 [CDD [M1 M2]]]]. + splits. + { unfold seq. exists x; split. + { red; split; vauto. + destruct CD2 as [[CD1 CD2] CD4]; vauto. } + exists y; split. + { apply (seq_co SIMREL). + destruct ereq_co as [IN OUT]. + unfold collect_rel. + exists x0, x1; splits; vauto. + { destruct OUT with x0 x1. + { split; vauto. + unfold WCore.X_start; ins. split. + { split. + { split. + { destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_coE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] RF2]]; vauto. } + destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { apply rexec_acts. + subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_coE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] RF2]]; vauto. } + destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. + apply dtrmt_cmt in DTT1; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_coE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] RF2]]; vauto. } + split. + { split. + { destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_coE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { apply rexec_acts. + subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_coE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. + apply dtrmt_cmt in DTT1; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_coE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + unfold WCore.X_start in H; ins. + destruct H as [x2 [[EQ1 DT1] [x3 [RF [EQ2 DT2]]]]]. + subst; vauto. } + { destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst. + apply DTRSAME; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_coE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst. + apply DTRSAME; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_coE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + red; split; vauto. + destruct CD3 as [[CD1 CD3] CD4]; vauto. } + all : vauto. } + { unfold WCore.X_start; ins. + destruct STEP. + destruct reexec_start_wf. + destruct wf_ereq. + split. + { intros x y COND. + unfold restr_rel in *. + destruct COND as [CD1 [CD2 CD3]]. + split; vauto. + destruct CD1 as [x0 [[EQ1 DT1] + [x1 [RF [EQ2 DT2]]]]]; subst. + destruct ereq_rmw as [IN OUT]. + destruct DT1 as [x2 [DT1 M1]]. + destruct DT2 as [x3 [DT2 M2]]. + destruct IN with x2 x3. + { unfold WCore.X_start; ins. + apply (seq_rmw SIMREL) in RF. + unfold collect_rel in RF. + destruct RF as [x5 [x6 [RF [EQ3 EQ4]]]]. + splits. + { unfold seq. + exists x2; split; vauto. + exists x3; split; vauto. + assert (EQQ1 : x5 = x2). + { assert (MEQ : mapper' x2 = mapper x2). + { apply DTRSAME in DT1; vauto. } + rewrite MEQ in EQ3. + apply (seq_inj SIMREL) in EQ3; vauto. + { apply wf_rmwE in RF; [|apply INV]. + destruct RF as [x4 [[INE EQQ] RF2]]; vauto. } + apply rexec_acts; vauto. } + assert (EQQ2 : x6 = x3). + { assert (MEQ : mapper' x3 = mapper x3). + { apply DTRSAME in DT2; vauto. } + rewrite MEQ in M2. + apply (seq_inj SIMREL) in M2; vauto. + { apply rexec_acts; vauto. } + apply wf_rmwE in RF; [|apply INV]. + destruct RF as [x4 [[INE EQQ] + [x7 [RF [EQR INER]]]]]; vauto. } + subst; vauto. } + { split. + { split; vauto. + apply rexec_acts; vauto. } + apply dtrmt_cmt in DT1; vauto. } + split. + { split; vauto. + apply rexec_acts; vauto. } + apply dtrmt_cmt in DT2; vauto. } + unfold collect_rel. + exists x2, x3; splits; vauto. } + intros x y COND. + unfold restr_rel in *. + destruct COND as [CD1 [CD2 CD3]]. + destruct CD1 as [x0 [x1 [CDD [M1 M2]]]]. + splits. + { unfold seq. exists x; split. + { red; split; vauto. + destruct CD2 as [[CD1 CD2] CD4]; vauto. } + exists y; split. + { apply (seq_rmw SIMREL). + destruct ereq_rmw as [IN OUT]. + unfold collect_rel. + exists x0, x1; splits; vauto. + { destruct OUT with x0 x1. + { split; vauto. + unfold WCore.X_start; ins. split. + { split. + { split. + { destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rmwE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] RF2]]; vauto. } + destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { apply rexec_acts. + subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rmwE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] RF2]]; vauto. } + destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. + apply dtrmt_cmt in DTT1; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rmwE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] RF2]]; vauto. } + split. + { split. + { destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rmwE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { apply rexec_acts. + subst; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rmwE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst; vauto. + apply dtrmt_cmt in DTT1; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rmwE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + unfold WCore.X_start in H; ins. + destruct H as [x2 [[EQ1 DT1] [x3 [RF [EQ2 DT2]]]]]. + subst; vauto. } + { destruct CD2 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst. + apply DTRSAME; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rmwE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + destruct CD3 as [[[x2 [DTT1 MP1]] ES] + [x3 [CMT1 MP2]]]. + apply (seq_inj SIMRELQ) in MP1. + { subst. + apply DTRSAME; vauto. } + { apply dtrmt_cmt in DTT1. + apply reexec_embd_dom in DTT1; vauto. } + apply wf_rmwE in CDD; [|apply INV']. + destruct CDD as [x4 [[INE EQQ] + [x5 [RF [INE2 EQ2]]]]]; vauto. } + red; split; vauto. + destruct CD3 as [[CD1 CD3] CD4]; vauto. } + all : vauto. } + { unfold WCore.X_start; ins. + rewrite (seq_data SIMREL). + clear; basic_solver 8. } + { unfold WCore.X_start; ins. + rewrite (seq_ctrl SIMREL). + clear; basic_solver 8. } + unfold WCore.X_start; ins. + rewrite (seq_rmw_dep SIMREL). + clear; basic_solver 8. } + { unfold rf_complete. + unfold restrict; ins. + arewrite ((fun x : actid => + ifP ~ (mapper' ↑₁ E_t') x + then x + else (ifP tid x <> t_2 then x + else ThreadEvent t_1 + (t_1_len + + index x))) = mapper_rev'). + destruct STEP. + intros x COND. + destruct COND as [[CD2 CD3] CD1]. + destruct CD2 as [x0 [CM MP]]. + destruct reexec_start_wf. + destruct wf_rfc with x0. + { split. + { unfold restrict; ins. + split; vauto. + apply reexec_embd_dom in CM; vauto. } + unfold restrict; ins. + unfold compose in CD1. + unfold is_r in *. + rewrite <- MP in CD1. + unfold compose in MAPCOMP. + rewrite MAPCOMP in CD1. + { unfold id in CD1; vauto. } + apply reexec_embd_dom in CM; vauto. } + unfold restrict in H; ins. + unfold codom_rel. + exists (mapper' x1). + unfold seq. exists (mapper' x1); split. + { red. split; vauto. + destruct H as [x2 [[EQQ CMM] MP]]; subst. + unfold cmt'. + unfold set_collect. + exists x2; split; vauto. } + exists x; split; vauto. + unfold collect_rel. + exists x1, x0; splits; vauto. + destruct H as [x2 [[EQQ CMM] + [x3 [RF [CM3 EQ]]]]]; subst; vauto. } + intros x COND. + destruct COND as [[DTT ESS] RD]. + destruct DTT as [x0 [DTT MP1]]. + destruct STEP. + destruct reexec_start_wf. + destruct wf_sub_rfD with x0. + { unfold WCore.X_start; ins. + split. + { split; vauto. + apply rexec_acts; vauto. } + rewrite <- MP1 in RD. + unfold is_r in *. + destruct SIMREL. + rewrite seq_lab. + { unfold compose. + assert (COND : mapper' x0 = mapper x0). + { apply DTRSAME in DTT; vauto. } + rewrite <- COND; vauto. } + apply rexec_acts; vauto. } + { left. unfold WCore.X_start; ins. + destruct SIMREL. + destruct H as [x1 PTH]. + unfold codom_rel. exists (mapper' x1). + unfold seq. exists (mapper' x1); split. + { red. split; vauto. + unfold dtrmt'. unfold set_collect. + exists x1; split; vauto. + destruct PTH as [x2 [[EQQ CMM] MP]]; subst; vauto. } + exists x; split; vauto. + apply seq_rf. + unfold collect_rel. + exists x1, x0; splits; vauto. + { destruct PTH as [x2 [[EQQ CMM] + [x3 [RF [CM3 EQ]]]]]; subst; vauto. } + { apply DTRSAME. + destruct PTH as [x2 [[EQQ CMM] MP]]; vauto. } + apply DTRSAME. + destruct PTH as [x2 [[EQQ CMM] MP]]; vauto. } + right. + unfold cmt'. + unfold set_collect. + exists x0; split; vauto. } + + assert (RFCS : rf_complete (WCore.G X_s')). + { destruct STEP. unfold rf_complete. + arewrite (WCore.G X_s' = G_s'). + unfold G_s'. simpls. + arewrite ((fun x : actid => + ifP ~ (mapper' ↑₁ E_t') x then x + else (ifP tid x <> t_2 then x + else ThreadEvent t_1 + (t_1_len + index x))) = mapper_rev'). + unfold is_r. unfold compose. + intros x COND. + destruct COND as [MAP RD]. + destruct MAP as [x0 [MAP M1]]; subst. + unfold rf_complete in rexec_rfc. + destruct rexec_rfc with x0; vauto. + { split; vauto. + unfold compose in MAPCOMP. + apply MAPCOMP in MAP. + unfold id in MAP. + rewrite MAP in RD. + unfold is_r; vauto. } + unfold codom_rel. + exists (mapper' x). + unfold collect_rel. + exists x, x0; split; vauto. } + + assert (CONSS : WCore.is_cons (WCore.G X_s')). + { apply XmmCons.monoton_cons with (G_t := G_t') + (m := mapper'); vauto. + all : try arewrite (WCore.G X_s' = G_s'). + { apply SIMRELQ. } + { unfold G_s'; ins. + arewrite ((fun x : actid => + ifP ~ (mapper' ↑₁ E_t') x then x + else (ifP tid x <> t_2 then x + else ThreadEvent t_1 + (t_1_len + index x))) = mapper_rev'). + unfold compose. unfold eq_dom. + intros x COND. + unfold compose in MAPCOMP. + apply MAPCOMP in COND. + rewrite COND. + unfold id; vauto. } + { intros x y PTH. + destruct PTH as [SBP SL]. + unfold sb in SBP. + unfold G_s' in SBP; ins. + destruct SBP as [x0 [[EQ1 INE1] + [x1 [PTH [EQ2 INE2]]]]]; subst. + unfold collect_rel. + destruct INE1 as [x2 [INE1 M1]]. + destruct INE2 as [x3 [INE2 M2]]. + exists x2, x3; splits; vauto. + split. + { unfold sb. + unfold seq. exists x2; split; vauto. + exists x3; split; vauto. + apply EXTSBL; vauto. } + assert (MAPP : (fun x : actid => + ifP ~ (mapper' ↑₁ E_t') x then x + else (ifP tid x <> t_2 then x + else ThreadEvent t_1 + (t_1_len + index x))) = mapper_rev') by vauto. + rewrite MAPP in SL. + unfold same_loc in SL. + unfold loc in SL. + unfold compose in SL. + unfold compose in MAPCOMP. + apply MAPCOMP in INE1. + unfold id in INE1. + apply MAPCOMP in INE2. + unfold id in INE2. + rewrite INE1, INE2 in SL. + unfold same_loc, loc; vauto. } + { apply INV'. } + { arewrite (G_s' = (WCore.G X_s')). + apply wf_transition with (X_t := X_t') + (t_1 := t_1) (t_2 := t_2) + (mapper := mapper') (mapper_rev := mapper_rev') + (ptc_1 := ptc_1); vauto. } + destruct STEP; vauto. } + + assert (STURG : WCore.stable_uncmt_reads_gen X_s' cmt' thrdle'). + { constructor. + { destruct STEP. destruct reexec_sur. + unfold least_elt. intros trn INIT. + unfold thrdle'. + right. + split; vauto. + unfold least_elt in surg_init_least. + specialize (surg_init_least trn INIT). + clear - surg_init_least. + basic_solver. } + { unfold min_elt. intros trn INIT. + assert (FLS : codom_rel thrdle' tid_init). + { clear - INIT. basic_solver. } + unfold thrdle' in INIT. + apply codom_union in FLS. + destruct FLS as [FLS | FLS1]. + { apply codom_union in FLS. + destruct FLS as [FLS | FLS2]. + { apply codom_union in FLS. + destruct FLS as [FLS | FLS3]. + { apply codom_union in FLS. + destruct FLS as [FLS | FLS4]. + { destruct STEP. destruct reexec_sur. + unfold min_elt in surg_init_min. + destruct FLS as [x FLS]. + specialize (surg_init_min x). + apply surg_init_min. + vauto. } + clear - NINIT1 FLS4. + apply codom_crossed in FLS4. + desf. } + clear - NINIT2 FLS3. + apply codom_crossed in FLS3. + desf. } + apply codom_crossed in FLS2. + destruct STEP. destruct reexec_sur. + clear - FLS2 surg_init_min. + unfold min_elt in surg_init_min. + destruct FLS2 as [x FLS2]. + specialize (surg_init_min x). + apply surg_init_min. + destruct FLS2 as [x0 [EQ FLS2]]. + destruct EQ. desf. } + apply codom_crossed in FLS1. + destruct STEP. destruct reexec_sur. + clear - FLS1 surg_init_min. + unfold min_elt in surg_init_min. + destruct FLS1 as [x FLS1]. + specialize (surg_init_min x). + desf. } + { constructor. + { unfold thrdle'. + repeat (apply irreflexive_union; split). + { destruct STEP. destruct reexec_sur. + unfold strict_partial_order in surg_order. + destruct surg_order as [IRR _]; vauto. } + { clear - THRDNEQ. basic_solver. } + { intros x COND. + destruct COND as [CD1 CD2]; subst x. + destruct CD1 as [x1 [x2 [CD1 CD2]]]. + apply THRLEE in CD1. + destruct CD1 as [x3 [[EQ INE] CD3]]. + subst x3. desf. } + { intros x COND. + destruct COND as [CD1 CD2]; subst x. + destruct CD2 as [x1 [x2 [CD1 CD2]]]. + apply THRLEE in CD2. + destruct CD2 as [x3 [CD2 [x4 [CD3 [EQ INE]]]]]. + subst x4. desf. } + destruct STEP. destruct reexec_sur. + unfold min_elt in surg_init_min. + clear - surg_init_min. + intros x [EQ [y FLS]]. + specialize (surg_init_min y). + basic_solver 4. } + unfold thrdle'. unfold transitive. + intros x y z XY YZ. + destruct XY as [[[[C1 | C1] | C1] | C1] | C1]. + all : destruct YZ as [[[[C2 | C2] | C2] | C2] | C2]. + all : destruct STEP. + all : destruct reexec_sur. + all : destruct surg_order as [IR TR]. + { do 4 left. clear - C1 C2 TR. basic_solver 4. } + { destruct C2 as [EQ1 EQ2]. + subst y. apply THRLEE in C1. + destruct C1 as [x3 [CD2 [x4 [CD3 [EQ INE]]]]]. + desf. } + { do 2 left; right. + clear - C1 C2 TR. + destruct C2 as [C2 EQ]; subst z. + split; vauto. + destruct C2 as [x0 [x1 [CD2 [EQ1 EQ2]]]]; subst. + basic_solver 8. } + { destruct C2 as [EQ1 EQ2]. + subst y. apply THRLEE in C1. + destruct C1 as [x3 [CD2 [x4 [CD3 [EQ INE]]]]]. + desf. } + { clear - C1 C2 surg_init_min. + exfalso. unfold min_elt in surg_init_min. + destruct C2 as [C2 C3]. + basic_solver 4. } + { left; right. + clear - C1 C2 TR. + destruct C1 as [C1 EQ]; subst x y. + split; vauto. } + { clear - C1 C2 THRDNEQ. + destruct C1 as [C1 EQ]; subst x y. + destruct C2 as [C2 EQ1]; subst z. + exfalso. desf. } + { clear - C1 C2 IR. + exfalso. + destruct C1 as [C1 EQ]; subst x y. + destruct C2 as [C2 EQ1]; subst z. + destruct IR with t_1. + destruct C2 as [x0 [x1 [CD [EQ1 EQ2]]]]; subst. + vauto. } + { clear - C1 C2 THRDNEQ. + destruct C1 as [C1 EQ]; subst x y. + destruct C2 as [C2 EQ1]. + exfalso. desf. } + { clear - C1 C2 NINIT1. + destruct C1 as [C1 EQ]; subst x y. + destruct C2 as [C2 EQ1]. + exfalso. desf. } + { destruct C1 as [EQ1 EQ2]. + subst y. apply THRLEE in C2. + destruct C2 as [x3 [[EQ TD] [x4 [CD3 CD4]]]]. + desf. } + { do 4 left. clear - C1 C2 TR. + destruct C2 as [C2 EQ]; subst y z. + destruct C1 as [C1 EQ1]. + destruct C1 as [x0 [x1 [CD1 [EQ2 EQ3]]]]; subst. + vauto. } + { destruct C1 as [EQ1 EQ2]. + subst y. + destruct C2 as [C2 EQ]; subst z. + destruct C2 as [x0 [x1 [CD2 [EQ3 EQ4]]]]; subst. + apply THRLEE in CD2. + destruct CD2 as [x3 [[EQ TD] [x4 [CD3 CD4]]]]. + desf. } + { do 4 left. clear - C1 C2 TR. + destruct C2 as [C2 EQ]; subst. + destruct C1 as [C1 EQ1]; subst. + destruct C1 as [x0 [x1 [CD1 [EQ2 EQ3]]]]; subst. + destruct EQ as [x1 [x2 [[EQ INE] CDD]]]; subst. + basic_solver 8. } + { clear - C1 C2 NINIT2. + destruct C1 as [C1 EQ]; subst. + destruct C2 as [C2 EQ1]; subst. + exfalso. desf. } + { left; right. + clear - C1 C2 TR. + destruct C1 as [EQ1 EQ2]. + subst x. split; vauto. + unfold codom_rel. + destruct EQ2 as [x0 [x1 [[EQ1 EQ2] CD]]]. + basic_solver 8. } + { clear - C1 C2 THRLEE T2NOTIN. + destruct C2 as [C2 EQ]; subst. + destruct C1 as [C1 EQ1]; subst. + destruct EQ1 as [x0 [x1 [[EQ1 EQ2] CD]]]. + apply THRLEE in CD. + destruct CD as [x3 [[EQ TD] [x4 [CD3 [EQ3 TD2]]]]]. + desf. } + { clear - C1 C2 IR TR. + exfalso. + destruct C1 as [C1 EQ]; subst. + destruct C2 as [C2 EQ1]; subst. + destruct EQ as [x0 [x1 [[EQ1 EQ2] CD]]]; subst. + destruct C2 as [x2 [x3 [CD2 [INE1 INE2]]]]; subst. + basic_solver 8. } + { destruct C1 as [EQ1 EQ2]. + subst x. + destruct C2 as [C2 EQ]; subst. + destruct EQ2 as [x0 [x1 [CD2 CD3]]]; subst. + apply THRLEE in CD3. + destruct CD3 as [x3 [[EQ2 TD] [x4 [CD3 [EQ3 EQ4]]]]]. + desf. } + { clear - C1 C2 surg_init_min TR. + exfalso. + destruct C1 as [C1 EQ]; subst. + destruct C2 as [C2 EQ1]; subst. + destruct EQ as [x0 [x1 [[EQ3 EQ2] CD]]]; subst. + destruct surg_init_min with x1; vauto. } + { do 4 left. clear - C1 C2 TR surg_init_least surg_init_min. + destruct C1. + destruct H0 as [x0 CND]; subst. + unfold least_elt in surg_init_least. + apply surg_init_least. + intros FLS. basic_solver 12. } + { clear - C1 C2 THRLEE T2NOTIN. + exfalso. + destruct C1 as [C1 EQ]; subst. + destruct C2 as [C2 EQ1]; subst. + destruct EQ as [x0 CND]; subst. + apply THRLEE in CND. + destruct CND as [x3 [[EQ2 TD] [x4 [CD3 [EQ3 EQ4]]]]]. + desf. } + { do 2 left; right. + clear - C1 C2 TR NINIT1 surg_init_least. + destruct C1 as [C1 EQ]; subst. + destruct C2 as [C2 EQ1]; subst. + split; vauto. + unfold dom_rel. + exists t_1; vauto. + unfold seq; exists t_1; split; vauto. + unfold least_elt in surg_init_least. + specialize (surg_init_least t_1). + apply surg_init_least. + basic_solver. } + { clear - C1 C2 THRLEE T2NOTIN. + exfalso. + destruct C1 as [C1 EQ]; subst. + destruct C2 as [C2 EQ1]; subst. + destruct EQ as [x0 CND]; subst. + apply THRLEE in CND. + destruct CND as [x3 [[EQ2 TD] [x4 [CD3 [EQ3 EQ4]]]]]. + desf. } + clear - C1 C2 surg_init_min. + destruct C1 as [C1 EQ]; subst. + destruct C2 as [C2 EQ1]; subst. + exfalso. + unfold min_elt in surg_init_min. + destruct EQ as [x0 CND]. + specialize (surg_init_min x0). + vauto. } + admit. (* proof scheme of this statement is + in the appendix of the article*)} + + unfold WCore.reexec. + exists thrdle'. + constructor; vauto. + { unfold dtrmt'. destruct SIMRELQ. + arewrite ((fun a : actid => is_init a) ⊆₁ + mapper' ↑₁ (fun a : actid => is_init a)). + { clear- seq_init. + unfold fixset in seq_init. + basic_solver. } + destruct STEP. + rewrite dtrmt_init; vauto. } + { unfold dtrmt', cmt'. + rewrite (WCore.dtrmt_cmt STEP); vauto. } + { unfold dtrmt'. + unfold fixset. + intros x DTT. + destruct DTT as [x0 [INX DTT]]. + subst. unfold compose. + assert (HLP : mapper_rev' (mapper' x0) = x0). + { unfold compose in MAPCOMP. + apply MAPCOMP. destruct STEP. + apply dtrmt_cmt, reexec_embd_dom in INX; vauto. } + rewrite HLP. + arewrite (f_t x0 = x0). + { destruct STEP. + apply dtrmt_fixed; vauto. } + apply DTRSAME; vauto. } + { destruct STEP. unfold cmt'. + arewrite (WCore.G X_s' = G_s'). + unfold G_s'. simpls. + basic_solver 8. } + { unfold sb. rewrite !seqA. + rewrite <- !id_inter. + rewrite <- seqA with (r1 := ⦗dtrmt'⦘). + rewrite <- id_inter. + unfold dtrmt'. destruct SIMREL. + rewrite seq_acts. + intros x y PTH. + destruct PTH as [x0 [[EQ1 IN1] + [x1 [PTH [EQ2 [IN2 IN3]]]]]]. + destruct IN1 as [x2 [IN1 M1]]. + destruct IN2 as [x3 [IN2 M2]]. + subst. + unfold seq. exists (mapper x2); split. + { red; split; vauto. + split; [| basic_solver]. + destruct STEP. + destruct reexec_dtrmt_sb_closed with + (x := x2) (y := x3). + { unfold seq. exists x3; split. + { destruct x2. + { unfold sb. + unfold seq; exists (InitEvent l); split; vauto. + exists x3; split; vauto. + unfold ext_sb. desf. + rewrite !seq_init in PTH; vauto. } + destruct classic with (tid (mapper + (ThreadEvent thread index)) = t_2) as [TID2 | TID2]. + { rewrite seq_mapto in PTH. + { destruct x3. + { rewrite !seq_init in PTH; vauto. } + destruct classic with (tid (mapper + (ThreadEvent thread0 index0)) = t_2) as [TID2' | TID2']. + { rewrite seq_mapto in PTH. + { assert (TD1 : thread = t_1). + { apply seq_thrd in TID2; vauto. } + assert (TD2 : thread0 = t_1). + { apply seq_thrd in TID2'; vauto. } + clear - PTH IN1 IN2 TID2 TID2' TD1 TD2. + unfold sb. unfold seq. + exists (ThreadEvent thread index); split; vauto. + exists (ThreadEvent t_1 index0); split; vauto. + unfold ext_sb. desf; split; vauto. + unfold ext_sb in PTH. desf. + unfold Events.index in *. lia. } + all : vauto. } + clear - TID2 TID2' PTH IN1 IN2. + unfold sb. unfold seq. + exists (ThreadEvent thread index); split; vauto. + exists (ThreadEvent thread0 index0); split; vauto. + unfold ext_sb in *. + unfold tid in *. + desf; desf. } + all : vauto. } + destruct x3. + { exfalso. + assert (HLP : mapper (InitEvent l) + = InitEvent l). + { rewrite seq_init; vauto. } + rewrite HLP in PTH. + clear - PTH. + unfold ext_sb in PTH. + desf. } + destruct classic with (tid (mapper + (ThreadEvent thread0 index0)) = t_2) as [TID2' | TID2']. + { clear - TID2 TID2' PTH IN1 IN2 seq_init seq_init_rev MAPREV. + unfold sb. unfold seq. + exists (ThreadEvent thread index); split; vauto. + exists (ThreadEvent thread0 index0); split; vauto. + exfalso. unfold ext_sb in *. + unfolder. desf. + { assert (Heqq : mapper_rev (mapper (ThreadEvent thread index)) = + mapper_rev (InitEvent l)). + { rewrite Heq; vauto. } + unfold compose in MAPREV. + rewrite MAPREV in Heqq; vauto. + unfold id in Heqq. + rewrite seq_init_rev in Heqq; vauto. } + unfold tid in *. desf. } + assert (EQQ1 : mapper (ThreadEvent thread index) = + ThreadEvent thread index). + { rewrite seq_mapeq; vauto. } + assert (EQQ2 : mapper (ThreadEvent thread0 index0) = + ThreadEvent thread0 index0). + { rewrite seq_mapeq; vauto. } + rewrite EQQ1, EQQ2 in PTH. + unfold sb. unfold seq. + exists (ThreadEvent thread index); split; vauto. } + red; split; vauto. + unfold set_collect in IN3. + destruct IN3 as [x4 [IN3 EQ]]. + assert (IN4 : E_t' x4). + { apply dtrmt_cmt, reexec_embd_dom in IN3; vauto. } + unfold mapper' in EQ. + apply MAPS in EQ; vauto. } + unfold set_collect. + exists x2; split. + { destruct H as [DT _]. + red in DT. basic_solver 4. } + destruct x2. + { rewrite seq_init; vauto. + destruct SIMRELQ. + rewrite seq_init0; vauto. } + destruct H as [DT SB]. + destruct classic with (tid (mapper + (ThreadEvent thread index)) = t_2) as [TID2 | TID2]. + { assert (TID2' : tid (mapper (ThreadEvent thread index)) = t_2) by vauto. + assert (TID2S : tid (mapper (ThreadEvent thread index)) = t_2) by vauto. + apply seq_index in TID2. + apply seq_thrd in TID2'. + { apply INDLEMMA. + { unfold mapper'. desf. + { rewrite TID2'; vauto. } + unfold not in n0. + apply NNPP in n0. + rewrite n0; vauto. } + { unfold mapper'. + rewrite TID2S. clear TID2S. + desf. + { red in DT. destruct DT as [EQ DT]. + apply dtrmt_cmt in DT. + apply reexec_embd_dom in DT; vauto. } + symmetry in TID2. + rewrite <- TID2 in l. + exfalso. unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + unfold mapper'. + rewrite TID2. clear TID2. + desf. + { red in DT. destruct DT as [EQ DT]. + apply dtrmt_cmt in DT. + apply reexec_embd_dom in DT; vauto. } + { exfalso. unfold Events.index in *. + unfold SequentBase.t_1_len in *. + unfold t_1_len in *. + lia. } + unfold Events.index in *. + unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + lia. } + { red in DT. destruct DT as [EQ DT]. + apply dtrmt_cmt in DT. + apply reexec_embd_dom in DT; vauto. } + red in DT. destruct DT as [EQ DT]. + apply dtrmt_cmt in DT. + apply reexec_embd_dom in DT; vauto. } + assert (TID2' : tid (mapper (ThreadEvent thread index)) <> t_2) by vauto. + assert (TID2S : tid (mapper (ThreadEvent thread index)) <> t_2) by vauto. + apply seq_mapeq in TID2. + { rewrite TID2. clear TID2. + unfold mapper'. desf. + apply INDLEMMA. + { unfold tid; vauto. } + { unfold tid. + unfold not in n0. + apply NNPP in n0. + apply seq_out_move in n0; vauto. + { apply seq_mapeq in TID2S; vauto. + rewrite TID2S in n0. + desf. } + unfold Events.index in *. + unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + lia. } + unfold Events.index in *. + unfold not in n0. + apply NNPP in n0. + apply seq_out_move in n0; vauto. + { apply seq_mapeq in TID2S; vauto. + rewrite TID2S in n0. + desf. } + unfold Events.index in *. + unfold t_1_len in *. + unfold SequentBase.t_1_len in *. + lia. } + red in DT. destruct DT as [EQ DT]. + apply dtrmt_cmt in DT. + apply reexec_embd_dom in DT; vauto. } + exists (mapper x3); split; vauto. + red; split; vauto. } + { unfold nin_sb. + rewrite SBSEQ. + rewrite <- seq_eqv_minus_ll. + admit. (* immediate on exclusion is unfolded and then + the mapper is taken out *)} + { arewrite (WCore.G X_s' = G_s'). + unfold G_s' at 1; ins. + intros x COND. + destruct COND as (INE & NDT). + unfold set_compl. intros FLS. + destruct INE as [x0 [INE M1]]; subst. + unfold dtrmt' in NDT. + assert (DTRM : ~ dtrmt_t x0). + { intros FLSS. + apply NDT. unfold set_collect. + exists x0; split; vauto. } + destruct FLS as [FL1 | FL2]. + { assert (FLS : (Rel G_t') x0). + { assert (SUBST : (fun x : actid => + ifP ~ (mapper' ↑₁ E_t') x then x + else (ifP tid x <> t_2 then x + else ThreadEvent t_1 + (t_1_len + index x))) = mapper_rev') by vauto. + rewrite SUBST in FL1. + unfold compose in FL1. + unfold is_rel, mod in *. + assert (HLP : mapper_rev' (mapper' x0) = x0). + { unfold compose in MAPCOMP. + apply MAPCOMP in INE. + unfold id in INE; vauto. } + rewrite HLP in FL1; vauto. } + destruct STEP. + clear - reexec_dtrmt_rpo FLS DTRM INE. + unfold set_compl in reexec_dtrmt_rpo. + destruct reexec_dtrmt_rpo with x0; vauto. } + assert (FLS : (Acq G_t') x0). + { assert (SUBST : (fun x : actid => + ifP ~ (mapper' ↑₁ E_t') x then x + else (ifP tid x <> t_2 then x + else ThreadEvent t_1 + (t_1_len + index x))) = mapper_rev') by vauto. + rewrite SUBST in FL2. + unfold compose in FL2. + unfold is_acq, mod in *. + assert (HLP : mapper_rev' (mapper' x0) = x0). + { unfold compose in MAPCOMP. + apply MAPCOMP in INE. + unfold id in INE; vauto. } + rewrite HLP in FL2; vauto. } + destruct STEP. + clear - reexec_dtrmt_rpo FLS DTRM INE. + unfold set_compl in reexec_dtrmt_rpo. + destruct reexec_dtrmt_rpo with x0; vauto. } + { destruct STEP. + destruct reexec_embd_corr. + constructor; vauto. + { unfold cmt'. + unfold inj_dom. + intros x y CD1 CD2 EQQ. + destruct CD1 as [x0 [CD1 M1]]. + destruct CD2 as [x1 [CD2 M2]]. + subst. + unfold compose in EQQ. + unfold compose in MAPCOMP. + assert (HLP1 : mapper_rev' (mapper' x0) = x0). + { unfold compose in MAPCOMP. + apply MAPCOMP. + apply reexec_embd_dom in CD1; vauto. } + assert (HLP2 : mapper_rev' (mapper' x1) = x1). + { unfold compose in MAPCOMP. + apply MAPCOMP. + apply reexec_embd_dom in CD2; vauto. } + rewrite HLP1, HLP2 in EQQ. + destruct SIMREL. + apply seq_inj in EQQ. + { apply reexec_embd_inj in EQQ; vauto. } + { apply reexec_embd_acts; red. + exists x0; vauto. } + apply reexec_embd_acts; red. + exists x1; vauto. } + { intros e CMT. + unfold cmt' in CMT. + unfold set_collect in CMT. + destruct CMT as [x [CMT EQ]]. + specialize (reexec_embd_lab x). + assert (INE : E_t' x). + { apply reexec_embd_dom in CMT; vauto. } + assert (CMT' : cmt_t x) by vauto. + apply reexec_embd_lab in CMT. + destruct SIMRELQ. + apply seq_lab in INE. + unfold compose in INE. + rewrite EQ in INE. + rewrite <- INE. + destruct SIMREL. + rewrite CMT. + subst. + unfold compose. + unfold compose in MAPCOMP. + rewrite MAPCOMP. + { unfold id. + apply seq_lab0. + apply reexec_embd_acts; red; vauto. } + apply reexec_embd_dom; vauto. } + { admit. (* case analysis on where in G_s' + the rpo-edge lies: if it lies not in t_1 or t_2, + it stays there and if not, we use the lemma + about rpo-edges proven earlier *) } + { unfold cmt'. + rewrite (seq_rf SIMRELQ). + rewrite (seq_rf SIMREL). + destruct STEP. + destruct reexec_embd_corr. + rewrite <- reexec_embd_rf0. + rewrite collect_rel_restr. + { intros x y COND. + unfold compose in COND. + unfold collect_rel in COND. + destruct COND as [x0 [x1 [COND [EQ1 EQ2]]]]. + destruct COND as [x2 [x3 [COND [EQ3 EQ4]]]]. + unfold collect_rel. + exists (f_t (mapper_rev' x0)), (f_t (mapper_rev' x1)); splits. + { exists x2, x3; splits; vauto. + { unfold compose in MAPCOMP. + rewrite MAPCOMP; vauto. + destruct COND as [RF CDS]. + apply wf_rfE in RF; [|apply INV']. + destruct RF as [x0 [[INE EQQ] RF2]]; vauto. } + unfold compose in MAPCOMP. + rewrite MAPCOMP; vauto. + destruct COND as [RF CDS]. + apply wf_rfE in RF; [|apply INV']. + destruct RF as [x0 [RF1 [RF2 [RF3 [INE EQQ]]]]]; vauto. } + all : vauto. } + rewrite reexec_embd_dom0. + rewrite wf_rfE; [| apply INV']. + rewrite dom_eqv1. + rewrite <- seqA. + rewrite codom_seq_eqv_r. + arewrite (E_t' ∩₁ dom_rel (rf_t' ⨾ ⦗E_t'⦘) ⊆₁ E_t'). + { basic_solver. } + destruct SIMRELQ. + clear - seq_inj. + basic_solver 8. } + { unfold cmt'. + rewrite (seq_co SIMRELQ). + rewrite (seq_co SIMREL). + destruct STEP. + destruct reexec_embd_corr. + rewrite <- reexec_embd_co0. + rewrite collect_rel_restr. + { intros x y COND. + unfold compose in COND. + unfold collect_rel in COND. + destruct COND as [x0 [x1 [COND [EQ1 EQ2]]]]. + destruct COND as [x2 [x3 [COND [EQ3 EQ4]]]]. + unfold collect_rel. + exists (f_t (mapper_rev' x0)), (f_t (mapper_rev' x1)); splits. + { exists x2, x3; splits; vauto. + { unfold compose in MAPCOMP. + rewrite MAPCOMP; vauto. + destruct COND as [CO CDS]. + apply wf_coE in CO; [|apply INV']. + destruct CO as [x0 [[INE EQQ] CO2]]; vauto. } + unfold compose in MAPCOMP. + rewrite MAPCOMP; vauto. + destruct COND as [CO CDS]. + apply wf_coE in CO; [|apply INV']. + destruct CO as [x0 [CO1 [CO2 [CO3 [INE EQQ]]]]]; vauto. } + all : vauto. } + rewrite reexec_embd_dom0. + rewrite wf_coE; [| apply INV']. + rewrite dom_eqv1. + rewrite <- seqA. + rewrite codom_seq_eqv_r. + arewrite (E_t' ∩₁ dom_rel (co_t' ⨾ ⦗E_t'⦘) ⊆₁ E_t'). + { basic_solver. } + destruct SIMRELQ. + clear - seq_inj. + basic_solver 8. } + { unfold cmt'. + rewrite (seq_rmw SIMRELQ). + rewrite (seq_rmw SIMREL). + destruct STEP. + destruct reexec_embd_corr. + rewrite <- reexec_embd_rmw0. + rewrite collect_rel_restr. + { intros x y COND. + unfold compose in COND. + unfold collect_rel in COND. + destruct COND as [x0 [x1 [COND [EQ1 EQ2]]]]. + destruct COND as [x2 [x3 [COND [EQ3 EQ4]]]]. + unfold collect_rel. + exists (f_t (mapper_rev' x0)), (f_t (mapper_rev' x1)); splits. + { exists x2, x3; splits; vauto. + { unfold compose in MAPCOMP. + rewrite MAPCOMP; vauto. + destruct COND as [RM CDS]. + apply wf_rmwE in RM; [|apply INV']. + destruct RM as [x0 [[INE EQQ] RM2]]; vauto. } + unfold compose in MAPCOMP. + rewrite MAPCOMP; vauto. + destruct COND as [RM CDS]. + apply wf_rmwE in RM; [|apply INV']. + destruct RM as [x0 [RM1 [RM2 [RM3 [INE EQQ]]]]]; vauto. } + all : vauto. } + rewrite reexec_embd_dom0. + rewrite wf_rmwE; [| apply INV']. + rewrite dom_eqv1. + rewrite <- seqA. + rewrite codom_seq_eqv_r. + arewrite (E_t' ∩₁ dom_rel (rmw_t' ⨾ ⦗E_t'⦘) ⊆₁ E_t'). + { basic_solver. } + destruct SIMRELQ. + clear - seq_inj. + basic_solver 8. } + unfold cmt'. + intros x COND. + unfold set_collect in COND. + destruct COND as [x0 [COND EQ]]. + destruct COND as [x1 [COND EQ1]]. + rewrite <- EQ1 in EQ. + unfold compose in EQ. + unfold compose in MAPCOMP. + rewrite MAPCOMP in EQ. + { unfold id in EQ. + rewrite <- EQ. + destruct SIMREL. + apply seq_acts. + unfold set_collect. + exists (f_t x1); split; vauto. + apply reexec_embd_acts. + clear - COND. + basic_solver. } + apply reexec_embd_dom; vauto. } + + { destruct SIMREL. + unfold dtrmt'. unfold WCore.reexec_thread. + arewrite ((WCore.G X_s') = G_s'). + unfold G_s'; ins. + rewrite <- set_collect_minus. + { rewrite seq_acts. + destruct STEP. + rewrite rexec_acts at 1. + rewrite set_collect_union. + apply set_union_more. + { split. + { intros x COND. + destruct COND as [x0 [COND EQ]]. + unfold set_collect. + exists x0; split; vauto. + symmetry. + apply DTRSAME; vauto. } + intros x COND. + destruct COND as [x0 [COND EQ]]. + unfold set_collect. + exists x0; split; vauto. + apply DTRSAME; vauto. } + unfold WCore.reexec_thread. + split. + { rewrite set_collect_inter. + apply set_subset_inter_r. + split; [clear; basic_solver |]. + admit. } + admit. } + destruct STEP. rewrite dtrmt_cmt. + rewrite reexec_embd_dom. + destruct SIMRELQ. + clear - seq_inj0. + basic_solver. } + apply sub_to_full_exec_listless + with (thrdle := thrdle'); vauto. + { admit. (* acts_set is generally finite *) } + { constructor. + { unfold WCore.X_start; ins. + destruct STEP; vauto. + unfold dtrmt'. rewrite <- dtrmt_init. + destruct SIMREL. rewrite seq_acts. + split. + { destruct SIMRELQ. + unfold set_collect. exists x; split; vauto. + apply seq_init0 in H; vauto. } + unfold set_collect. + exists x; split. + { apply INV; vauto. } + destruct SIMRELQ. + apply seq_init in H; vauto. } + { unfold WCore.X_start; ins. + rewrite (seq_acts SIMREL). + unfold dtrmt'. destruct STEP. + rewrite dtrmt_cmt, reexec_embd_dom. + clear; basic_solver. } + { unfold WCore.X_start; ins. } + all : admit. (* all of these statements follow from + induction on guided step and + particularly its add_setp part *)} + { apply wf_transition with (X_t := X_t') + (t_1 := t_1) (t_2 := t_2) + (mapper := mapper') (mapper_rev := mapper_rev') + (ptc_1 := ptc_1); vauto. } + unfold WCore.X_start; ins. + destruct STEP. + intros x COND. + destruct COND as [MP NOT]. + intros FLS. + assert (INITT: is_init x). + { apply INTREADS; vauto. } + assert (INITT2: is_init x) by vauto. + apply dtrmt_init in INITT. + assert (DTRF : dtrmt' x). + { unfold dtrmt'. + unfold set_collect. + exists x; split; vauto. + destruct SIMRELQ. + apply seq_init; vauto. } + destruct NOT. + split; vauto. + destruct SIMREL. + apply seq_acts. + unfold set_collect. + exists x; split; vauto. + { apply rexec_acts; vauto. } + destruct MP as [x0 [INE MPP]]. + apply seq_init; vauto. +Admitted. + +End SequentReexec. \ No newline at end of file diff --git a/src/sequentialization/SequentWf.v b/src/sequentialization/SequentWf.v new file mode 100644 index 00000000..93d87490 --- /dev/null +++ b/src/sequentialization/SequentWf.v @@ -0,0 +1,418 @@ +Require Import AuxDef. +Require Import Core. +Require Import AuxRel AuxRel2. +Require Import Srf Rhb. +Require Import SimrelCommon. +Require Import SubToFullExec. +Require Import StepOps. +Require Import AuxInj. +Require Import xmm_s_hb. +Require Import Lia. +From xmm Require Import Reordering. +From xmm Require Import ThreadTrace. +From xmm Require Import Programs. +From xmm Require Import SequentBase. +From xmm Require Import ConsistencyMonotonicity. + +From hahn Require Import Hahn. +From hahnExt Require Import HahnExt. +From imm Require Import Events Execution Execution_eco SubExecution. +Require Import Setoid Morphisms Program.Basics. + +Open Scope program_scope. + +Set Implicit Arguments. + +Section SequentWf. + +Variable X_t X_s : WCore.t. +Variable t_1 t_2 : thread_id. +Variable mapper : actid -> actid. +Variable mapper_rev : actid -> actid. + +Variable dtrmt_t cmt_t : actid -> Prop. +Variable thrdle : relation thread_id. +Variable f_t : actid -> actid. + +Variable ptc_1 ptc_2 : program_trace. + +Notation "'G_t'" := (WCore.G X_t). +Notation "'G_s'" := (WCore.G X_s). + +Notation "'R' G" := (fun e => is_true (is_r (lab G) e)) (at level 1). +Notation "'F' G" := (fun e => is_true (is_f (lab G) e)) (at level 1). +Notation "'W' G" := (fun e => is_true (is_w (lab G) e)) (at level 1). +Notation "'Acq' G" := (fun e => is_true (is_acq (lab G) e)) (at level 1). +Notation "'Rlx' G" := (fun e => is_true (is_rlx (lab G) e)) (at level 1). +Notation "'Rel' G" := (fun e => is_true (is_rel (lab G) e)) (at level 1). + +Notation "'lab_t'" := (lab G_t). +Notation "'val_t'" := (val lab_t). +Notation "'loc_t'" := (loc lab_t). +Notation "'same_loc_t'" := (same_loc lab_t). +Notation "'E_t'" := (acts_set G_t). +Notation "'sb_t'" := (sb G_t). +Notation "'rf_t'" := (rf G_t). +Notation "'co_t'" := (co G_t). +Notation "'rmw_t'" := (rmw G_t). +Notation "'rpo_t'" := (rpo G_t). +Notation "'rmw_dep_t'" := (rmw_dep G_t). +Notation "'data_t'" := (data G_t). +Notation "'ctrl_t'" := (ctrl G_t). +Notation "'addr_t'" := (addr G_t). +Notation "'W_t'" := (fun x => is_true (is_w lab_t x)). +Notation "'R_t'" := (fun x => is_true (is_r lab_t x)). +Notation "'Loc_t_' l" := (fun e => loc_t e = l) (at level 1). + +Notation "'lab_s'" := (lab G_s). +Notation "'val_s'" := (val lab_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'same_loc_s'" := (same_loc lab_s). +Notation "'E_s'" := (acts_set G_s). +Notation "'loc_s'" := (loc lab_s). +Notation "'sb_s'" := (sb G_s). +Notation "'rf_s'" := (rf G_s). +Notation "'co_s'" := (co G_s). +Notation "'rmw_s'" := (rmw G_s). +Notation "'rpo_s'" := (rpo G_s). +Notation "'rmw_dep_s'" := (rmw_dep G_s). +Notation "'data_s'" := (data G_s). +Notation "'ctrl_s'" := (ctrl G_s). +Notation "'addr_s'" := (addr G_s). +Notation "'W_s'" := (fun x => is_true (is_w lab_s x)). +Notation "'R_s'" := (fun x => is_true (is_r lab_s x)). +Notation "'F_s'" := (F G_s). + +Notation "'Tid_' t" := (fun e => tid e = t) (at level 1). + +Hypothesis MAPREV : eq_dom E_t (mapper_rev ∘ mapper) id. +Hypothesis PROGSEQ : program_trace_sequented ptc_1 ptc_2 t_1 t_2. + +Definition t_12_len := length (ptc_2 t_2). +Definition t_1_len := length (ptc_1 t_1). +Definition t_2_len := length (ptc_1 t_2). + +Hypothesis INV : seq_simrel_inv X_t. + +Lemma wf_transition + (SIMREL : seq_simrel X_s X_t t_1 t_2 mapper mapper_rev ptc_1) : + Wf G_s. +Proof using. + assert (INDLEMMA : forall x y (NNIT : tid x <> tid_init) (EQT : tid x = tid y) (EQI : index x = index y), + x = y). + { clear. intros x y NNIT EQT EQI. + destruct x; destruct y; desf; ins. + desf. } + constructor. + { intros a b COND. + destruct COND as [INA [INB [NEQ [TIDS NINIT]]]]. + intros FLS. + specialize INDLEMMA with a b. + apply NEQ; apply INDLEMMA; vauto. + unfold is_init in NINIT. + clear - NINIT. unfold not in NINIT. + unfold not. intros FLS. + unfold tid in FLS. + destruct a. + { apply NINIT; vauto. } + admit. (* ??? *) } + { rewrite (seq_data SIMREL); vauto. } + { rewrite (seq_data SIMREL); clear; [ basic_solver 4 ]. } + { rewrite (seq_addr SIMREL); vauto. } + { rewrite (seq_addr SIMREL); clear; [ basic_solver 4 ]. } + { rewrite (seq_ctrl SIMREL); vauto. } + { rewrite (seq_ctrl SIMREL); clear; [ basic_solver 4 ]. } + { rewrite (seq_ctrl SIMREL); clear; [ basic_solver 4 ]. } + { split; [| basic_solver 9 ]. + rewrite (seq_rmw SIMREL); vauto. + intros x y COND. destruct COND as [x0 [y0 [RMW [M1 M2]]]]. + apply wf_rmwE in RMW. + { destruct RMW as [x1 [[EQ1 INE1] [x2 [PTH [EQ2 INE2]]]]]. + subst. destruct SIMREL. + apply seq_lab in INE1, INE2. + apply wf_rmwD in PTH. + { destruct PTH as [x2 [[EQ1 RD] [x3 [PTH [EQ2 WT]]]]]. + subst. unfold seq. exists (mapper x2); splits. + { red; splits; vauto. + unfold compose in INE1. + unfold is_r in *. + rewrite <- INE1; vauto. } + exists (mapper y0); splits; vauto. + red; splits; vauto. unfold is_w in *. + unfold compose in INE2. + rewrite <- INE2; vauto. } + apply INV. } + apply INV. } + { rewrite (seq_rmw SIMREL). + intros x y COND. + destruct COND as [x0 [y0 [PTH [M1 M2]]]]. + subst. + apply wf_rmwE in PTH; [| apply INV]. + destruct PTH as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]. + subst. + apply wf_rmwl in PTH; [| apply INV]. + unfold same_loc in *. + apply (seq_lab SIMREL) in INE1, INE2. + unfold compose in *. + unfold loc in *. + rewrite <- INE1. + rewrite <- INE2; vauto. } + { rewrite (seq_rmw SIMREL). + intros x y COND. + destruct COND as [x0 [y0 [PTH [M1 M2]]]]. + subst. + apply wf_rmwE in PTH; [| apply INV]. + destruct PTH as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]. + subst. apply wf_rmwi in PTH; [| apply INV]. + admit. (* false *) } + { split; [| basic_solver 4]. + rewrite (seq_rf SIMREL). + intros x y COND. + destruct COND as [x0 [y0 [PTH [M1 M2]]]]. + subst. + apply wf_rfE in PTH; [| apply INV]. + destruct PTH as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]. + subst. + unfold seq. + exists (mapper x2); split. + { red; split; vauto. + destruct SIMREL. apply seq_codom. + red; exists x2; vauto. } + exists (mapper y0); split; vauto. + red; split; vauto. + destruct SIMREL. apply seq_codom. + red; exists y0; vauto. } + { split; [| basic_solver 4]. + rewrite (seq_rf SIMREL). + intros x y COND. + destruct COND as [x0 [y0 [PTH [M1 M2]]]]. + subst. + apply wf_rfE in PTH; [| apply INV]. + destruct PTH as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]. + subst. + apply wf_rfD in PTH; [| apply INV]. + destruct PTH as [x3 [[EQ1 WT] [x4 [PTH [EQ2 RD]]]]]. + subst. + destruct SIMREL. + apply seq_lab in INE1, INE2. + unfold compose in *. + unfold seq. exists (mapper x3); splits. + { red; splits; vauto. + unfold compose in INE1. + unfold is_w in *. + rewrite <- INE1; vauto. } + exists (mapper y0); splits; vauto. + red; splits; vauto. unfold is_r in *. + unfold compose in INE2. + rewrite <- INE2; vauto. } + { rewrite (seq_rf SIMREL). + intros x y COND. + destruct COND as [x0 [y0 [PTH [M1 M2]]]]. + subst. + apply wf_rfE in PTH; [| apply INV]. + destruct PTH as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]. + subst. + apply wf_rfl in PTH; [| apply INV]. + unfold same_loc in *. + apply (seq_lab SIMREL) in INE1, INE2. + unfold compose in *. + unfold loc in *. + rewrite <- INE1. + rewrite <- INE2; vauto. } + { rewrite (seq_rf SIMREL). + unfold funeq. intros a b MAP. + destruct MAP as [x0 [y0 [PTH [M1 M2]]]]. + subst. + apply wf_rfE in PTH; [| apply INV]. + destruct PTH as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]. + subst. + apply wf_rfv in PTH; [| apply INV]. + apply (seq_lab SIMREL) in INE1. + apply (seq_lab SIMREL) in INE2. + unfold compose in *. + unfold val in *. + rewrite <- INE1. + rewrite <- INE2; vauto. } + { rewrite (seq_rf SIMREL). + unfold functional. + intros x y z M M'. + destruct M as [x0 [y0 [PTH1 [M1 M2]]]]; subst. + destruct M' as [x1 [y1 [PTH2 [M3 M4]]]]; subst. + destruct SIMREL. + assert (EQQ : y1 = y0). + { apply seq_inj; vauto. + { apply wf_rfE in PTH2; [| apply INV]. + destruct PTH2 as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]; vauto. } + apply wf_rfE in PTH1; [| apply INV]. + destruct PTH1 as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]; vauto. } + subst. + assert (EQQ' : x0 = x1). + { destruct wf_rff with (G := G_t) (x := y0) + (y := x0) (z := x1); vauto. + apply INV. } + basic_solver. } + { split; [| basic_solver]. + rewrite (seq_co SIMREL). + intros x y COND. + destruct COND as [x0 [y0 [PTH [M1 M2]]]]. + subst. + apply wf_coE in PTH; [| apply INV]. + destruct PTH as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]. + subst. + unfold seq. + exists (mapper x2); split. + { red; split; vauto. + destruct SIMREL. apply seq_codom. + red; exists x2; vauto. } + exists (mapper y0); split; vauto. + red; split; vauto. + destruct SIMREL. apply seq_codom. + red; exists y0; vauto. } + { split; [| basic_solver 4]. + rewrite (seq_co SIMREL). + intros x y COND. + destruct COND as [x0 [y0 [PTH [M1 M2]]]]. + subst. + apply wf_coE in PTH; [| apply INV]. + destruct PTH as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]. + subst. + apply wf_coD in PTH; [| apply INV]. + destruct PTH as [x3 [[EQ1 WT] [x4 [PTH [EQ2 RD]]]]]. + subst. + destruct SIMREL. + apply seq_lab in INE1, INE2. + unfold compose in *. + unfold seq. exists (mapper x3); splits. + { red; splits; vauto. + unfold compose in INE1. + unfold is_w in *. + rewrite <- INE1; vauto. } + exists (mapper y0); splits; vauto. + red; splits; vauto. unfold is_w in *. + unfold compose in INE2. + rewrite <- INE2; vauto. } + { rewrite (seq_co SIMREL). + intros x y COND. + destruct COND as [x0 [y0 [PTH [M1 M2]]]]. + subst. + apply wf_coE in PTH; [| apply INV]. + destruct PTH as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]. + subst. + apply wf_col in PTH; [| apply INV]. + unfold same_loc in *. + apply (seq_lab SIMREL) in INE1, INE2. + unfold compose in *. + unfold loc in *. + rewrite <- INE1. + rewrite <- INE2; vauto. } + { rewrite (seq_co SIMREL). + unfold transitive. + intros x y z M M'. + destruct M as [x0 [y0 [PTH1 [M1 M2]]]]; subst. + destruct M' as [x1 [y1 [PTH2 [M3 M4]]]]; subst. + destruct SIMREL. + red; exists x0, y1; splits; vauto. + assert (EQQ : x1 = y0). + { apply seq_inj; vauto. + { apply wf_coE in PTH2; [| apply INV]. + destruct PTH2 as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]; vauto. } + apply wf_coE in PTH1; [| apply INV]. + destruct PTH1 as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]; vauto. } + subst. + apply co_trans with (x := x0) (y := y0) (z := y1); vauto. + apply INV. } + { intros ol. + rewrite (seq_co SIMREL). + unfold is_total. + intros a COND1 b COND2 NEQ. + unfold collect_rel. + destruct COND1 as [[INE1 ISW1] LOC1]. + destruct COND2 as [[INE2 ISW2] LOC2]. + destruct SIMREL. + apply seq_acts in INE1, INE2. + destruct INE1 as [a0 [INE1 MAP1]]. + destruct INE2 as [b0 [INE2 MAP2]]. + destruct wf_co_total with (G := G_t) (ol := ol) + (a := a0) (b := b0). + { apply INV. } + { split. + { split; vauto. + apply seq_lab in INE1. + unfold compose in *. + unfold is_w in *. + rewrite INE1; vauto. } + unfold loc in *. + apply seq_lab in INE1. + unfold compose in *. + rewrite INE1; vauto. } + { split. + { split; vauto. + apply seq_lab in INE2. + unfold compose in *. + unfold is_w in *. + rewrite INE2; vauto. } + unfold loc in *. + apply seq_lab in INE2. + unfold compose in *. + rewrite INE2; vauto. } + { intros FALSE. + apply NEQ. subst; vauto. } + { left. exists a0, b0; splits; vauto. } + right. exists b0, a0; splits; vauto. } + { rewrite (seq_co SIMREL). + unfold irreflexive. + intros x COND. + destruct COND as [x0 [y0 [PTH1 [M1 M2]]]]; subst. + destruct co_irr with (G := G_t) (x := x0); [apply INV|]. + assert (EQQ : y0 = x0). + { apply (seq_inj SIMREL); vauto. + { apply wf_coE in PTH1; [| apply INV]. + destruct PTH1 as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]; vauto. } + apply wf_coE in PTH1; [| apply INV]. + destruct PTH1 as [x2 [[EQ1 INE1] [x3 [PTH [EQ2 INE2]]]]]; vauto. } + subst; vauto. } + { intros l COND. + destruct COND. + destruct H as [INE LOC]. + apply (seq_acts SIMREL) in INE. + destruct INE as [x0 [INE MAP]]. + apply (seq_acts SIMREL). + unfold set_collect. exists (InitEvent l); split; vauto. + { apply wf_init; [apply INV |]. + exists x0; split; vauto. + unfold loc in *. apply (seq_lab SIMREL) in INE. + unfold compose in *. + rewrite INE; vauto. } + rewrite (seq_init SIMREL); vauto. } + { intros l. + assert (INE1 : E_s (InitEvent l)). + { apply (seq_acts SIMREL). + exists (InitEvent l). + split; [now apply (rsr_init_acts INV) |]. + destruct SIMREL. + rewrite seq_init; vauto. } + destruct SIMREL. + apply seq_lab_rev in INE1. + rewrite INE1. + unfold compose. + rewrite seq_init_rev; vauto. + apply wf_init_lab; apply INV. } + { rewrite (seq_rmw_dep SIMREL); vauto. } + { rewrite (seq_rmw_dep SIMREL); basic_solver 4. } + intros e INE. + assert (INE' : E_s e) by vauto. + destruct SIMREL. + apply seq_acts in INE. + destruct INE as [e0 [INE MAP]]. + assert (INE2 : E_t e0) by vauto. + apply wf_threads in INE; [| apply INV]. + rewrite <- MAP. + apply seq_threads. + destruct classic with (tid (mapper e0) = t_2). + { right; vauto. } + left. apply seq_mapeq in H. + { rewrite H; vauto. } + vauto. +Admitted. + +End SequentWf. \ No newline at end of file diff --git a/src/xmm/Core.v b/src/xmm/Core.v index b0b108ea..c6207415 100644 --- a/src/xmm/Core.v +++ b/src/xmm/Core.v @@ -437,7 +437,7 @@ Record stable_uncmt_reads_gen thrdle : Prop := Record commit_embedded : Prop := { reexec_embd_inj : inj_dom cmt f; - reexec_embd_tid : forall e (CMT : cmt e), tid (f e) = tid e; + (* reexec_embd_tid : forall e (CMT : cmt e), tid (f e) = tid e; *) reexec_embd_lab : forall e (CMT : cmt e), lab' e = lab (f e); reexec_embd_rpo : f ↑ restr_rel cmt rpo' ⊆ rpo; reexec_embd_rf : f ↑ restr_rel cmt rf' ⊆ rf; diff --git a/src/xmm/StepOps.v b/src/xmm/StepOps.v index a33e3c66..19b14c64 100644 --- a/src/xmm/StepOps.v +++ b/src/xmm/StepOps.v @@ -866,6 +866,69 @@ Proof using. eapply xmm_rexec_gen_correct; eauto. Qed. +Lemma guided_thrd_preserve cmt dtrmt + (STEP : WCore.guided_step cmt X (WCore.X_start X dtrmt) X') : + threads_set' ≡₁ threads_set. +Proof using. + unfold WCore.guided_step in STEP. + destruct STEP as (e0 & l0 & COND). + destruct COND. + unfold WCore.add_event in gsg_add_step. + destruct gsg_add_step + as (r & R1 & w & W1 & W2 & gsg_add_step). + destruct gsg_add_step. + rewrite add_event_threads. + reflexivity. +Qed. + +Lemma reex_thrd_preserve f dtrmt cmt thrdle + (STEP : WCore.reexec_gen X X' f dtrmt cmt thrdle) : + threads_set' ≡₁ threads_set. +Proof using. + destruct STEP. + assert (RT : ((WCore.guided_step cmt X')* ≡ (WCore.guided_step cmt X')⁺ ∪ eq)). + { split; intros x y COND. + { assert (RTH : (WCore.guided_step cmt X')* x y <-> x = y \/ (WCore.guided_step cmt X')⁺ x y). + { clear; split; ins; desf; vauto; + induction H; desf; vauto. } + apply RTH in COND. + desf; vauto. } + assert (RTH : (WCore.guided_step cmt X')* x y <-> (WCore.guided_step cmt X')⁺ x y \/ x = y). + { clear; split; ins; desf; vauto; + induction H; desf; vauto. } + unfold union in COND. + apply RTH in COND; vauto. } + apply RT in reexec_steps. + unfold union in reexec_steps. + destruct reexec_steps + as [reexec_steps | reexec_steps]. + { assert (TST : threads_set ≡₁ + Execution.threads_set (WCore.G (WCore.X_start X dtrmt))). + { reflexivity. } + rewrite TST. + apply clos_trans_ind with + (R := WCore.guided_step cmt X') + (a := X') (x := (WCore.X_start X dtrmt)). + { intros x y COND. + unfold WCore.guided_step in COND. + destruct COND as (e0 & l0 & COND). + destruct COND. + unfold WCore.add_event in gsg_add_step. + destruct gsg_add_step + as (r & R1 & w & W1 & W2 & gsg_add_step). + destruct gsg_add_step. + rewrite add_event_threads. + reflexivity. } + { intros x y z COND1 IH1 COND2 IH2. + rewrite IH2; vauto. } + vauto. } + assert (TST : threads_set ≡₁ + Execution.threads_set (WCore.G (WCore.X_start X dtrmt))). + { reflexivity. } + rewrite TST. + rewrite reexec_steps; vauto. +Qed. + End OtherStepInvariants. Lemma xmm_step_correct_ind X1 X2