aboutsummaryrefslogtreecommitdiff
path: root/test-suite/output/bug_9403.v
blob: b915e7fbce059d41aa3fd971a63c37c6ac894525 (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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
(* Uselessly long but why not *)

From Coq Require Export Utf8.

Local Set Universe Polymorphism.

Module tele.
(** Telescopes *)
Inductive tele : Type :=
  | TeleO : tele
  | TeleS {X} (binder : X  tele) : tele.

Arguments TeleS {_} _.

(** The telescope version of Coq's function type *)
Fixpoint tele_fun (TT : tele) (T : Type) : Type :=
  match TT with
  | TeleO => T
  | TeleS b =>  x, tele_fun (b x) T
  end.

Notation "TT -t> A" :=
  (tele_fun TT A) (at level 99, A at level 200, right associativity).

(** An eliminator for elements of [tele_fun].
    We use a [fix] because, for some reason, that makes stuff print nicer
    in the proofs in iris:bi/lib/telescopes.v *)
Definition tele_fold {X Y} {TT : tele} (step :  {A : Type}, (A  Y)  Y) (base : X  Y)
  : (TT -t> X)  Y :=
  (fix rec {TT} : (TT -t> X)  Y :=
     match TT as TT return (TT -t> X)  Y with
     | TeleO => λ x : X, base x
     | TeleS b => λ f, step (λ x, rec (f x))
     end) TT.
Arguments tele_fold {_ _ !_} _ _ _ /.

(** A sigma-like type for an "element" of a telescope, i.e. the data it
  takes to get a [T] from a [TT -t> T]. *)
Inductive tele_arg : tele  Type :=
| TargO : tele_arg TeleO
(* the [x] is the only relevant data here *)
| TargS {X} {binder} (x : X) : tele_arg (binder x)  tele_arg (TeleS binder).

Definition tele_app {TT : tele} {T} (f : TT -t> T) : tele_arg TT  T :=
  λ a, (fix rec {TT} (a : tele_arg TT) : (TT -t> T)  T :=
     match a in tele_arg TT return (TT -t> T)  T with
     | TargO => λ t : T, t
     | TargS x a => λ f, rec a (f x)
     end) TT a f.
Arguments tele_app {!_ _} _ !_ /.

Coercion tele_arg : tele >-> Sortclass.
Local Coercion tele_app : tele_fun >-> Funclass.

(** Operate below [tele_fun]s with argument telescope [TT]. *)
Fixpoint tele_bind {U} {TT : tele} : (TT  U)  TT -t> U :=
  match TT as TT return (TT  U)  TT -t> U with
  | TeleO => λ F, F TargO
  | @TeleS X b => λ (F : TeleS b  U) (x : X), (* b x -t> U *)
                  tele_bind (λ a, F (TargS x a))
  end.
Arguments tele_bind {_ !_} _ /.

(** Notation-compatible telescope mapping *)
(* This adds (tele_app  tele_bind), which is an identity function, around every
   binder so that, after simplifying, this matches the way we typically write
   notations involving telescopes. *)
Notation "t $ r" := (t r)
  (at level 65, right associativity, only parsing).
Notation "'λ..' x .. y , e" :=
  (tele_app $ tele_bind (λ x, .. (tele_app $ tele_bind (λ y, e)) .. ))
  (at level 200, x binder, y binder, right associativity,
   format "'[  ' 'λ..'  x  ..  y ']' ,  e").

(** Telescopic quantifiers *)
Definition texist {TT : tele} (Ψ : TT  Prop) : Prop :=
  tele_fold ex (λ x, x) (tele_bind Ψ).
Arguments texist {!_} _ /.

Notation "'∃..' x .. y , P" := (texist (λ x, .. (texist (λ y, P)) .. ))
  (at level 200, x binder, y binder, right associativity,
  format "∃..  x  ..  y ,  P").
End tele.
Import tele.

(* This is like Iris' accessors, but in Prop.  Just to play with telescopes. *)
Definition accessor {X : tele} (α β γ : X  Prop) : Prop :=
  .. x, α x  (β x  γ x).

(* Working with abstract telescopes. *)
Section tests.
Context {X : tele}.
Implicit Types α β γ : X  Prop.

Lemma acc_mono_disj α β γ1 γ2 :
  accessor α β γ1  accessor α β (λ.. x, γ1 x  γ2 x).
Show.
Abort.
End tests.