Skip to content

Commit d759a55

Browse files
NotBad4Ufblanqui
andauthored
Add interfaces to declare generic level polymorphic n-ary functions (#73)
This work is based on Guillaume Allais - "Generic Level Polymorphic N-ary Functions" (TyDe 2019) Co-authored-by: Frédéric Blanqui <frederic.blanqui@inria.fr>
1 parent 9f94c03 commit d759a55

3 files changed

Lines changed: 141 additions & 0 deletions

File tree

‎CHANGES.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/).
77

88
### Added
99

10+
- Pos: builtins for parsing decimal numbers
11+
- Univ: universe levels for Set and Prop
1012
- Quotient: quotient types
13+
- NaryFun: n-ary functions and relations
1114

1215
### Changed
1316

‎HOL.lp‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,8 @@ notation ⤳d infix right 20;
1313
rule $a ⤳d λ _,$b.[] ↪ $a ⤳ $b;
1414

1515
rule τ ($a ⤳d λ x,$b.[x]) ↪ Π x:τ $a, τ $b.[x];
16+
17+
// function composition \circ
18+
symbol ∘ [a b c] : τ (b ⤳ c) → τ (a ⤳ b) → τ a → τ c ≔ λ g f x, g (f x);
19+
20+
notation ∘ infix 20;

