|
| 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