Proof using.
induction l; simpl.
- intuition.
- intros. repeat break_match; intuition; subst; simpl in *; intuition eauto.
+ do_bool. destruct (clientId_eq_dec (eClient e) (eClient a)).
* assert (eId a <= eId e).
{ repeat find_rewrite. auto using has_key_intro.
}
{ find_apply_lem_hyp le_lt_or_eq. break_or_hyp.
- specialize (IHl _ ltac:(eauto)).
match goal with
| [ |- context [deduplicate_log' _ ?ks] ] =>
specialize (IHl ks)
end.
forward IHl.
{ intuition.
repeat find_rewrite. rewrite get_set_same in *. find_injection. auto.
}
concludes.
forward IHl.
{ intuition auto using has_key_different_id_false with *. }
concludes.
break_exists_exists. intuition.
- eauto.
}
* specialize (IHl _ ltac:(eauto)).
match goal with
| [ |- context [deduplicate_log' _ ?ks] ] =>
specialize (IHl ks)
end.
forward IHl.
{ intuition.
repeat find_rewrite. rewrite get_set_diff in * by auto. auto.
}
concludes.
forward IHl.
{ intuition auto using has_key_different_client_false with *. }
concludes.
break_exists_exists. intuition.
+ do_bool. assert (n < eId e) by auto. omega.
+ do_bool. apply IHl; auto.
intros.
destruct (clientId_eq_dec (eClient e) (eClient a)).
* assert (eId e <> eId a).
{ intro. repeat find_rewrite.
assert (n < eId a) by auto. omega.
}
intuition auto using has_key_different_id_false with *.
* intuition auto using has_key_different_client_false with *.
+ destruct (clientId_eq_dec (eClient e) (eClient a)).
* assert (eId a <= eId e).
{ repeat find_rewrite. auto using has_key_intro.
}
{ find_apply_lem_hyp le_lt_or_eq. break_or_hyp.
- specialize (IHl _ ltac:(eauto)).
match goal with
| [ |- context [deduplicate_log' _ ?ks] ] =>
specialize (IHl ks)
end.
forward IHl.
{ intuition.
repeat find_rewrite. rewrite get_set_same in *. find_injection. auto.
}
concludes.
forward IHl.
{ intuition auto using has_key_different_id_false with *. }
concludes.
break_exists_exists. intuition.
- eauto.
}
* specialize (IHl _ ltac:(eauto)).
match goal with
| [ |- context [deduplicate_log' _ ?ks] ] =>
specialize (IHl ks)
end.
forward IHl.
{ intuition.
repeat find_rewrite. rewrite get_set_diff in * by auto. auto.
}
concludes.
forward IHl.
{ intuition auto using has_key_different_client_false with *. }
concludes.
break_exists_exists. intuition.
Qed.

(* Specifications: *)
Lemma deduplicate_log_In :
forall l e,
In e l ->
(forall id',
before_func (has_key (eClient e) id') (has_key (eClient e) (eId e)) l ->
id' <= eId e) ->
exists e',
eClient e' = eClient e /\
eId e' = eId e /\
In e' (deduplicate_log l).