aneris.aneris_lang.lib.util
From iris.algebra Require Import gmap.
Lemma nat_Z_eq (n : nat) (z : Z) :
(0 ≤ z)%Z → n = Z.to_nat z :> nat → n = z :> Z.
Proof. lia. Qed.
Section gset_map.
Context `{EqDecision A, !Countable A, !EqDecision B, !Countable B}.
Definition gset_map (f : A → B) (g : gset A) : gset B :=
list_to_set (f <$> elements g).
Lemma gset_map_empty f : gset_map f ∅ = ∅.
Proof. by rewrite /gset_map elements_empty /=. Qed.
Lemma gset_map_singleton f a : gset_map f {[a]} = {[f a]}.
Proof. by rewrite /gset_map elements_singleton /= right_id_L. Qed.
Lemma gset_map_union f g g' :
gset_map f (g ∪ g') = gset_map f g ∪ gset_map f g'.
Proof.
revert g'.
pattern g.
match goal with |- ?F g => simpl; apply (set_ind_L F) end; set_solver.
Qed.
Lemma gset_map_correct1 f g : ∀ a, a ∈ g → (f a) ∈ gset_map f g.
Proof.
pattern g.
match goal with |- ?F g => simpl; apply (set_ind_L F) end; set_solver.
Qed.
Lemma gset_map_correct2 f g : ∀ b, b ∈ gset_map f g → ∃ a, b = f a ∧ a ∈ g.
Proof.
pattern g.
match goal with |- ?F g => simpl; apply (set_ind_L F) end; set_solver.
Qed.
End gset_map.
Section find_one_maximal.
Context {A B : Type} (f : A → B)
(R : relation B) `{!RelDecision R} `{!Transitive R}
(S : relation B) `{!Transitive S} `{!Reflexive S}
(HRS : ∀ a b, R a b → S a b)
(HSR : ∀ a b, S a b → a = b ∨ R a b)
(HRir : ∀ a, ¬ R a a)
(HRex : ∀ a b, R a b → R b a → False)
(HSR_trans : ∀ a b c, S a b → R b c → R a c).
Fixpoint find_one_maximal (candidate : A) (l : list A) :=
match l with
| [] => candidate
| a :: l' => if bool_decide (R (f candidate) (f a)) then
find_one_maximal a l'
else
find_one_maximal candidate l'
end.
Lemma find_one_maximal_rel c l : S (f c) (f (find_one_maximal c l)).
Proof.
revert c; induction l as [|a l IHl]; intros c; first done.
destruct (decide (R (f c) (f a))).
- rewrite /= bool_decide_eq_true_2 //; by etrans; eauto.
- rewrite /= bool_decide_eq_false_2 //.
Qed.
Lemma find_one_maximal_maximal c l y :
y ∈ l → ¬ R (f (find_one_maximal c l)) (f y).
Proof.
revert c; induction l as [|a l IHl]; intros c; first by inversion 1.
intros [->|Hy]%elem_of_cons.
- destruct (decide (R (f c) (f a))) as [|Hnot].
+ rewrite /= bool_decide_eq_true_2 //.
pose proof (find_one_maximal_rel a l) as [ <- | ?]%HSR;
first by apply HRir.
intros ?; eapply HRex; eauto.
+ rewrite /= bool_decide_eq_false_2 //.
intros ?.
apply Hnot.
eapply HSR_trans; eauto using find_one_maximal_rel.
- destruct (decide (R (f c) (f a))) as [|Hnot].
+ rewrite /= bool_decide_eq_true_2 //.
intros ?; eapply IHl; eauto.
+ rewrite /= bool_decide_eq_false_2 //.
intros ?; eapply IHl; eauto.
Qed.
Lemma find_one_maximal_eq_or_elem_of c l :
find_one_maximal c l = c ∨ find_one_maximal c l ∈ l.
Proof.
revert c; induction l as [|a l IHl]; intros c; first by left.
destruct (decide (R (f c) (f a))) as [|Hnot].
- rewrite /= bool_decide_eq_true_2 //.
destruct (IHl a) as [->|]; by right; constructor.
- rewrite /= bool_decide_eq_false_2 //.
destruct (IHl c) as [->|]; first by left.
by right; constructor.
Qed.
Context (HNRS : ∀ a b, ¬ R a b → S b a)
(min : A)
(Hmin : ∀ a, S (f min) a).
Definition sup l := find_one_maximal min l.
Lemma sup_UB l a : a ∈ l → S (f a) (f (sup l)).
Proof. by intros Hl; apply HNRS; apply find_one_maximal_maximal. Qed.
Lemma sup_LUB l u : (∀ a, a ∈ l → S (f a) (f u)) → (S (f (sup l)) (f u)).
Proof.
intros Hu.
rewrite /sup.
destruct (find_one_maximal_eq_or_elem_of min l) as [->|];
first by apply Hmin.
by apply Hu.
Qed.
Context `{!RelDecision S} `{!EqDecision A} `{!AntiSymm eq S} `{!Inj eq eq f}.
Lemma sup_elem_of a l : a ∈ l → sup l ∈ l.
Proof.
intros Hal.
rewrite /sup.
destruct (find_one_maximal_eq_or_elem_of min l) as [Heq|]; last done.
rewrite Heq.
destruct (decide (S (f a) (f min))) as [|Hnz].
- assert (a = min) as <-; last done.
eapply inj; first apply _.
eapply anti_symm; first apply _; auto.
- exfalso; apply Hnz.
rewrite -Heq.
by apply sup_UB.
Qed.
Lemma sup_mono l l' : (∀ a, a ∈ l → a ∈ l') → S (f (sup l)) (f (sup l')).
Proof.
destruct l as [|x l]; first by intros; rewrite /sup /=; auto.
assert (x ∈ (x :: l)) as Hx by constructor.
revert Hx.
generalize (x :: l) as k; clear l; intros l Hxl.
intros Hll.
apply sup_UB.
apply Hll.
eapply sup_elem_of; eauto.
Qed.
Lemma sup_equiv `{!AntiSymm S' S} l l' :
(∀ a, a ∈ l ↔ a ∈ l') → S' (f (sup l)) (f (sup l')).
Proof. intros; eapply anti_symm; first done; apply sup_mono; naive_solver. Qed.
Lemma sup_of_nil : sup [] = min.
Proof. done. Qed.
End find_one_maximal.
Definition nat_sup (l : list nat) := sup id lt 0 l.
Lemma nat_sup_UB l a : a ∈ l → a ≤ (nat_sup l).
Proof. apply (sup_UB id); try apply _; auto with lia. Qed.
Lemma nat_sup_LUB l u : (∀ a, a ∈ l → a ≤ u) → (nat_sup l) ≤ u.
Proof. apply (sup_LUB id); try apply _; simpl; auto with lia. Qed.
Lemma nat_sup_elem_of a l : a ∈ l → nat_sup l ∈ l.
Proof.
eapply (sup_elem_of id lt le); try apply _; simpl; auto with lia.
Qed.
Lemma nat_sup_mono l l' : (∀ a, a ∈ l → a ∈ l') → (nat_sup l) ≤ (nat_sup l').
Proof.
eapply (sup_mono id lt le); try apply _; simpl; auto with lia.
Qed.
Lemma nat_sup_equiv l l' : (∀ a, a ∈ l ↔ a ∈ l') → (nat_sup l) = (nat_sup l').
Proof.
intros; eapply (sup_equiv id lt le) with (S' := eq);
try apply _; simpl; auto with lia.
Qed.
Lemma nat_sup_of_nil : nat_sup [] = 0.
Proof. apply sup_of_nil. Qed.
Lemma nat_Z_eq (n : nat) (z : Z) :
(0 ≤ z)%Z → n = Z.to_nat z :> nat → n = z :> Z.
Proof. lia. Qed.
Section gset_map.
Context `{EqDecision A, !Countable A, !EqDecision B, !Countable B}.
Definition gset_map (f : A → B) (g : gset A) : gset B :=
list_to_set (f <$> elements g).
Lemma gset_map_empty f : gset_map f ∅ = ∅.
Proof. by rewrite /gset_map elements_empty /=. Qed.
Lemma gset_map_singleton f a : gset_map f {[a]} = {[f a]}.
Proof. by rewrite /gset_map elements_singleton /= right_id_L. Qed.
Lemma gset_map_union f g g' :
gset_map f (g ∪ g') = gset_map f g ∪ gset_map f g'.
Proof.
revert g'.
pattern g.
match goal with |- ?F g => simpl; apply (set_ind_L F) end; set_solver.
Qed.
Lemma gset_map_correct1 f g : ∀ a, a ∈ g → (f a) ∈ gset_map f g.
Proof.
pattern g.
match goal with |- ?F g => simpl; apply (set_ind_L F) end; set_solver.
Qed.
Lemma gset_map_correct2 f g : ∀ b, b ∈ gset_map f g → ∃ a, b = f a ∧ a ∈ g.
Proof.
pattern g.
match goal with |- ?F g => simpl; apply (set_ind_L F) end; set_solver.
Qed.
End gset_map.
Section find_one_maximal.
Context {A B : Type} (f : A → B)
(R : relation B) `{!RelDecision R} `{!Transitive R}
(S : relation B) `{!Transitive S} `{!Reflexive S}
(HRS : ∀ a b, R a b → S a b)
(HSR : ∀ a b, S a b → a = b ∨ R a b)
(HRir : ∀ a, ¬ R a a)
(HRex : ∀ a b, R a b → R b a → False)
(HSR_trans : ∀ a b c, S a b → R b c → R a c).
Fixpoint find_one_maximal (candidate : A) (l : list A) :=
match l with
| [] => candidate
| a :: l' => if bool_decide (R (f candidate) (f a)) then
find_one_maximal a l'
else
find_one_maximal candidate l'
end.
Lemma find_one_maximal_rel c l : S (f c) (f (find_one_maximal c l)).
Proof.
revert c; induction l as [|a l IHl]; intros c; first done.
destruct (decide (R (f c) (f a))).
- rewrite /= bool_decide_eq_true_2 //; by etrans; eauto.
- rewrite /= bool_decide_eq_false_2 //.
Qed.
Lemma find_one_maximal_maximal c l y :
y ∈ l → ¬ R (f (find_one_maximal c l)) (f y).
Proof.
revert c; induction l as [|a l IHl]; intros c; first by inversion 1.
intros [->|Hy]%elem_of_cons.
- destruct (decide (R (f c) (f a))) as [|Hnot].
+ rewrite /= bool_decide_eq_true_2 //.
pose proof (find_one_maximal_rel a l) as [ <- | ?]%HSR;
first by apply HRir.
intros ?; eapply HRex; eauto.
+ rewrite /= bool_decide_eq_false_2 //.
intros ?.
apply Hnot.
eapply HSR_trans; eauto using find_one_maximal_rel.
- destruct (decide (R (f c) (f a))) as [|Hnot].
+ rewrite /= bool_decide_eq_true_2 //.
intros ?; eapply IHl; eauto.
+ rewrite /= bool_decide_eq_false_2 //.
intros ?; eapply IHl; eauto.
Qed.
Lemma find_one_maximal_eq_or_elem_of c l :
find_one_maximal c l = c ∨ find_one_maximal c l ∈ l.
Proof.
revert c; induction l as [|a l IHl]; intros c; first by left.
destruct (decide (R (f c) (f a))) as [|Hnot].
- rewrite /= bool_decide_eq_true_2 //.
destruct (IHl a) as [->|]; by right; constructor.
- rewrite /= bool_decide_eq_false_2 //.
destruct (IHl c) as [->|]; first by left.
by right; constructor.
Qed.
Context (HNRS : ∀ a b, ¬ R a b → S b a)
(min : A)
(Hmin : ∀ a, S (f min) a).
Definition sup l := find_one_maximal min l.
Lemma sup_UB l a : a ∈ l → S (f a) (f (sup l)).
Proof. by intros Hl; apply HNRS; apply find_one_maximal_maximal. Qed.
Lemma sup_LUB l u : (∀ a, a ∈ l → S (f a) (f u)) → (S (f (sup l)) (f u)).
Proof.
intros Hu.
rewrite /sup.
destruct (find_one_maximal_eq_or_elem_of min l) as [->|];
first by apply Hmin.
by apply Hu.
Qed.
Context `{!RelDecision S} `{!EqDecision A} `{!AntiSymm eq S} `{!Inj eq eq f}.
Lemma sup_elem_of a l : a ∈ l → sup l ∈ l.
Proof.
intros Hal.
rewrite /sup.
destruct (find_one_maximal_eq_or_elem_of min l) as [Heq|]; last done.
rewrite Heq.
destruct (decide (S (f a) (f min))) as [|Hnz].
- assert (a = min) as <-; last done.
eapply inj; first apply _.
eapply anti_symm; first apply _; auto.
- exfalso; apply Hnz.
rewrite -Heq.
by apply sup_UB.
Qed.
Lemma sup_mono l l' : (∀ a, a ∈ l → a ∈ l') → S (f (sup l)) (f (sup l')).
Proof.
destruct l as [|x l]; first by intros; rewrite /sup /=; auto.
assert (x ∈ (x :: l)) as Hx by constructor.
revert Hx.
generalize (x :: l) as k; clear l; intros l Hxl.
intros Hll.
apply sup_UB.
apply Hll.
eapply sup_elem_of; eauto.
Qed.
Lemma sup_equiv `{!AntiSymm S' S} l l' :
(∀ a, a ∈ l ↔ a ∈ l') → S' (f (sup l)) (f (sup l')).
Proof. intros; eapply anti_symm; first done; apply sup_mono; naive_solver. Qed.
Lemma sup_of_nil : sup [] = min.
Proof. done. Qed.
End find_one_maximal.
Definition nat_sup (l : list nat) := sup id lt 0 l.
Lemma nat_sup_UB l a : a ∈ l → a ≤ (nat_sup l).
Proof. apply (sup_UB id); try apply _; auto with lia. Qed.
Lemma nat_sup_LUB l u : (∀ a, a ∈ l → a ≤ u) → (nat_sup l) ≤ u.
Proof. apply (sup_LUB id); try apply _; simpl; auto with lia. Qed.
Lemma nat_sup_elem_of a l : a ∈ l → nat_sup l ∈ l.
Proof.
eapply (sup_elem_of id lt le); try apply _; simpl; auto with lia.
Qed.
Lemma nat_sup_mono l l' : (∀ a, a ∈ l → a ∈ l') → (nat_sup l) ≤ (nat_sup l').
Proof.
eapply (sup_mono id lt le); try apply _; simpl; auto with lia.
Qed.
Lemma nat_sup_equiv l l' : (∀ a, a ∈ l ↔ a ∈ l') → (nat_sup l) = (nat_sup l').
Proof.
intros; eapply (sup_equiv id lt le) with (S' := eq);
try apply _; simpl; auto with lia.
Qed.
Lemma nat_sup_of_nil : nat_sup [] = 0.
Proof. apply sup_of_nil. Qed.