Require Export Coq.Logic.Classical.
Require Export Coq.Logic.FunctionalExtensionality.
Require Export Coq.Classes.Equivalence.
Require Export Coq.Classes.Morphisms.
Class RandomOracle: Type := {
ro_question: Type;
ro_answer: ro_question -> Type;
ro_default_question: ro_question;
ro_default_answer: ro_answer ro_default_question
}.
Definition RandomQA {ora: RandomOracle}: Type := {q: ro_question & ro_answer q}.
Definition RandomHistory {ora: RandomOracle}: Type := {h: nat -> option RandomQA | forall x y, x < y -> h x = None -> h y = None}.
Definition history_get {ora: RandomOracle} (h: RandomHistory) (n: nat) := proj1_sig h n.
Coercion history_get: RandomHistory >-> Funclass.
Tactic Notation "history_extensionality" ident(x) :=
match goal with
[ |- ?X = ?Y ] =>
apply history_extensionality; intro x
end.
Definition fin_history {ora: RandomOracle} (h: list RandomQA) : RandomHistory.
exists (fun n => nth_error h n).
intros.
rewrite nth_error_None_iff in H0 |- *.
omega.
Defined.
Definition inf_history {ora: RandomOracle} (h: nat -> RandomQA) : RandomHistory.
exists (fun n => Some (h n)).
intros.
congruence.
Defined.
Definition fstn_history {ora: RandomOracle} (n: nat) (h: RandomHistory) : RandomHistory.
exists (fun m => if le_lt_dec n m then None else h m).
intros.
destruct (le_lt_dec n x), (le_lt_dec n y); try congruence.
+ omega.
+ apply (history_sound1 h x y); auto; omega.
Defined.
Definition history_coincide {ora: RandomOracle} (n: nat) (h1 h2: RandomHistory): Prop :=
forall m, m < n -> h1 m = h2 m.
(* Definition history_cons {ora: RandomOracle} (h1: RandomHistory) (a: RandomQA) (h2: RandomHistory): Prop := exists n, history_coincide n h1 h2 /\ h1 n = None /\ h2 n = Some a /\ h2 (S n) = None. *)
Definition history_app {ora: RandomOracle} (h1 h2 h: RandomHistory): Prop :=
exists n,
h1 n = None /\
history_coincide n h1 h /\
(forall m, h (m + n) = h2 m).
Definition is_fin_history {ora: RandomOracle} (h: RandomHistory): Prop :=
exists n, h n = None.
Definition is_inf_history {ora: RandomOracle} (h: RandomHistory): Prop :=
forall n, h n <> None.
Definition is_n_history {ora: RandomOracle} (n: nat) (h: RandomHistory): Prop :=
h n = None /\ forall n', n' < n -> h n' <> None.
Definition is_at_least_n_history {ora: RandomOracle} (n: nat) (h: RandomHistory): Prop :=
forall n', n' < n -> h n' <> None.
Definition prefix_history {ora: RandomOracle} (h1 h2: RandomHistory): Prop :=
forall n, h1 n = None \/ h1 n = h2 n.
Definition strict_prefix_history {ora: RandomOracle} (h1 h2: RandomHistory): Prop :=
prefix_history h1 h2 /\ exists n, h1 n <> h2 n.
Definition n_bounded_prefix_history {ora: RandomOracle} (m: nat) (h1 h2: RandomHistory): Prop :=
forall n, (h1 n = None /\ h2 (n + m) = None) \/ h1 n = h2 n.
Definition n_conflict_history {ora: RandomOracle} (n: nat) (h1 h2: RandomHistory): Prop :=
match h1 n, h2 n with
| Some a1, Some a2 => projT1 a1 <> projT1 a2
| Some _, None => True
| None, Some _ => True
| None, None => False
end.
Definition conflict_history {ora: RandomOracle} (h1 h2: RandomHistory): Prop :=
exists n, history_coincide n h1 h2 /\ n_conflict_history n h1 h2.
Definition strict_conflict_history {ora: RandomOracle} (h1 h2: RandomHistory): Prop :=
exists n,
history_coincide n h1 h2 /\
match h1 n, h2 n with
| Some a1, Some a2 => projT1 a1 <> projT1 a2
| _, _ => False
end.
(* TODO: put this in lib *)
Definition isSome {A} (o: option A) := match o with Some _ => True | None => False end.
Definition history_set_consi {ora: RandomOracle} (P: RandomHistory -> Prop) : Prop :=
forall h1 h2,
conflict_history h1 h2 ->
P h1 ->
P h2 ->
False.
Class LegalHistoryAntiChain {ora: RandomOracle} (d: RandomHistory -> Prop) : Prop := {
rand_consi: history_set_consi d
}.
Record HistoryAntiChain {ora: RandomOracle}: Type := {
raw_anti_chain: RandomHistory -> Prop;
raw_anti_chain_legal: LegalHistoryAntiChain raw_anti_chain
}.
Definition in_anti_chain {ora: RandomOracle} (d: HistoryAntiChain) (h: RandomHistory): Prop := raw_anti_chain d h.
Coercion in_anti_chain: HistoryAntiChain >-> Funclass.
Definition history_in_anti_chain{ora: RandomOracle} (d: HistoryAntiChain) : Type := {h: RandomHistory | d h}.
Coercion history_in_anti_chain: HistoryAntiChain >-> Sortclass.
Definition history_in_anti_chain_history {ora: RandomOracle} (d: HistoryAntiChain) : history_in_anti_chain d -> RandomHistory := @proj1_sig _ _.
Coercion history_in_anti_chain_history: history_in_anti_chain >-> RandomHistory.
(* Definition join {ora: RandomOracle} {A: Type} (v1 v2 v: RandomVariable A): Prop := forall h, (v1 h = None /\ v2 h = v h) \/ (v2 h = None /\ v1 h = v h).  Definition Forall_RandomHistory {ora: RandomOracle} {A: Type} (P: A -> Prop) (v: RandomVariable A): Prop := forall h, match v h with | None => True | Some a => P a end. *)
Definition singleton_history_anti_chain {ora: RandomOracle} (h: RandomHistory): HistoryAntiChain.
exists (fun h' => forall n, h n = h' n).
constructor.
hnf; intros; simpl in *.
destruct H as [n [? ?]].
specialize (H0 n).
specialize (H1 n).
hnf in H2.
destruct (h n); rewrite <- H0, <- H1 in H2; auto.
Defined.
Definition unit_space_anti_chain {ora: RandomOracle}: HistoryAntiChain := singleton_history_anti_chain (fin_history nil).
Definition filter_anti_chain {ora: RandomOracle} (filter: RandomHistory -> Prop) (d: HistoryAntiChain): HistoryAntiChain.
exists (fun h => d h /\ filter h).
constructor.
destruct d as [d [H]].
hnf; simpl; intros.
apply (H h1 h2 H0); tauto.
Defined.
Definition covered_by {ora: RandomOracle} (h: RandomHistory) (d: HistoryAntiChain): Prop :=
exists h', prefix_history h' h /\ d h'.
Definition n_bounded_covered_by {ora: RandomOracle} (n: nat) (h: RandomHistory) (d: HistoryAntiChain): Prop :=
exists h', n_bounded_prefix_history n h' h -> d h'.
Definition future_anti_chain {ora: RandomOracle} (present future: HistoryAntiChain): Prop :=
forall h, future h -> covered_by h present.
Definition n_bounded_future_anti_chain {ora: RandomOracle} (n: nat) (present future: HistoryAntiChain): Prop :=
forall h, future h -> n_bounded_covered_by n h present.
Definition bounded_future_anti_chain {ora: RandomOracle} (present future: HistoryAntiChain): Prop :=
exists n, n_bounded_future_anti_chain n present future.
Definition same_covered_anti_chain {ora: RandomOracle} (d1 d2: HistoryAntiChain): Prop :=
forall h, is_inf_history h ->
((exists h', (prefix_history h' h \/ strict_conflict_history h' h) /\ d1 h') <->
(exists h', (prefix_history h' h \/ strict_conflict_history h' h) /\ d2 h')).
Instance same_covered_eq {ora: RandomOracle}: Equivalence same_covered_anti_chain.

Lemma proj_in_anti_chain_unique {ora: RandomOracle}: forall (d: HistoryAntiChain) h1 h2 h3,
prefix_history h1 h3 ->
prefix_history h2 h3 ->
covered_by h2 d ->
d h1 ->
prefix_history h1 h2.