Definition input_correct (tr : list (name * (raft_input + list raft_output))) : Prop :=
    (forall client id i i' h h',
       In (h, inl (ClientRequest client id i)) tr ->
       In (h', inl (ClientRequest client id i')) tr ->
       i = i').

(* Specifications: *)
Lemma in_input_trace_get_input : forall tr e, input_correct tr -> in_input_trace (eClient e) (eId e) (eInput e) tr -> get_input tr (eClient e, eId e) = Some (eInput e).
Lemma get_output_in_output_trace : forall tr client id o, get_output tr (client, id) = Some o -> in_output_trace client id o tr.
Lemma deduplicate_partition : forall l xs e ys xs' e' ys', deduplicate_log l = xs ++ e :: ys -> deduplicate_log l = xs' ++ e' :: ys' -> eClient e = eClient e' -> eId e = eId e' -> xs = xs'.
Lemma applied_entries_applied_implies_input_state : forall net e, In e (applied_entries (nwState net)) -> applied_implies_input_state (eClient e) (eId e) (eInput e) net.
Theorem raft_linearizable' : forall failed net tr, input_correct tr -> step_failure_star step_failure_init (failed, net) tr -> exists l tr1 st, equivalent _ (import tr) l /\ exported (get_input tr) (get_output tr) l tr1 /\ step_1_star init st tr1.