‎NaryFun.lp‎

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
/* n-ary functions and relations
2+
3+
following "Generic Level Polymorphic N-ary Functions" by Guillaume
4+
Allais (TyDe 2019). */
5+
6+
require open Stdlib.HOL Stdlib.Nat;
7+
8+
// vectors of type codes
9+
inductive VSet : ℕ → TYPE ≔
10+
| ◃ : VSet 0 // \smalltriangleleft
11+
| ▹ : Set → Π [n], VSet n → VSet (n +1); // \smalltriangleright
12+
13+
notation ▹ infix right 10;
14+
15+
// tail
16+
symbol tl [n] : VSet (n +1) → VSet n;
17+
rule tl (_ ▹ $ts) ↪ $ts;
18+
19+
// constant vector
20+
injective symbol vcst n (t : Set) : VSet n;
21+
rule vcst 0 _ ↪ ◃
22+
with vcst ($n +1) $t ↪ $t ▹ vcst $n $t;
23+
24+
// type code of n-ary functions: fun (a₁ ▹ … ▹ aₙ ▹ ◃) b ≡ a₁ ⤳ … ⤳ aₙ ⤳ b
25+
symbol fun [n] : VSet n → Set → Set;
26+
rule fun ◃ $b ↪ $b
27+
with fun ($t ▹ $ts) $b ↪ $t ⤳ fun $ts $b;
28+
29+
// fun is not injective, however (fun d) and (fun _ b) are both injective
30+
// we can therefore safely add the following unification rules:
31+
unif_rule fun $x $y ≡ fun $x $y' ↪ [$y ≡ $y'];
32+
unif_rule fun $x $y ≡ fun $x' $y ↪ [$x ≡ $x'];
33+
unif_rule fun $x $y ≡ $y ↪ [$x ≡ ◃];
34+
35+
// type of n-ary functions
36+
symbol Fun [n] (dom : VSet n) cod ≔ τ (fun dom cod);
37+
38+
// type of n-ary endofunctions
39+
injective symbol Endo n a ≔ Fun (vcst n a) a;
40+
41+
// lift (a₁ ▹ … ▹ aₙ ▹ ◃) p f x₁ … xₙ ≡ p (f x₁ … xₙ)
42+
symbol lift [a b n] (d: VSet n): (τ a → τ b) → Fun d a → Fun d b;
43+
rule lift ◃ $op $f ↪ $op $f
44+
with lift (_ ▹ $ts) $op $f ↪ λ x, lift $ts $op ($f x);
45+
46+
// comp (a₁ ▹ … ▹ aₙ ▹ ◃) g f x₁ … xₙ ≡ g x₁ … xₙ ∘ f
47+
symbol comp [n] (d: VSet n) [j b] (g: Fun d (j ⤳ b)) [i] (f: τ i → τ j)
48+
: Fun d (i ⤳ b) ≔ lift d (λ h:_ → τ b, h ∘ f) g;
49+
50+
// lift2 (a₁ ▹ … ▹ aₙ ▹ ◃) p f g x₁ … xₙ ≡ p (f x₁ … xₙ) (g x₁ … xₙ)
51+
symbol lift2 [a b c n] (d: VSet n) :
52+
(τ a → τ b → τ c) → Fun d a → Fun d b → Fun d c;
53+
rule lift2 ◃ $op $f $g ↪ $op $f $g
54+
with lift2 (_ ▹ $ts) $op $f $g ↪ λ x, lift2 $ts $op ($f x) ($g x);
55+
56+
// cong (a₁ ▹ … ▹ aₙ ▹ ◃) r f g ≡
57+
// `∀ x₁,`∀ y₁, x₁ = y₁ ⇒ … ⇒ `∀ xₙ,`∀ yₙ, xₙ = yₙ ⇒ f x₁ … xₙ = g y₁ … yₙ
58+
symbol cong [n] (ts: VSet n) [r] (f g: Fun ts r): Prop;
59+
rule cong ◃ $f $g ↪ $f = $g
60+
with cong (_ ▹ $ts) $f $g ↪ `∀ x,`∀ y, x = y ⇒ cong $ts ($f x) ($g y);
61+
62+
opaque symbol refl_cong [n] (ts: VSet n) [r] (f: Fun ts r): π(cong ts f f) ≔
63+
begin
64+
have aux: Π r n (ts: VSet n) (f: Fun ts r), π(cong ts f f) {
65+
assume r n; refine ind_VSet (λ n ts, `∀ f, cong ts [r] f f) _ _ n
66+
{ reflexivity }
67+
{ assume t m ts ih f x y xy; rewrite xy; refine ih (f y) }
68+
};
69+
assume n ts r; refine aux r n ts
70+
end;
71+
72+
require open Stdlib.Impred;
73+
74+
// subst (a₁ ▹ … ▹ aₙ ▹ ◃) f g ≡
75+
// `∀x₁:τa₁,`∀y₁, x₁ = y₁ ⇒ … ⇒ `∀xₙ:τaₙ,`∀yₙ, xₙ = yₙ ⇒ f x₁ … xₙ ⇒ g y₁ … yₙ
76+
symbol subst [n] (ts: VSet n) (f g: Fun ts o): Prop;
77+
rule subst ◃ $f $g ↪ $f ⇒ $g
78+
with subst (_ ▹ $ts) $f $g ↪ `∀ x,`∀ y, x = y ⇒ subst $ts ($f x) ($g y);
79+
80+
opaque symbol refl_subst [n] (ts: VSet n) (p: Fun ts o): π(subst ts p p) ≔
81+
begin
82+
assume n; refine ind_VSet (λ n ts, `∀ p, subst ts p p) _ _ n
83+
{ assume p h; refine h }
84+
{ assume t m ts ih p x y xy; rewrite xy; refine ih (p y) }
85+
end;
86+
87+
// lifted connectors
88+
symbol ∧ₙ [n] [d: VSet n] ≔ lift2 d (∧);
89+
symbol ∨ₙ [n] [d: VSet n] ≔ lift2 d (∨);
90+
symbol ⇒ₙ [n] [d: VSet n] ≔ lift2 d (⇒);
91+
92+
// quantₙ Q (a₁ ▹ … ▹ aₙ ▹ ◃) p ≡ `Q x₁, …, `Q xₙ, p x₁ … xₙ
93+
symbol quantₙ (q: Π a, (τ a → Prop) → Prop) [n] (ts: VSet n): Fun ts o → Prop;
94+
rule quantₙ _ ◃ $p ↪ $p
95+
with quantₙ $q ($t ▹ $ts) $p ↪ $q $t (λ x, quantₙ $q $ts ($p x));
96+
97+
symbol ∀ₙ [n] ≔ @quantₙ @∀ n;
98+
symbol ∃ₙ [n] ≔ @quantₙ @∃ n;
99+
100+
// tests
101+
102+
private symbol f1 : Endo 4 o;
103+
104+
private opaque symbol ex_cong a b c d x y w z :
105+
π (a = x) → π (b = y) → π (c = w) → π (d = z) → π (f1 a b c d = f1 x y w z) ≔
106+
begin
107+
assume a b c d x y w z heq1 heq2 heq3 heq4;
108+
refine refl_cong (o ▹ o ▹ o ▹ o ▹ ◃) f1 _ _ heq1 _ _ heq2 _ _ heq3 _ _ heq4
109+
end;
110+
111+
private opaque symbol ex_cong_param a b c d x y w z
112+
(g : Fun (o ▹ o ▹ o ▹ o ▹ ◃) o) :
113+
π (a = x) → π (b = y) → π (c = w) → π (d = z) → π (g a b c d = g x y w z) ≔
114+
begin
115+
assume a b c d x y w z g heq1 heq2 heq3 heq4;
116+
refine refl_cong (o ▹ o ▹ o ▹ o ▹ ◃) g _ _ heq1 _ _ heq2 _ _ heq3 _ _ heq4
117+
end;
118+
119+
private opaque symbol ex_cong_add (a b x y : ℕ) :
120+
π (a = x) → π (b = y) → π (a + b = x + y) ≔
121+
begin
122+
assume a b x y h1 h2;
123+
refine refl_cong (nat ▹ nat ▹ ◃) (+) _ _ h1 _ _ h2
124+
end;
125+
126+
assert x y ⊢ let u ≔ comp (nat ▹ ◃) (+) (+1) in u x y ≡ x + (y +1);
127+
128+
private opaque symbol testSubst (p: Fun (nat ▹ nat ▹ ◃) o) a b x y:
129+
π (a = x) → π (b = y) → π (p a b) → π (p x y) ≔
130+
begin
131+
assume p a b x y ax by;
132+
refine refl_subst (nat ▹ nat ▹ ◃) p _ _ ax _ _ by
133+
end;

0 commit comments

Comments
 (0)