Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

define type class instances for PERs #79

Merged
merged 3 commits into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 31 additions & 31 deletions theories/Core/Semantic/PER/Definitions.v
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ From Mcltt Require Export Domain.
Import Domain_Notations.

Notation "'Dom' a ≈ b ∈ R" := ((R a b : Prop) : Prop) (in custom judg at level 90, a custom domain, b custom domain, R constr).
Notation "'DF' a ≈ b ∈ R ↘ R'" := ((R a b R' : Prop) : Prop) (in custom judg at level 90, a custom domain, b custom domain, R constr, R' constr).
Notation "'DF' a ≈ b ∈ R ↘ R'" := ((R R' a b : Prop) : Prop) (in custom judg at level 90, a custom domain, b custom domain, R constr, R' constr).
Notation "'Exp' a ≈ b ∈ R" := (R a b : (Prop : Type)) (in custom judg at level 90, a custom exp, b custom exp, R constr).
Notation "'EF' a ≈ b ∈ R ↘ R'" := (R a b R' : (Prop : Type)) (in custom judg at level 90, a custom exp, b custom exp, R constr, R' constr).
Notation "'EF' a ≈ b ∈ R ↘ R'" := (R R' a b : (Prop : Type)) (in custom judg at level 90, a custom exp, b custom exp, R constr, R' constr).

Generalizable All Variables.

(** Helper Bundles *)
Inductive rel_mod_eval (R : domain -> domain -> relation domain -> Prop) A p A' p' R' : Prop := mk_rel_mod_eval : forall a a', {{ ⟦ A ⟧ p ↘ a }} -> {{ ⟦ A' ⟧ p' ↘ a' }} -> {{ DF a ≈ a' ∈ R ↘ R' }} -> rel_mod_eval R A p A' p' R'.
Inductive rel_mod_eval (R : relation domain -> domain -> domain -> Prop) A p A' p' R' : Prop := mk_rel_mod_eval : forall a a', {{ ⟦ A ⟧ p ↘ a }} -> {{ ⟦ A' ⟧ p' ↘ a' }} -> {{ DF a ≈ a' ∈ R ↘ R' }} -> rel_mod_eval R A p A' p' R'.
#[global]
Arguments mk_rel_mod_eval {_ _ _ _ _ _}.

Expand Down Expand Up @@ -81,7 +81,7 @@ Section Per_univ_elem_core_def.
(i : nat)
(per_univ_rec : forall {j}, j < i -> relation domain).

Inductive per_univ_elem_core : domain -> domain -> relation domain -> Prop :=
Inductive per_univ_elem_core : relation domain -> domain -> domain -> Prop :=
| per_univ_elem_core_univ :
`{ forall (lt_j_i : j < i),
j = j' ->
Expand All @@ -102,39 +102,39 @@ Section Per_univ_elem_core_def.
.

Hypothesis
(motive : domain -> domain -> relation domain -> Prop)
(case_U : forall (j j' : nat) (lt_j_i : j < i), j = j' -> motive d{{{ 𝕌@j }}} d{{{ 𝕌@j' }}} (per_univ_rec lt_j_i))
(case_nat : motive d{{{ ℕ }}} d{{{ ℕ }}} per_nat)
(motive : relation domain -> domain -> domain -> Prop)
(case_U : forall (j j' : nat) (lt_j_i : j < i), j = j' -> motive (per_univ_rec lt_j_i) d{{{ 𝕌@j }}} d{{{ 𝕌@j' }}})
(case_nat : motive per_nat d{{{ ℕ }}} d{{{ ℕ }}})
(case_Pi :
forall {A p B A' p' B' in_rel elem_rel}
(out_rel : forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), relation domain),
{{ DF A ≈ A' ∈ per_univ_elem_core ↘ in_rel }} ->
motive A A' in_rel ->
motive in_rel A A' ->
PER in_rel ->
(forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}),
rel_mod_eval (fun x y R => {{ DF x ≈ y ∈ per_univ_elem_core ↘ R }} /\ motive x y R) B d{{{ p ↦ c }}} B' d{{{ p' ↦ c' }}} (out_rel equiv_c_c')) ->
rel_mod_eval (fun R x y => {{ DF x ≈ y ∈ per_univ_elem_core ↘ R }} /\ motive R x y) B d{{{ p ↦ c }}} B' d{{{ p' ↦ c' }}} (out_rel equiv_c_c')) ->
(forall f f', elem_rel f f' = forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), rel_mod_app (out_rel equiv_c_c') f c f' c') ->
motive d{{{ Π A p B }}} d{{{ Π A' p' B' }}} elem_rel)
(case_ne : (forall {a b a' b'}, {{ Dom b ≈ b' ∈ per_bot }} -> motive d{{{ ⇑ a b }}} d{{{ ⇑ a' b' }}} per_ne)).
motive elem_rel d{{{ Π A p B }}} d{{{ Π A' p' B' }}})
(case_ne : (forall {a b a' b'}, {{ Dom b ≈ b' ∈ per_bot }} -> motive per_ne d{{{ ⇑ a b }}} d{{{ ⇑ a' b' }}})).

#[derive(equations=no, eliminator=no)]
Equations per_univ_elem_core_strong_ind a b R (H : {{ DF a ≈ b ∈ per_univ_elem_core ↘ R }}) : {{ DF a ≈ b ∈ motive ↘ R }} :=
| a, b, R, (per_univ_elem_core_univ lt_j_i eq) => case_U _ _ lt_j_i eq;
| a, b, R, per_univ_elem_core_nat => case_nat;
| a, b, R, (per_univ_elem_core_pi in_rel out_rel equiv_a_a' per HT HE) =>
Equations per_univ_elem_core_strong_ind R a b (H : {{ DF a ≈ b ∈ per_univ_elem_core ↘ R }}) : {{ DF a ≈ b ∈ motive ↘ R }} :=
| R, a, b, (per_univ_elem_core_univ lt_j_i eq) => case_U _ _ lt_j_i eq;
| R, a, b, per_univ_elem_core_nat => case_nat;
| R, a, b, (per_univ_elem_core_pi in_rel out_rel equiv_a_a' per HT HE) =>
case_Pi out_rel equiv_a_a' (per_univ_elem_core_strong_ind _ _ _ equiv_a_a') per
(fun _ _ equiv_c_c' => match HT _ _ equiv_c_c' with
| mk_rel_mod_eval b b' evb evb' Rel =>
mk_rel_mod_eval b b' evb evb' (conj _ (per_univ_elem_core_strong_ind _ _ _ Rel))
end)
HE;
| a, b, R, (per_univ_elem_core_neut equiv_b_b') => case_ne equiv_b_b'.
| R, a, b, (per_univ_elem_core_neut equiv_b_b') => case_ne equiv_b_b'.

End Per_univ_elem_core_def.

Global Hint Constructors per_univ_elem_core : mcltt.

Equations per_univ_elem (i : nat) : domain -> domain -> relation domain -> Prop by wf i :=
Equations per_univ_elem (i : nat) : relation domain -> domain -> domain -> Prop by wf i :=
| i => per_univ_elem_core i (fun j lt_j_i a a' => exists R', {{ DF a ≈ a' ∈ per_univ_elem j ↘ R' }}).

Definition per_univ (i : nat) : relation domain := fun a a' => exists R', {{ DF a ≈ a' ∈ per_univ_elem i ↘ R' }}.
Expand All @@ -157,36 +157,36 @@ Global Hint Resolve per_univ_elem_core_univ' : mcltt.

Section Per_univ_elem_ind_def.
Hypothesis
(motive : nat -> domain -> domain -> relation domain -> Prop)
(motive : nat -> relation domain -> domain -> domain -> Prop)
(case_U : forall j j' i, j < i -> j = j' ->
(forall A B R, {{ DF A ≈ B ∈ per_univ_elem j ↘ R }} -> motive j A B R) ->
motive i d{{{ 𝕌@j }}} d{{{ 𝕌@j' }}} (per_univ j))
(case_N : forall i, motive i d{{{ ℕ }}} d{{{ ℕ }}} per_nat)
(forall A B R, {{ DF A ≈ B ∈ per_univ_elem j ↘ R }} -> motive j R A B) ->
motive i (per_univ j) d{{{ 𝕌@j }}} d{{{ 𝕌@j' }}})
(case_N : forall i, motive i per_nat d{{{ ℕ }}} d{{{ ℕ }}})
(case_Pi :
forall i {A p B A' p' B' in_rel elem_rel}
(out_rel : forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), relation domain),
{{ DF A ≈ A' ∈ per_univ_elem i ↘ in_rel }} ->
motive i A A' in_rel ->
motive i in_rel A A' ->
PER in_rel ->
(forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}),
rel_mod_eval (fun x y R => {{ DF x ≈ y ∈ per_univ_elem i ↘ R }} /\ motive i x y R) B d{{{ p ↦ c }}} B' d{{{ p' ↦ c' }}} (out_rel equiv_c_c')) ->
rel_mod_eval (fun R x y => {{ DF x ≈ y ∈ per_univ_elem i ↘ R }} /\ motive i R x y) B d{{{ p ↦ c }}} B' d{{{ p' ↦ c' }}} (out_rel equiv_c_c')) ->
(forall f f', elem_rel f f' = forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), rel_mod_app (out_rel equiv_c_c') f c f' c') ->
motive i d{{{ Π A p B }}} d{{{ Π A' p' B' }}} elem_rel)
(case_ne : (forall i {a b a' b'}, {{ Dom b ≈ b' ∈ per_bot }} -> motive i d{{{ ⇑ a b }}} d{{{ ⇑ a' b' }}} per_ne)).
motive i elem_rel d{{{ Π A p B }}} d{{{ Π A' p' B' }}})
(case_ne : (forall i {a b a' b'}, {{ Dom b ≈ b' ∈ per_bot }} -> motive i per_ne d{{{ ⇑ a b }}} d{{{ ⇑ a' b' }}})).

#[local]
Ltac def_simp := simp per_univ_elem in *.

#[derive(equations=no, eliminator=no), tactic="def_simp"]
Equations per_univ_elem_ind' (i : nat) (a b : domain) (R : relation domain)
Equations per_univ_elem_ind' (i : nat) (R : relation domain) (a b : domain)
(H : {{ DF a ≈ b ∈ per_univ_elem_core i (fun j lt_j_i a a' => exists R', {{ DF a ≈ a' ∈ per_univ_elem j ↘ R' }}) ↘ R }}) : {{ DF a ≈ b ∈ motive i ↘ R }} by wf i :=
| i, a, b, R, H =>
| i, R, a, b, H =>
per_univ_elem_core_strong_ind i _ (motive i)
(fun j j' j_lt_i eq => case_U j j' i j_lt_i eq (fun A B R' H' => per_univ_elem_ind' _ A B R' _))
(fun j j' j_lt_i eq => case_U j j' i j_lt_i eq (fun A B R' H' => per_univ_elem_ind' _ R' A B _))
(case_N i)
(fun A p B A' p' B' in_rel elem_rel out_rel HA IHA per HT HE => case_Pi i out_rel _ IHA per _ HE)
(@case_ne i)
a b R H.
R a b H.

#[derive(equations=no, eliminator=no), tactic="def_simp"]
Equations per_univ_elem_ind i a b R (H : per_univ_elem i a b R) : motive i a b R :=
Expand Down Expand Up @@ -214,7 +214,7 @@ Arguments rel_typ _ _ _ _ _ _ /.

Definition per_total : relation env := fun p p' => True.

Inductive per_ctx_env : ctx -> ctx -> relation env -> Prop :=
Inductive per_ctx_env : relation env -> ctx -> ctx -> Prop :=
| per_ctx_env_nil :
`{ {{ EF ⋅ ≈ ⋅ ∈ per_ctx_env ↘ per_total }} }
| per_ctx_env_cons :
Expand All @@ -229,5 +229,5 @@ Inductive per_ctx_env : ctx -> ctx -> relation env -> Prop :=
{{ EF Γ, A ≈ Γ', A' ∈ per_ctx_env ↘ env_rel }} }
.

Definition per_ctx : relation ctx := fun Γ Γ' => exists R', per_ctx_env Γ Γ' R'.
Definition per_ctx : relation ctx := fun Γ Γ' => exists R', per_ctx_env R' Γ Γ'.
Definition valid_ctx : ctx -> Prop := fun Γ => per_ctx Γ Γ.
110 changes: 82 additions & 28 deletions theories/Core/Semantic/PER/Lemmas.v
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
From Coq Require Import Lia PeanoNat Relation_Definitions RelationClasses.
From Equations Require Import Equations.
From Mcltt Require Import Axioms Base Evaluation LibTactics PER.Definitions Readback.
Import Domain_Notations.

Expand Down Expand Up @@ -148,9 +149,9 @@ Qed.
#[export]
Hint Resolve per_ne_trans : mcltt.

Lemma per_univ_elem_right_irrel : forall i i' A B R B' R',
per_univ_elem i A B R ->
per_univ_elem i' A B' R' ->
Lemma per_univ_elem_right_irrel : forall i i' R A B R' B',
per_univ_elem i R A B ->
per_univ_elem i' R' A B' ->
R = R'.
Proof with mautosolve.
intros * Horig.
Expand Down Expand Up @@ -181,9 +182,9 @@ Ltac per_univ_elem_right_irrel_rewrite1 :=
#[local]
Ltac per_univ_elem_right_irrel_rewrite := repeat per_univ_elem_right_irrel_rewrite1.

Lemma per_univ_elem_sym : forall i A B R,
per_univ_elem i A B R ->
per_univ_elem i B A R /\
Lemma per_univ_elem_sym : forall i R A B,
per_univ_elem i R A B ->
per_univ_elem i R B A /\
(forall a b,
{{ Dom a ≈ b ∈ R }} ->
{{ Dom b ≈ a ∈ R }}).
Expand Down Expand Up @@ -216,35 +217,35 @@ Proof with (try econstructor; mautosolve).
- split...
Qed.

Corollary per_univ_sym : forall i A B R,
per_univ_elem i A B R ->
per_univ_elem i B A R.
Corollary per_univ_sym : forall i R A B,
per_univ_elem i R A B ->
per_univ_elem i R B A.
Proof.
intros * ?%per_univ_elem_sym.
firstorder.
Qed.

Corollary per_elem_sym : forall i A B a b R,
per_univ_elem i A B R ->
Corollary per_elem_sym : forall i R A B a b,
per_univ_elem i R A B ->
R a b ->
R b a.
Proof.
intros * ?%per_univ_elem_sym.
firstorder.
Qed.

Corollary per_univ_elem_left_irrel : forall i i' A B R A' R',
per_univ_elem i A B R ->
per_univ_elem i' A' B R' ->
Corollary per_univ_elem_left_irrel : forall i i' R A B R' A',
per_univ_elem i R A B ->
per_univ_elem i' R' A' B ->
R = R'.
Proof.
intros * ?%per_univ_sym ?%per_univ_sym.
eauto using per_univ_elem_right_irrel.
Qed.

Corollary per_univ_elem_cross_irrel : forall i i' A B R B' R',
per_univ_elem i A B R ->
per_univ_elem i' B' A R' ->
Corollary per_univ_elem_cross_irrel : forall i i' R A B R' B',
per_univ_elem i R A B ->
per_univ_elem i' R' B' A ->
R = R'.
Proof.
intros * ? ?%per_univ_sym.
Expand Down Expand Up @@ -274,11 +275,11 @@ Ltac per_univ_elem_irrel_rewrite :=
do_per_univ_elem_irrel_rewrite;
clear_dups.

Lemma per_univ_elem_trans : forall i A1 A2 R,
per_univ_elem i A1 A2 R ->
Lemma per_univ_elem_trans : forall i R A1 A2,
per_univ_elem i R A1 A2 ->
(forall j A3,
per_univ_elem j A2 A3 R ->
per_univ_elem i A1 A3 R) /\
per_univ_elem j R A2 A3 ->
per_univ_elem i R A1 A3) /\
(forall a1 a2 a3,
R a1 a2 ->
R a2 a3 ->
Expand Down Expand Up @@ -311,17 +312,17 @@ Proof with ((econstructor + per_univ_elem_econstructor); mautosolve).
- idtac...
Qed.

Corollary per_univ_trans : forall i j A1 A2 A3 R,
per_univ_elem i A1 A2 R ->
per_univ_elem j A2 A3 R ->
per_univ_elem i A1 A3 R.
Corollary per_univ_trans : forall i j R A1 A2 A3,
per_univ_elem i R A1 A2 ->
per_univ_elem j R A2 A3 ->
per_univ_elem i R A1 A3.
Proof.
intros * ?%per_univ_elem_trans.
firstorder.
Qed.

Corollary per_elem_trans : forall i A1 A2 a1 a2 a3 R,
per_univ_elem i A1 A2 R ->
Corollary per_elem_trans : forall i R A1 A2 a1 a2 a3,
per_univ_elem i R A1 A2 ->
R a1 a2 ->
R a2 a3 ->
R a1 a3.
Expand All @@ -330,7 +331,42 @@ Proof.
firstorder.
Qed.

Lemma per_univ_elem_cumu : forall {i a0 a1 R},

#[export]
Instance per_elem_PER {i R A B} `(H : per_univ_elem i R A B) : PER R.
Proof.
split.
- auto using (per_elem_sym _ _ _ _ _ _ H).
- eauto using (per_elem_trans _ _ _ _ _ _ _ H).
Qed.


#[export]
Instance per_univ_PER {i R} : PER (per_univ_elem i R).
Proof.
split.
- auto using per_univ_sym.
- eauto using per_univ_trans.
Qed.

(* This lemma gets rid of the unnecessary PER premise. *)
Lemma per_univ_elem_core_pi' :
Ailrun marked this conversation as resolved.
Show resolved Hide resolved
forall i A p B A' p' B' elem_rel
(in_rel : relation domain)
(out_rel : forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), relation domain)
(equiv_a_a' : {{ DF A ≈ A' ∈ per_univ_elem i ↘ in_rel}}),
(forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}),
rel_mod_eval (per_univ_elem i) B d{{{ p ↦ c }}} B' d{{{ p' ↦ c' }}} (out_rel equiv_c_c')) ->
(forall f f', elem_rel f f' = forall {c c'} (equiv_c_c' : {{ Dom c ≈ c' ∈ in_rel }}), rel_mod_app (out_rel equiv_c_c') f c f' c') ->
{{ DF Π A p B ≈ Π A' p' B' ∈ per_univ_elem i ↘ elem_rel }}.
Proof.
intros.
per_univ_elem_econstructor; eauto.
typeclasses eauto.
Qed.


Lemma per_univ_elem_cumu : forall i a0 a1 R,
{{ DF a0 ≈ a1 ∈ per_univ_elem i ↘ R }} ->
{{ DF a0 ≈ a1 ∈ per_univ_elem (S i) ↘ R }}.
Proof with solve [eauto].
Expand Down Expand Up @@ -499,3 +535,21 @@ Proof.
intros * ?% per_ctx_env_trans.
firstorder.
Qed.


#[export]
Instance per_ctx_PER {R} : PER (per_ctx_env R).
Proof.
split.
- auto using per_ctx_sym.
- eauto using per_ctx_trans.
Qed.


#[export]
Instance per_env_PER {R Γ Δ} (H : per_ctx_env R Γ Δ) : PER R.
Proof.
split.
- auto using (per_env_sym _ _ _ _ _ H).
- eauto using (per_env_trans _ _ _ _ _ _ H).
Qed.
6 changes: 6 additions & 0 deletions theories/LibTactics.v
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,9 @@ Tactic Notation "mauto" int_or_var(pow) "using" uconstr(use1) "," uconstr(use2)
eauto pow using use1, use2, use3, use4 with mcltt core.

Ltac mautosolve := unshelve solve [mauto]; solve [constructor].


(* Improve type class resolution *)

#[export]
Hint Extern 1 => eassumption : typeclass_instances.
Loading