Section StateMachineSafety'.
Context {orig_base_params : BaseParams}.
Context {one_node_params : OneNodeParams orig_base_params}.
Context {raft_params : RaftParams orig_base_params}.
Context {rri : raft_refinement_interface}.
Context {lci : leader_completeness_interface}.
Context {aelli : all_entries_leader_logs_interface}.
Context {lmi : log_matching_interface}.
Context {uii : unique_indices_interface}.
Context {aerlli : append_entries_leaderLogs_interface}.
Context {llsi : leaderLogs_sorted_interface}.
Context {lsi : sorted_interface}.
Context {llci : leaderLogs_contiguous_interface}.
Context {lllmi : leaderLogs_entries_match_interface}.
Context {llli : logs_leaderLogs_interface}.
Context {ollpti : one_leaderLog_per_term_interface}.
Context {rlmli : refined_log_matching_lemmas_interface}.
Proof using lmi rri.
intros.
eapply lift_prop; eauto using log_matching_invariant.
Qed.
Proof using lsi rri.
intros.
eapply lift_prop; eauto using logs_sorted_invariant.
Qed.
Proof using lmi rri.
intros.
find_apply_lem_hyp lift_log_matching.
unfold log_matching, log_matching_hosts in *. intuition.
unfold deghost in *. simpl in *.
repeat break_match; eauto.
Qed.
Proof using uii rri.
intros. eapply lift_prop; eauto using UniqueIndices_invariant.
Qed.
Proof using uii rri.
intros.
find_apply_lem_hyp lift_UniqueIndices.
unfold UniqueIndices, uniqueIndices_host_invariant in *.
intuition.
unfold deghost in *. simpl in *. break_match; eauto.
Qed.
Proof using lsi rri.
intros.
find_apply_lem_hyp lift_sorted.
unfold logs_sorted, logs_sorted_host in *.
intuition.
unfold deghost in *. simpl in *. break_match; eauto.
Qed.
Proof using uii lmi aelli lci rri.
unfold state_machine_safety_host'. intros.
find_copy_apply_lem_hyp leader_completeness_invariant.
unfold leader_completeness in *. intuition.
unfold committed in *. break_exists. intuition.
repeat match goal with
| [ H : directly_committed _ ?e |- _ ] =>
try match goal with
| H' : context [ allEntries ] |- _ =>
match type of H' with
| context [ e ] => fail 3
end
end;
let Hnew := fresh "H" in
remember H as Hnew; unfold directly_committed in Hnew;
match goal with
| [ Heq : Hnew = H |- _ ] => clear Heq
end
end.
break_exists. intuition.
assert (NoDup nodes) by eauto using all_fin_NoDup.
match goal with
| H : NoDup nodes, _ : NoDup ?l1, _ : NoDup ?l2 |- _ =>
eapply pigeon with (l := nodes) (sub1 := l1) (sub2 := l2) in H
end; eauto using all_fin_all, name_eq_dec, div2_correct.
break_exists.
intuition.
repeat find_apply_hyp_hyp.
do 2 find_apply_lem_hyp all_entries_leader_logs_invariant; auto.
intuition; try solve [break_exists; intuition; find_false; eauto].
match goal with
| [ _ : eIndex ?e <= eIndex ?x, _ : eIndex ?e' <= eIndex ?x',
_ : In ?x ?l |- ?e = ?e' ] =>
cut (In e l /\ In e' l)
end;
[intros; intuition;
eapply uniqueIndices_elim_eq;
eauto using lift_uniqueIndices_log|].
intuition;
match goal with
| _ : In ?e ?l, _ : eIndex ?e <= eIndex ?x, _ : In ?x ?l' |- In ?e ?l' =>
assert (entries_match l l') as Hem by eauto using lift_entries_match;
specialize (Hem x x e)
end; intuition.
Qed.
Ltac copy_eapply_prop_hyp P Q :=
match goal with
| [ H : context [ P ], H' : context [ Q ] |- _ ] =>
copy_eapply H H'
end.
Proof using rlmli.  (* by log matching, annoying because of refinement *)
intros.
find_apply_lem_hyp entries_contiguous_nw_invariant.
unfold entries_contiguous_nw in *. eauto.
Qed.
Proof using.
unfold deghost.
simpl.
intros.
eexists; intuition eauto.
apply in_map_iff. eexists; eauto.
Qed.
Proof using uii lmi rri.
intros.
pose proof lift_uniqueIndices_log net h; intuition.
find_copy_apply_lem_hyp lift_log_matching.
unfold log_matching, log_matching_nw in *.
intuition.
find_apply_lem_hyp exists_deghosted_packet.
break_exists.
intuition.
subst. destruct p; simpl in *; subst.
eapply_prop_hyp In In; simpl; eauto. intuition.
match goal with
| H : forall _ _ _, _ |- _ =>
specialize (H h e' e)
end; intuition.
repeat break_match. simpl in *. repeat find_rewrite. simpl in *.
intuition.
match goal with
| H : forall _, _ <= _ -> _ |- _ =>
specialize (H e'); conclude H ltac:(lia)
end. intuition.
eapply rachet; eauto.
Qed.
Proof using.
intros; induction l1; simpl in *; intuition.
subst_max. specialize (H2 e').
assert (In e' (l1 ++ l2)) by auto with datatypes.
concludes. intuition.
Qed.
Proof using.
induction l; intros; simpl in *; intuition;
subst; break_match; intuition; subst; intuition.
Qed.
Ltac get_invariant i :=
match goal with
| H : refined_raft_intermediate_reachable _ |- _ =>
copy_apply i H
end.

Lemma in_not_nil :
forall A (l : list A) x,
In x l ->
l <> nil.