From Coq Require Import Orders Lia RelationPairs Bool.Bool Structures.EqualitiesFacts Lists.List.
From DeBrLevel Require Import LevelInterface Level.
Import ListNotations.
From DeBrLevel Require Import LevelInterface Level.
Import ListNotations.
Implementation - Leveled List
Leveled List Implementation - ET and WL
Definition t := list E.t.
Definition eq := @Logic.eq (list E.t).
Definition shift (lb k: Level.t) (t: t) := map (E.shift lb k) t.
Definition Wf (lb: Level.t) (t: t) := ∀ x, In x t → E.Wf lb x.
#[export] Instance eq_refl : Reflexive eq := _.
#[export] Instance eq_sym : Symmetric eq := _.
#[export] Instance eq_trans : Transitive eq := _.
#[export] Instance eq_equiv : Equivalence eq := _.
Lemma eq_leibniz (x y: t) : eq x y → x = y.
Proof. now unfold eq. Qed.
shift properties
Section shift_props.
Variable lb k k' k'' : Level.t.
Variable t t' : t.
#[export] Instance shift_eq : Proper (Logic.eq ==> Logic.eq ==> eq ==> eq) shift := _.
Lemma shift_eq_iff : eq t t' ↔ eq (shift lb k t) (shift lb k t').
Proof.
split; unfold eq in ×.
- intros; now subst.
- revert t'; induction t.
-- unfold shift; intros; simpl in ×.
destruct t'; auto. simpl in ×.
inversion H.
-- intros; destruct t'; simpl in ×.
+ inversion H.
+ inversion H. f_equal.
++ apply E.eq_leibniz.
rewrite E.shift_eq_iff; now rewrite H1.
++ now apply IHt0.
Qed.
Lemma shift_zero_refl : eq (shift lb 0 t) t.
Proof.
unfold eq; induction t; simpl; f_equal; auto.
apply E.eq_leibniz; now apply E.shift_zero_refl.
Qed.
Lemma shift_trans : eq (shift lb k (shift lb k' t)) (shift lb (k + k') t).
Proof.
unfold eq; induction t; simpl; f_equal; auto.
apply E.eq_leibniz; now apply E.shift_trans.
Qed.
Lemma shift_permute : eq (shift lb k (shift lb k' t)) (shift lb k' (shift lb k t)).
Proof.
unfold eq; induction t; simpl; f_equal; auto.
apply E.eq_leibniz; now apply E.shift_permute.
Qed.
Lemma shift_unfold : eq (shift lb (k + k') t) (shift (lb + k) k' (shift lb k t)).
Proof.
unfold eq; induction t; simpl; f_equal; auto.
apply E.eq_leibniz; now apply E.shift_unfold.
Qed.
Lemma shift_unfold_1 :
k ≤ k' → k' ≤ k'' →
eq (shift k' (k'' - k') (shift k (k' - k) t)) (shift k (k'' - k) t).
Proof.
unfold eq; intros Hle Hle'; induction t; simpl; f_equal; auto.
apply E.eq_leibniz; now apply E.shift_unfold_1.
Qed.
Lemma shift_nil: eq (shift lb k nil) nil.
Proof. unfold eq, shift; now simpl. Qed.
Lemma shift_cons v:
eq (shift lb k (v :: t)) ((E.shift lb k v) :: (shift lb k t)).
Proof. unfold eq, shift; now simpl. Qed.
Lemma shift_app:
eq (shift lb k (t ++ t')) ((shift lb k t) ++ (shift lb k t')).
Proof.
unfold eq, shift. apply map_app.
Qed.
Lemma shift_in v: In v t ↔ In (E.shift lb k v) (shift lb k t).
Proof.
split. clear k' k'' t'.
- revert v. induction t; intros; simpl in *; auto.
destruct H; subst; auto.
- revert v. induction t; intros; simpl in *; auto.
destruct H; subst; auto.
left. apply E.eq_leibniz.
rewrite E.shift_eq_iff. now rewrite H.
Qed.
Lemma shift_in_e v:
In v (shift lb k t) →
∃ v', v = (E.shift lb k v') ∧ In (E.shift lb k v') (shift lb k t).
Proof.
clear k' k'' t'. revert v; induction t; simpl; intros.
- inversion H.
- destruct H; subst.
-- ∃ a. split; auto.
-- apply IHt0 in H as [v' [Heq HIn]]; subst.
∃ v'; split; auto.
Qed.
Lemma shift_notin v : ¬ In v t ↔ ¬ In (E.shift lb k v) (shift lb k t).
Proof.
intros; split; unfold not; intros; apply H.
- now rewrite <- shift_in in H0.
- now rewrite <- shift_in.
Qed.
End shift_props.
Wf properties
#[export] Instance Wf_iff : Proper (Logic.eq ==> eq ==> iff) Wf := _.
Lemma Wf_unfold (lb: Lvl.t) (s: t) : Wf lb s ↔ (∀ v, List.In v s → E.Wf lb v).
Proof. now unfold Wf. Qed.
Lemma Wf_nil (lb: Lvl.t) : Wf lb [].
Proof. unfold Wf; intros x c. inversion c. Qed.
Lemma Wf_cons (lb: Lvl.t) (v: E.t) (s: t) : Wf lb (v :: s) ↔ E.Wf lb v ∧ Wf lb s.
Proof.
unfold Wf; split; intros.
- split.
-- apply H. simpl; now left.
-- intros x HIn.
apply H. simpl; now right.
- destruct H,H0; subst; auto.
Qed.
Lemma Wf_app (lb: Lvl.t) (s s': t) : Wf lb (s ++ s') ↔ Wf lb s ∧ Wf lb s'.
Proof.
unfold Wf; split; intros.
- split; intros.
-- apply H.
apply in_or_app; now left.
-- apply H.
apply in_or_app; now right.
- apply in_app_or in H0.
destruct H, H0; auto.
Qed.
Lemma Wf_in (lb: Lvl.t) (v: E.t) (t: t) : Wf lb t → In v t → E.Wf lb v.
Proof. unfold Wf; intros; now apply H. Qed.
Lemma Wf_weakening (k k': Lvl.t) (t: t) : (k ≤ k') → Wf k t → Wf k' t.
Proof.
intros. unfold Wf in ×. intros.
apply H0 in H1.
eapply E.Wf_weakening; eauto.
Qed.
Lemma shift_preserves_wf (k k': Lvl.t) (t: t) : Wf k t → Wf (k + k') (shift k k' t).
Proof.
induction t; simpl; intros.
- apply Wf_nil.
- rewrite Wf_cons in *;
destruct H; split; auto.
now apply E.shift_preserves_wf.
Qed.
Lemma shift_preserves_wf_1 (lb k k': Lvl.t) (t: t) :
Wf k t → Wf (k + k') (shift lb k' t).
Proof.
induction t; simpl; intros.
- apply Wf_nil.
- rewrite Wf_cons in *;
destruct H; split; auto.
now apply E.shift_preserves_wf_1.
Qed.
Lemma shift_preserves_wf_gen (lb lb' k k': Lvl.t) (t: t) :
k ≤ k' → lb ≤ lb' → k ≤ lb → k' ≤ lb' →
k' - k = lb' - lb → Wf lb t → Wf lb' (shift k (k' - k) t).
Proof.
intros Hle Hle1 Hle2 Hle3 Heq.
induction t; simpl; intros.
- apply Wf_nil.
- rewrite Wf_cons in *;
destruct H; split; auto.
now apply E.shift_preserves_wf_gen with lb.
Qed.
Lemma shift_preserves_wf_2 (lb lb': Lvl.t) (t: t) :
lb ≤ lb' → Wf lb t → Wf lb' (shift lb (lb' - lb) t).
Proof. intros. eapply shift_preserves_wf_gen; eauto. Qed.
Lemma shift_preserves_wf_zero (k: Lvl.t) (t: t) : Wf k t → Wf k (shift k 0 t).
Proof.
intros; replace k with (k + 0); try lia;
now apply shift_preserves_wf_1.
Qed.
End IsLvlListETWL.
Section props.
Variable k : Level.t.
Variable t : t.
Lemma is_wf_eq : Proper (Logic.eq ==> eq ==> Logic.eq) is_wf.
Proof.
repeat red; intros. unfold eq in *; now subst.
Qed.
Lemma Wf_is_wf_true : Wf k t ↔ is_wf k t = true.
Proof.
split; intros; unfold Wf,is_wf in ×.
- rewrite List.forallb_forall; intros.
rewrite <- E.Wf_is_wf_true.
now apply H.
- rewrite List.forallb_forall in H; intros.
rewrite E.Wf_is_wf_true.
now apply H.
Qed.
Lemma notWf_is_wf_false : ¬ Wf k t ↔ is_wf k t = false.
Proof.
intros; rewrite <- not_true_iff_false; split; intros; intro.
- apply H; now rewrite Wf_is_wf_true.
- apply H; now rewrite <- Wf_is_wf_true.
Qed.
End props.
End IsLvlFullListETWL.
Variable k : Level.t.
Variable t : t.
Lemma is_wf_eq : Proper (Logic.eq ==> eq ==> Logic.eq) is_wf.
Proof.
repeat red; intros. unfold eq in *; now subst.
Qed.
Lemma Wf_is_wf_true : Wf k t ↔ is_wf k t = true.
Proof.
split; intros; unfold Wf,is_wf in ×.
- rewrite List.forallb_forall; intros.
rewrite <- E.Wf_is_wf_true.
now apply H.
- rewrite List.forallb_forall in H; intros.
rewrite E.Wf_is_wf_true.
now apply H.
Qed.
Lemma notWf_is_wf_false : ¬ Wf k t ↔ is_wf k t = false.
Proof.
intros; rewrite <- not_true_iff_false; split; intros; intro.
- apply H; now rewrite Wf_is_wf_true.
- apply H; now rewrite <- Wf_is_wf_true.
Qed.
End props.
End IsLvlFullListETWL.
Module IsBdlLvlListETWL (E : IsBdlLvlETWL) <: IsBdlLvlETWL.
Include IsLvlListETWL E.
Lemma shift_wf_refl (lb k: Lvl.t) (t: t) : Wf lb t → eq (shift lb k t) t.
Proof.
induction t; simpl; intro Hwf.
- reflexivity.
- apply Wf_cons in Hwf as [HWfa Hwf].
rewrite IHt; auto.
unfold eq; f_equal.
apply E.eq_leibniz.
rewrite E.shift_wf_refl; auto; reflexivity.
Qed.
End IsBdlLvlListETWL.
Include IsLvlListETWL E.
Lemma shift_wf_refl (lb k: Lvl.t) (t: t) : Wf lb t → eq (shift lb k t) t.
Proof.
induction t; simpl; intro Hwf.
- reflexivity.
- apply Wf_cons in Hwf as [HWfa Hwf].
rewrite IHt; auto.
unfold eq; f_equal.
apply E.eq_leibniz.
rewrite E.shift_wf_refl; auto; reflexivity.
Qed.
End IsBdlLvlListETWL.
Module IsBdlLvlFullListETWL (E : IsBdlLvlFullETWL) <: IsBdlLvlFullET.
Include IsLvlFullListETWL E.
Lemma shift_wf_refl (lb k: Lvl.t) (t: t) : Wf lb t → eq (shift lb k t) t.
Proof.
induction t; simpl; intro Hwf.
- reflexivity.
- apply Wf_cons in Hwf as [HWfa Hwf].
rewrite IHt; auto.
unfold eq; f_equal.
apply E.eq_leibniz.
rewrite E.shift_wf_refl; auto; reflexivity.
Qed.
End IsBdlLvlFullListETWL.
Include IsLvlFullListETWL E.
Lemma shift_wf_refl (lb k: Lvl.t) (t: t) : Wf lb t → eq (shift lb k t) t.
Proof.
induction t; simpl; intro Hwf.
- reflexivity.
- apply Wf_cons in Hwf as [HWfa Hwf].
rewrite IHt; auto.
unfold eq; f_equal.
apply E.eq_leibniz.
rewrite E.shift_wf_refl; auto; reflexivity.
Qed.
End IsBdlLvlFullListETWL.