Proof using.
intros.
find_copy_apply_lem_hyp doLeader_same_log.
unfold doLeader in *.
break_match; repeat break_let; repeat tuple_inversion; simpl in *;
try solve [
eapply log_matching_state_same_packet_subset; eauto; intros;
try use_packet_subset_clear;
match goal with
| [ H : _ |- _ ] => rewrite H; solve [break_if; subst; auto]
end].
unfold log_matching_nw.
intuition.
- repeat find_higher_order_rewrite.
rewrite if_sum_bool_fun_comm  in *.
repeat find_rewrite. match goal with H : log _ = log _ |- _ => clear H end.
unfold log_matching in *. intuition.
use_packet_subset_clear.
+ unfold log_matching_nw in *. intuition.
use_nw_invariant.
break_if;
match goal with
| [ _ : eIndex ?e = eIndex ?e',
H : forall _ _ _, In _ _ -> _ |- context [(?h : name) ] ] =>
specialize (H h e e')
end; repeat concludes; intuition.
+ simpl in *.
shouldSend_true.
unfold log_matching_hosts in *.
repeat do_in_map. find_inversion.
unfold replicaMessage in *. subst. simpl in *.
find_inversion.
break_if; repeat do_elim; repeat find_rewrite.
match goal with
| [ H : forall _ _, entries_match _ _,
_ : eIndex ?e1 = eIndex ?e2 |- _ ] =>
eapply H with (e':=e1)(e:=e2); eauto
end.
- repeat find_higher_order_rewrite.
rewrite if_sum_bool_fun_comm  in *.
repeat find_rewrite. match goal with H : log _ = log _ |- _ => clear H end.
unfold log_matching in *. intuition.
use_packet_subset_clear.
+ unfold log_matching_nw in *.
use_nw_invariant. simpl in *.
break_if; subst;
use_log_matching_nw_host;
repeat concludes; intuition.
+ shouldSend_true.
repeat do_in_map. subst. simpl in *. do 2 find_inversion.
simpl.
unfold log_matching_hosts in *. intuition.
rewrite <- if_sum_bool_fun_comm with (f:= log) in *.
rewrite <- if_sum_bool_fun_comm with (f:= nwState net) in *.
do_elim. simpl in *. unfold getNextIndex in *.
simpl in *.
match goal with
| [ H : forall _ _, 1 <= _ <= _ -> _ |- context [eIndex _ = ?x] ] =>
remember (x) as index; specialize (H leaderId index); forward H
end.
* intuition; try (destruct index; intuition; omega).
match goal with
| _ : eIndex ?e > index, _ : In ?e ?l |- _ =>
pose proof maxIndex_is_max l e
end. unfold logs_sorted in *. intuition.
match goal with
| H : logs_sorted_host _ |- _ => specialize (H leaderId)
end. repeat concludes. omega.
* { concludes. break_exists. intuition. eexists; intuition eauto.
- break_match.
+ f_equal. eapply findAtIndex_uniq_equal; eauto. repeat find_rewrite; auto.
+ exfalso. eapply findAtIndex_None; eauto.
unfold logs_sorted in *. intuition.
- break_if; auto.
unfold entries_match in *.
subst.
match goal with
| [Hentries : forall _ _ _ _ _, eIndex _ = eIndex _ -> _,
_ : eIndex ?e1 = eIndex ?e2,
_ : In ?x (log (_ _ ?leader)) |-
In ?x (log (_ _ ?h)) ] =>
specialize (Hentries leader h e1 e2 x)
end.
assert (eIndex x <= eIndex e1) by omega.
repeat conclude. intuition.
}
- use_packet_subset_clear; unfold log_matching in *; intuition.
+ unfold log_matching_nw in *; intuition. use_nw_invariant.
+ shouldSend_true.
repeat do_in_map. subst. simpl in *. find_inversion.
unfold log_matching_hosts in *; intuition. find_inversion.
match goal with
| [ H : forall _ _, _ <= _ <= _ -> _,
H' : ?i <= maxIndex _ |- _ ] =>
match type of H' with
| context [ nwState _ ?h ] =>
specialize (H h i)
end;
conclude H ltac:(split; try omega; eapply le_trans; eauto using findGtIndex_max)
end.
break_exists;
eexists;
intuition; eauto; eauto using findGtIndex_sufficient.
unfold logs_sorted in *.
apply findGtIndex_sufficient; intuition.
- use_packet_subset_clear.
+ unfold log_matching, log_matching_nw in *; intuition. use_nw_invariant.
+ shouldSend_true. simpl in *. clean.
repeat do_in_map. subst. simpl in *. find_inversion. do_elim.
- use_packet_subset; use_packet_subset_clear.
+ unfold log_matching, log_matching_nw in *; intuition.
use_log_matching_nw_nw.
+ shouldSend_true.
unfold log_matching, log_matching_nw in *. intuition.
unfold logs_sorted in *. intuition.
match goal with
| |- In _ ?es =>
assert (sorted entries') by eauto
end.
use_nw_invariant.
simpl in *. clean.
repeat do_in_map. simpl in *. do 2 (find_inversion; simpl in *).
repeat do_elim.
use_log_matching_nw_host_keep; repeat concludes; intuition.
match goal with
| [ H : forall _, _ < _ <= _ -> _,
_ : eIndex ?e3 <= eIndex _
|- _ ] =>
specialize (H (eIndex e3));
conclude H ltac:(split; auto; repeat find_rewrite;
eapply le_trans; eauto; apply maxIndex_is_max; intuition)
end.
break_exists. intuition.
match goal with
| [ _ : In ?x _,
_ : eIndex ?x = eIndex ?e3,
_ : eIndex ?e3 <= eIndex _ |- _ ] =>
eapply rachet with (x' := x); eauto
end.
match goal with
| H : forall _, eIndex _ <= eIndex _ -> _ |- _ =>
apply H; eauto; omega
end.
+ shouldSend_true.
unfold log_matching, log_matching_nw in *. intuition.
use_nw_invariant.
simpl in *. clean.
repeat do_in_map. simpl in *. do 2 (find_inversion; simpl in *).
repeat do_elim.
use_log_matching_nw_host; repeat concludes; intuition.
unfold logs_sorted in *.
apply findGtIndex_sufficient; intuition eauto.
+ shouldSend_true. simpl in *. clean.
repeat do_in_map. do 3 (find_inversion; simpl in *).
repeat do_elim.
unfold logs_sorted in *.
apply findGtIndex_sufficient; intuition eauto.
- use_packet_subset; use_packet_subset_clear.
+ unfold log_matching, log_matching_nw in *; intuition.
use_log_matching_nw_nw.
+ shouldSend_true.
unfold log_matching, log_matching_nw in *. intuition.
use_nw_invariant.
simpl in *. clean.
repeat do_in_map. simpl in *. do 2 (find_inversion; simpl in *).
repeat do_elim.
use_log_matching_nw_host; repeat concludes; intuition.
break_exists. intuition.
match goal with
| _ : eIndex ?x = eIndex ?y |- context [ ?y ] =>
cut (x = y); [intros; subst; intuition|]
end.
eapply uniqueIndices_elim_eq; eauto.
+ shouldSend_true.
unfold log_matching, log_matching_nw in *. intuition.
use_nw_invariant.
simpl in *. clean.
repeat do_in_map. simpl in *. do 2 (find_inversion; simpl in *).
break_match.
* repeat do_elim. find_rewrite.
use_log_matching_nw_host. intuition.
match goal with
| H : forall _, _ -> In _ ?es -> In _ ?es' |- eTerm ?e = eTerm ?e' =>
assert (In e es') by (apply H; auto; omega)
end.
match goal with
| _ : eIndex ?x = eIndex ?y |- context [ ?y ] =>
cut (x = y); [intros; subst; intuition|]
end.
eapply uniqueIndices_elim_eq; eauto.
* exfalso. repeat do_elim.
unfold log_matching_hosts in *. intuition.
repeat find_rewrite.
match goal with
| _ : findAtIndex (log (nwState _ ?h)) ?i = None,
H : forall _ _, _ <= _ <= _ -> _ |- _ =>
specialize (H h i)
end. intuition.
forwards;
[match goal with
| H : forall _, In _ _ -> _ < _ |- context [ (?e : entry) ] =>
specialize (H e)
end; concludes; omega|].
concludes.
unfold logs_sorted in *.
forwards;
[find_apply_lem_hyp maxIndex_is_max; intuition; omega|].
concludes. break_exists. intuition.
eapply findAtIndex_None; intuition eauto.
+ shouldSend_true. simpl in *. clean.
repeat do_in_map. simpl in *.
do 3 (find_inversion; simpl in *).
repeat do_elim.
repeat find_rewrite.
unfold logs_sorted in *.
match goal with
[ |- context [findAtIndex ?l (eIndex ?e) ] ] =>
assert (findAtIndex l (eIndex e) = Some e); (intuition eauto using findAtIndex_intro)
end.
break_match; congruence.
- use_packet_subset; use_packet_subset_clear.
+ unfold log_matching, log_matching_nw in *; intuition.
use_log_matching_nw_nw.
+ shouldSend_true.
unfold log_matching, log_matching_nw in *. intuition.
use_nw_invariant.
repeat do_in_map. do 3 (find_inversion; simpl in *).
repeat do_elim.
use_log_matching_nw_host. intuition. break_exists.
unfold logs_sorted in *.
intuition. repeat find_reverse_rewrite.
match goal with
[ |- context [findAtIndex ?l (eIndex ?e) ] ] =>
assert (findAtIndex l (eIndex e) = Some e) by (intuition eauto using findAtIndex_intro)
end. repeat break_match; congruence.
+ shouldSend_true.
unfold log_matching, log_matching_nw in *. intuition.
use_nw_invariant.
repeat do_in_map. do 3 (find_inversion; simpl in *).
repeat do_elim.
use_log_matching_nw_host. intuition. break_exists.
intuition. repeat find_reverse_rewrite.
unfold logs_sorted in *.
match goal with
[ |- context [findAtIndex ?l (eIndex ?e) ] ] =>
assert (findAtIndex l (eIndex e) = Some e) by (intuition eauto using findAtIndex_intro)
end. repeat break_match; congruence.
+ shouldSend_true. simpl in *. clean.
repeat do_in_map. simpl in *.
do 3 (find_inversion; simpl in *).
repeat do_elim.
Qed.
Ltac do_doLeader_same_log :=
match goal with
| [ H : doLeader _ _ = (_, ?d, _) |- _ ] =>
erewrite doLeader_same_log with (st':=d) in *; try apply H; eauto
end.
Ltac do_tryToBecomeLeader_same_log :=
match goal with
| [ H : tryToBecomeLeader _ _ = (?d, _) |- _ ] =>
erewrite tryToBecomeLeader_same_log with (st':=d); try apply H; eauto
end.

Lemma doLeader_doesn't_touch_log :
forall d h out d' ms,
doLeader d h = (out, d', ms) ->
log d' = log d.