Ltac do_state_same_packet_subset :=
  repeat find_inversion;
  eapply log_matching_state_same_packet_subset; eauto; intros; simpl in *;
  try (try find_higher_order_rewrite; break_if; subst; auto);
  try (try find_apply_hyp_hyp; intuition).Ltac assert_do_leader :=
  match goal with
    | [ _ : nwPackets ?net = _,
            H : doLeader ?s ?h = (?out ?s' ?ms) |- _ ] =>
      match goal with
        | [ |-
            log_matching {|
                nwPackets := map ?f (ms) ++ ?xs ++ ?ys;
                nwState := _ |}
          ] =>
          assert (log_matching {| nwPackets :=
                                    xs ++ ys;
                                  nwState := fun nm =>
                                               if name_eq_dec nm h then s
                                               else nwState net nm |})
        | [ |-
            log_matching {|
                nwPackets := ?p :: map ?f (ms) ++ ?xs ++ ?ys;
                nwState := _ |}
          ] =>
          assert (log_matching {| nwPackets :=
                                    p :: xs ++ ys;
                                  nwState := fun nm =>
                                               if name_eq_dec nm h then s
                                               else nwState net nm |})
        | [ |-
            log_matching {|
                nwPackets := map ?f (?l1 ++ ms) ++ ?xs ++ ?ys;
                nwState := _ |}
          ] =>
          assert (log_matching {| nwPackets :=
                                    map f l1 ++ xs ++ ys;
                                  nwState := fun nm =>
                                               if name_eq_dec nm h then s
                                               else nwState net nm |})
        | [ |-
            log_matching {|
                nwPackets := ?p ::map ?f (?l1 ++ ms) ++ ?xs ++ ?ys;
                nwState := _ |}
          ] =>
          assert (log_matching {| nwPackets :=
                                    p :: map f l1 ++ xs ++ ys;
                                  nwState := fun nm =>
                                               if name_eq_dec nm h then s
                                               else nwState net nm |})
        | [ |-
            log_matching {|
                nwPackets := map ?f (ms ++ ?l1) ++ ?xs ++ ?ys;
                nwState := _ |}
          ] =>
          assert (log_matching {| nwPackets :=
                                    map f l1 ++ xs ++ ys;
                                  nwState := fun nm =>
                                               if name_eq_dec nm h then s
                                               else nwState net nm |})
        | [ |-
            log_matching {|
                nwPackets := map ?f (?l1 ++ ?l2 ++ ms) ++ ?xs ++ ?ys;
                nwState := _ |}
          ] =>
          assert (log_matching {| nwPackets :=
                                    map f (l1 ++ l2) ++ xs ++ ys;
                                  nwState := fun nm =>
                                               if name_eq_dec nm h then s
                                               else nwState net nm |})
        | [ |-
            log_matching {|
                nwPackets := map ?f (?l1 ++ ms ++ ?l2) ++ ?xs ++ ?ys;
                nwState := _ |}
          ] =>
          assert (log_matching {| nwPackets :=
                                    map f (l1 ++ l2) ++ xs ++ ys;
                                  nwState := fun nm =>
                                               if name_eq_dec nm h then s
                                               else nwState net nm |})
        | [ |-
            log_matching {|
                nwPackets := map ?f (ms ++ ?l1 ++ ?l2) ++ ?xs ++ ?ys;
                nwState := _ |}
          ] =>
          assert (log_matching {| nwPackets :=
                                    map f (l1 ++ l2) ++ xs ++ ys;
                                  nwState := fun nm =>
                                               if name_eq_dec nm h then s
                                               else nwState net nm |})
      end
  end.Ltac contradict_leader_sublog :=
    match goal with
      | H : eIndex _ = S _ |- _ =>
        exfalso; apply S_maxIndex_not_in in H; intuition; apply H; eauto
      | H : S _ = eIndex _ |- _ =>
        symmetry in H; exfalso; apply S_maxIndex_not_in in H; intuition; apply H; eauto
    end.Definition host_independent_log_matching_nw net :=
    (forall p t leaderId prevLogIndex prevLogTerm entries leaderCommit,
      In p (nwPackets net) ->
      pBody p = AppendEntries t leaderId prevLogIndex prevLogTerm entries leaderCommit ->
      (forall i,
         prevLogIndex < i <= maxIndex entries ->
         exists e,
           eIndex e = i /\
           In e entries) /\
      (forall e,
         In e entries ->
         prevLogIndex < eIndex e) /\
      (forall p' t' leaderId' prevLogIndex' prevLogTerm' entries' leaderCommit',
         In p' (nwPackets net) ->
         pBody p' = AppendEntries t' leaderId' prevLogIndex' prevLogTerm' entries' leaderCommit' ->
         (forall e1 e2,
            In e1 entries ->
            In e2 entries' ->
            eIndex e1 = eIndex e2 ->
            eTerm e1 = eTerm e2 ->
            (forall e3,
               prevLogIndex' < eIndex e3 <= eIndex e1 ->
               In e3 entries ->
               In e3 entries') /\
            (forall e3,
               In e3 entries ->
               eIndex e3 = prevLogIndex' ->
               eTerm e3 = prevLogTerm') /\
            (prevLogIndex <> 0 -> prevLogIndex = prevLogIndex' -> prevLogTerm = prevLogTerm')))).

(* Specifications: *)
Lemma host_independent_log_matching_nw_invariant : forall net net', host_independent_log_matching_nw net -> (forall p, is_append_entries (pBody p) -> In p (nwPackets net') -> In p (nwPackets net)) -> host_independent_log_matching_nw net'.