aboutsummaryrefslogtreecommitdiff
path: root/src/Util/IdfunWithAlt.v
blob: 8bc13019cb4289092c658c0218f025d7eb75131a (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
(** Some constants that return their first argument, and hold an equal second argument. *)
Require Import Crypto.Util.Tuple.
Definition id_with_alt {A} (value : A) (value_for_alt : A) : A
:= value.
Definition id_with_alt_proof {A} (value : A) (value_for_alt : A)
           {pf : value = value_for_alt}
  : A
  := id_with_alt value value_for_alt.

Section tuple.
  Context {A : Type}.

  Fixpoint id_tuple'_with_alt {n}
    : forall (value value_for_alt : tuple' A n),
      tuple' A n
    := match n return forall value value_for_alt : tuple' A n, tuple' A n with
       | O => id_with_alt
       | S n' => fun (value value_for_alt : tuple' A n' * A)
                 => (@id_tuple'_with_alt n' (fst value) (fst value_for_alt),
                     @id_with_alt A (snd value) (snd value_for_alt))
       end.

  Fixpoint id_tuple'_with_alt_proof {n}
    : forall (value value_for_alt : tuple' A n) {pf : value = value_for_alt},
      tuple' A n
    := match n return forall value value_for_alt : tuple' A n, _ -> tuple' A n with
       | O => id_with_alt_proof
       | S n' => fun (value value_for_alt : tuple' A n' * A) (pf : value = value_for_alt)
                 => (@id_tuple'_with_alt_proof n' (fst value) (fst value_for_alt)
                                               (f_equal (@fst _ _) pf),
                     @id_with_alt_proof A (snd value) (snd value_for_alt)
                                        (f_equal (@snd _ _) pf))
       end.
End tuple.
Definition id_tuple_with_alt {A n}
  : forall (value value_for_alt : tuple A n), tuple A n
  := match n with
     | O => id_with_alt
     | S n' => id_tuple'_with_alt
     end.
Definition id_tuple_with_alt_proof {A n}
  : forall (value value_for_alt : tuple A n) {pf : value = value_for_alt},
    tuple A n
  := match n with
     | O => id_with_alt_proof
     | S n' => id_tuple'_with_alt_proof
     end.

Lemma unfold_id_with_alt {A} value value'
  : @id_with_alt A value value' = value.
Proof. reflexivity. Qed.
Lemma unfold_id_with_alt_proof {A} value value' pf
  : @id_with_alt_proof A value value' pf = value.
Proof. reflexivity. Qed.
Local Ltac t_ind n :=
  let IHn := fresh "IHn" in
  induction n as [|n IHn]; cbn [id_tuple'_with_alt id_tuple'_with_alt_proof];
  first [ rewrite unfold_id_with_alt | rewrite unfold_id_with_alt_proof ];
  [ reflexivity
  | rewrite IHn, <- surjective_pairing; reflexivity ].
Lemma unfold_id_tuple'_with_alt {A n} value value'
  : @id_tuple'_with_alt A n value value' = value.
Proof. t_ind n. Qed.
Lemma unfold_id_tuple'_with_alt_proof {A n} value value' pf
  : @id_tuple'_with_alt_proof A n value value' pf = value.
Proof. t_ind n. Qed.
Lemma unfold_id_tuple_with_alt {A n} value value'
  : @id_tuple_with_alt A n value value' = value.
Proof.
  destruct n; cbn [id_tuple_with_alt];
    [ apply unfold_id_with_alt | apply unfold_id_tuple'_with_alt ].
Qed.
Lemma unfold_id_tuple_with_alt_proof {A n} value value' pf
  : @id_tuple_with_alt_proof A n value value' pf = value.
Proof.
  destruct n; cbn [id_tuple_with_alt_proof];
    [ apply unfold_id_with_alt_proof | apply unfold_id_tuple'_with_alt_proof ].
Qed.