Library HFcoc
Require Import Setoid.
Require Export HFrelation.
Definition ext_fun dom F := eq_hf_fun dom F F.
Definition cc_lam (x:hf) (y:hf->hf) : hf :=
union (repl x (fun x' => repl (y x') (fun y' => couple x' y'))).
Lemma cc_lam_ext :
∀ x1 x2 f1 f2,
x1 == x2 ->
eq_hf_fun x1 f1 f2 ->
cc_lam x1 f1 == cc_lam x2 f2.
unfold cc_lam in |- *; intros.
apply union_morph.
apply repl_morph; trivial.
red in |- *; intros.
apply repl_morph.
apply H0; trivial.
red in |- *; intros.
apply couple_morph; trivial.
Qed.
Definition cc_app (x y:hf) : hf :=
image (subset x (fun p => eq_hf (fst p) y)).
Instance cc_app_morph : morph2 cc_app.
unfold cc_app; do 3 red; intros.
apply image_morph.
apply subset_morph_ext; trivial.
red in |- *; intros.
rewrite H0; rewrite H2; reflexivity.
Qed.
Lemma cc_beta_eq:
∀ dom F x,
eq_hf_fun dom F F ->
x ∈ dom ->
cc_app (cc_lam dom F) x == F x.
Proof.
intros.
unfold cc_app, cc_lam in |- *.
unfold image in |- *.
let t := match goal with |- context[subset ?t _] => t end in
assert (Pm : hf_pred_morph t (fun p => eq_hf (fst p) x)).
red; intros.
rewrite <- H3.
rewrite H2; trivial.
assert (Pm': ext_fun dom
(fun x' => repl (F x') (fun y' => couple x' y'))).
red; red; intros.
apply repl_morph; auto.
red; intros.
apply couple_morph; auto.
symmetry.
apply repl_ext; intros.
red; intros.
apply snd_morph; trivial.
specialize subset_elim1 with (1 := H1); intro.
specialize subset_elim2 with (1:=Pm) (2 := H1); clear H1; intro.
elim union_elim with (1 := H2); clear H2; intros.
elim repl_elim with (1:=Pm') (2 := H3); clear H3; intros.
assert (Pm'': ext_fun (F x1) (fun y' => couple x1 y')).
red; red; intros; apply couple_morph; trivial; reflexivity.
rewrite H4 in H2.
clear H4 x0.
elim repl_elim with (1:=Pm'') (2 := H2); intros; clear H2.
rewrite H5 in H1 |- *; rewrite snd_def; rewrite fst_def in H1.
apply in_hf_reg_r with (F x1); auto.
exists (couple x y).
apply subset_intro; trivial.
apply union_intro with (repl (F x) (fun y' => couple x y')).
apply repl_intro with y; auto.
red; intros.
apply couple_morph; trivial; reflexivity.
reflexivity.
apply repl_intro with x; trivial; reflexivity.
apply fst_def.
symmetry; apply snd_def.
Qed.
Definition cc_prod (x:hf) (y:hf->hf) : hf :=
repl (dep_func x y) (fun f => cc_lam x (fun x' => app f x')).
Lemma beta_morph : ∀ dom F,
ext_fun (dep_func dom F)
(fun f0 : hf => cc_lam dom (fun x' : hf => app f0 x')).
Proof.
red; red; intros.
apply cc_lam_ext; try reflexivity.
red; intros; apply app_morph; trivial.
Qed.
Hint Resolve beta_morph.
Lemma cc_prod_ext :
∀ x1 x2 f1 f2,
x1 == x2 ->
eq_hf_fun x1 f1 f2 ->
cc_prod x1 f1 == cc_prod x2 f2.
Proof.
unfold cc_prod in |- *; intros.
apply repl_morph.
apply dep_func_ext; trivial.
red in |- *; intros.
apply cc_lam_ext; auto.
red in |- *; intros.
apply app_morph; auto.
Qed.
Lemma cc_prod_intro : ∀ dom f F,
eq_hf_fun dom f f ->
eq_hf_fun dom F F ->
(∀ x, x ∈ dom -> f x ∈ F x) ->
cc_lam dom f ∈ cc_prod dom F.
unfold cc_prod in |- *.
intros.
apply repl_intro with (lam dom f); trivial.
exact (beta_morph dom F).
apply dep_func_intro; trivial.
apply cc_lam_ext; intros.
reflexivity.
red in |- *; intros.
symmetry in |- *.
transitivity (f y2).
apply beta_eq; trivial.
apply in_hf_reg_l with y1; auto.
symmetry in |- *.
apply H; trivial.
Qed.
Lemma cc_prod_elim : ∀ dom f x F,
eq_hf_fun dom F F ->
f ∈ cc_prod dom F ->
x ∈ dom ->
cc_app f x ∈ F x.
intros dom f x F Fext ? ?.
unfold cc_prod in H.
elim repl_elim with (1:=beta_morph dom F) (2 := H); clear H; intros.
apply in_hf_reg_l with (cc_app (cc_lam dom (fun x' => app x0 x')) x).
apply cc_app_morph; auto.
symmetry in |- *; trivial.
reflexivity.
apply in_hf_reg_l with (app x0 x).
symmetry in |- *.
apply cc_beta_eq; trivial.
red; red in |- *; intros.
apply app_morph; trivial.
reflexivity.
apply dep_func_elim with (1:=Fext) (2 := H) (3 := H0).
Qed.
Definition prf_trm := empty.
Definition props := power (singl prf_trm).
Lemma cc_impredicative_lam : ∀ dom F,
eq_hf_fun dom F F ->
(∀ x, x ∈ dom -> F x == prf_trm) ->
cc_lam dom F == prf_trm.
Proof.
unfold cc_lam in |- *; intros.
apply empty_ext.
red in |- *; intros.
elim union_elim with (1 := H1); clear H1; intros.
assert (ext_fun dom (fun x' => repl (F x') (fun y' => couple x' y'))).
red; red; intros.
apply repl_morph; auto.
red; intros.
apply couple_morph; auto.
elim repl_elim with (1:=H3) (2 := H2); clear H2; intros.
specialize in_hf_reg_r with (1 := H4) (2 := H1); clear H4 H1 x0.
intro.
assert (ext_fun (F x1) (fun y' => couple x1 y')).
red; red; intros.
rewrite H5; reflexivity.
elim repl_elim with (1:=H4) (2 := H1); intros.
apply empty_elim with x0.
apply in_hf_reg_r with (F x1); trivial.
auto.
Qed.
Lemma cc_impredicative_prod : ∀ dom F,
eq_hf_fun dom F F ->
(∀ x, x ∈ dom -> F x ∈ props) ->
cc_prod dom F ∈ props.
Proof.
unfold props in |- *; intros dom F Fext ?.
apply power_intro; red; intros.
apply singl_intro.
unfold prf_trm in |- *.
unfold cc_prod in H0.
elim repl_elim with (1:=beta_morph dom F) (2 := H0); intros.
apply eq_hf_trans with (1 := H2).
apply cc_impredicative_lam.
red; intros; apply app_morph; trivial; reflexivity.
intros.
specialize dep_func_elim with (1:=Fext) (2 := H1) (3 := H3); intro.
specialize H with (1 := H3).
specialize power_elim with (1 := H) (2 := H4); intro.
apply singl_elim; trivial.
Qed.