aboutsummaryrefslogtreecommitdiff
path: root/theories/Program/FunctionalExtensionality.v
blob: 22cb93d56be7d8b0f40ccd51ed2f0e8f9f10b39a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
Require Import Coq.Program.Utils.
Require Import Coq.Program.Wf.

(** The converse of functional equality. *)

Lemma equal_f : forall A B : Type, forall (f g : A -> B), 
  f = g -> forall x, f x = g x.
Proof.
  intros.
  rewrite H.
  auto.
Qed.

(** Eta expansion *)

Axiom eta_expansion_dep : forall A (B : A -> Type) (f : forall x : A, B x), 
  f = fun x => f x.

Lemma eta_expansion : forall A B (f : A -> B), 
  f = fun x => f x.
Proof.
  intros ; apply eta_expansion_dep.
Qed.

(** Statements of functional equality for simple and dependent functions. *)

Axiom fun_extensionality_dep : forall A, forall B : (A -> Type), 
  forall (f g : forall x : A, B x), 
  (forall x, f x = g x) -> f = g.

Lemma fun_extensionality : forall A B (f g : A -> B), 
  (forall x, f x = g x) -> f = g.
Proof.
  intros ; apply fun_extensionality_dep.
  assumption.
Qed.

Hint Resolve fun_extensionality fun_extensionality_dep : program.

(** Unification needs help sometimes... *)
Ltac apply_ext :=
  match goal with 
    [ |- ?x = ?y ] => apply (@fun_extensionality _ _ x y)
  end.

(** The two following lemmas allow to unfold a well-founded fixpoint definition without
   restriction using the functional extensionality axiom. *)

(** For a function defined with Program using a well-founded order. *)

Lemma fix_sub_eq_ext :
  forall (A : Set) (R : A -> A -> Prop) (Rwf : well_founded R)
    (P : A -> Set)
    (F_sub : forall x : A, (forall  {y : A | R y x}, P (`y)) -> P x),
    forall x : A,
      Fix_sub A R Rwf P F_sub x =
        F_sub x (fun {y : A | R y x}=> Fix A R Rwf P F_sub (`y)).
Proof.
  intros ; apply Fix_eq ; auto.
  intros.
  assert(f = g).
  apply (fun_extensionality_dep _ _ _ _ H).
  rewrite H0 ; auto.
Qed.

(** For a function defined with Program using a measure. *)

Lemma fix_sub_measure_eq_ext :
  forall (A : Type) (f : A -> nat) (P : A -> Type)
    (F_sub : forall x : A, (forall  {y : A | f y < f x}, P (`y)) -> P x),
    forall x : A,
      Fix_measure_sub A f P F_sub x =
        F_sub x (fun {y : A | f y < f x}=> Fix_measure_sub A f P F_sub (`y)).
Proof.
  intros ; apply Fix_measure_eq ; auto.
  intros.
  assert(f0 = g).
  apply (fun_extensionality_dep _ _ _ _ H).
  rewrite H0 ; auto.
Qed.