Proof using uii misi smsi lmi lacimi si.
intros. match goal with H : step_failure _ _ _ |- _ => invcs H end; intuition.
- left. unfold RaftNetHandler in *. repeat break_let. subst.
unfold in_applied_entries in *.
break_exists_exists. intuition.
find_inversion.
match goal with
| Hdgs : doGenericServer ?h ?st' = _,
Hdl : doLeader ?st ?h = _, _ :context [update _ (nwState ?net) ?h ?st''] |- _ =>
replace st with (update name_eq_dec (nwState net) h st h) in Hdl by eauto using update_eq;
replace st' with (update name_eq_dec (update name_eq_dec (nwState net) h st) h st' h) in Hdgs by eauto using update_eq;
let H := fresh "H" in
assert (update name_eq_dec (nwState net) h st'' =
update name_eq_dec (update name_eq_dec (update name_eq_dec (nwState net) h st) h st') h st'') as H by (repeat rewrite update_overwrite; auto); unfold data in *; simpl in *; rewrite H in *; clear H
end.
find_copy_eapply_lem_hyp RIR_handleMessage; eauto.
find_eapply_lem_hyp RIR_doLeader; simpl in *; eauto.
simpl in *.
find_copy_apply_lem_hyp handleMessage_applied_entries; repeat find_rewrite; eauto;
try solve [destruct p; simpl in *; intuition].
find_copy_apply_lem_hyp doLeader_appliedEntries.
find_eapply_lem_hyp doGenericServer_applied_entries; eauto.
break_exists. intuition.
unfold ghost_data in *. simpl in *.
repeat find_rewrite.
do_in_app. intuition.
+ contradict H1. eexists; intuition; repeat find_rewrite; eauto.
+ find_apply_hyp_hyp. break_exists. intuition.
eapply handleMessage_log with (h'' := x1); eauto;
[destruct p; simpl in *; repeat find_rewrite; intuition|].
update_destruct; subst; rewrite_update; eauto.
find_apply_lem_hyp doLeader_log. repeat find_rewrite. auto.
- unfold RaftInputHandler in *. repeat break_let. subst.
unfold in_applied_entries in *.
break_exists_exists. intuition.
find_inversion.
match goal with
| Hdgs : doGenericServer ?h ?st' = _,
Hdl : doLeader ?st ?h = _, _ :context [update _ (nwState ?net) ?h ?st''] |- _ =>
replace st with (update name_eq_dec (nwState net) h st h) in Hdl by eauto using update_eq;
replace st' with (update name_eq_dec (update name_eq_dec (nwState net) h st) h st' h) in Hdgs by eauto using update_eq;
let H := fresh "H" in
assert (update name_eq_dec (nwState net) h st'' =
update name_eq_dec (update name_eq_dec (update name_eq_dec (nwState net) h st) h st') h st'') as H by (repeat rewrite update_overwrite; auto); unfold data in *; simpl in *; rewrite H in *; clear H
end.
find_copy_eapply_lem_hyp RIR_handleInput; eauto.
find_eapply_lem_hyp RIR_doLeader; simpl in *; eauto.
simpl in *.
find_copy_apply_lem_hyp handleInput_applied_entries; repeat find_rewrite; eauto;
try solve [destruct p; simpl in *; intuition].
find_copy_apply_lem_hyp doLeader_appliedEntries.
find_eapply_lem_hyp doGenericServer_applied_entries; eauto.
break_exists. intuition.
unfold ghost_data in *. simpl in *.
repeat find_rewrite.
match goal with
| H : In _ _ -> False |- _ => clear H
end.
do_in_app. intuition.
+ find_false. eexists; intuition; repeat find_rewrite; eauto.
+ find_apply_hyp_hyp. break_exists. intuition.
find_apply_lem_hyp doLeader_log.
match goal with
| H : _ |- _ =>
eapply handleInput_log with (h' := x1) in H
end; eauto;
[|update_destruct; subst; eauto; rewrite_update; repeat find_rewrite; eauto].
intuition; subst;
repeat find_rewrite; eauto.
- find_false.
unfold in_applied_entries in *.
break_exists_exists. intuition.
match goal with
| H : In _ (applied_entries _) |- In _ (applied_entries ?sig) =>
erewrite applied_entries_log_lastApplied_same with (sigma := sig) in H
end; auto;
intros; simpl in *; update_destruct_max_simplify; auto.
Qed.

(* Specifications: *)
Lemma in_applied_entries_step_applied_implies_input_state :
forall (s : list name * network) s' tr o,
refl_trans_1n_trace step_failure step_failure_init s tr ->
~ in_applied_entries client id (snd s) ->
step_failure s s' o ->
in_applied_entries client id (snd s') ->
(exists e,
eClient e = client /\
eId e = id /\
applied_implies_input_state client id (eInput e) (snd s)) \/
exists h o' inp,
o = (h, inl (ClientRequest client id inp)) :: o'.