Last active
March 3, 2025 23:13
-
-
Save CoderPuppy/b75cc0cb9abd563a3b768d733f78fa71 to your computer and use it in GitHub Desktop.
Proof inspired by a discussion with Komi in the Programming Language Development Discord
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Komi20250302 where | |
data _≡_ {A : Set} (base : A) : A → Set where | |
refl : base ≡ base | |
sym : {A : Set} {x y : A} → x ≡ y → y ≡ x | |
sym refl = refl | |
trans : {A : Set} {x y z : A} → x ≡ y → y ≡ z → x ≡ z | |
trans refl p = p | |
ap : {A B : Set} {x1 x2 : A} (f : A → B) → x1 ≡ x2 → f x1 ≡ f x2 | |
ap f refl = refl | |
ap2 : {A B C : Set} {x1 x2 : A} {y1 y2 : B} (f : A → B → C) → x1 ≡ x2 → y1 ≡ y2 → f x1 y1 ≡ f x2 y2 | |
ap2 f refl refl = refl | |
≡⟨⟩-syntax : {A : Set} (u : A) {v w : A} → u ≡ w → w ≡ v → u ≡ v | |
≡⟨⟩-syntax w = trans | |
infixr 2 ≡⟨⟩-syntax | |
syntax ≡⟨⟩-syntax u p q = u ≡⟨ p ⟩ q | |
_∎ : {A : Set} (u : A) → u ≡ u | |
_∎ u = refl | |
infix 3 _∎ | |
record Σ (base : Set) (fam : base → Set) : Set where | |
constructor [_,_] | |
field | |
fst : base | |
snd : fam fst | |
open Σ | |
syntax Σ base (λ x → fam) = [ x ∈ base ]× fam | |
data Nat : Set where | |
zero : Nat | |
succ : Nat → Nat | |
{-# BUILTIN NATURAL Nat #-} | |
succ-inj : (m n : Nat) → succ m ≡ succ n → m ≡ n | |
succ-inj m n refl = refl | |
_+N_ : Nat → Nat → Nat | |
zero +N n = n | |
succ m +N n = succ (m +N n) | |
+N-zero : (n : Nat) → (n +N 0) ≡ n | |
+N-zero zero = | |
0 ∎ | |
+N-zero (succ n) = | |
succ (n +N 0) ≡⟨ ap succ (+N-zero n) ⟩ | |
succ n ∎ | |
+N-succ : (m n : Nat) → (m +N succ n) ≡ succ (m +N n) | |
+N-succ zero n = | |
succ n ∎ | |
+N-succ (succ m) n = | |
succ (m +N succ n) ≡⟨ ap succ (+N-succ m n) ⟩ | |
succ (succ (m +N n)) ∎ | |
+N-comm : (m n : Nat) → (m +N n) ≡ (n +N m) | |
+N-comm zero n = | |
n ≡⟨ sym (+N-zero n) ⟩ | |
n +N 0 ∎ | |
+N-comm (succ m) n = | |
succ (m +N n) ≡⟨ ap succ (+N-comm m n) ⟩ | |
succ (n +N m) ≡⟨ sym (+N-succ n m) ⟩ | |
n +N succ m ∎ | |
+N-assoc : (m n o : Nat) → (m +N (n +N o)) ≡ ((m +N n) +N o) | |
+N-assoc zero n o = | |
n +N o ∎ | |
+N-assoc (succ m) n o = | |
succ (m +N (n +N o)) ≡⟨ ap succ (+N-assoc m n o) ⟩ | |
succ ((m +N n) +N o) ∎ | |
+N-inj : (m n o : Nat) → (m +N o) ≡ (n +N o) → m ≡ n | |
+N-inj m n zero p = | |
m ≡⟨ sym (+N-zero m) ⟩ | |
m +N 0 ≡⟨ p ⟩ | |
n +N 0 ≡⟨ +N-zero n ⟩ | |
n ∎ | |
+N-inj m n (succ o) p = +N-inj m n o (succ-inj (m +N o) (n +N o) ( | |
succ (m +N o) ≡⟨ sym (+N-succ m o) ⟩ | |
m +N succ o ≡⟨ p ⟩ | |
n +N succ o ≡⟨ +N-succ n o ⟩ | |
succ (n +N o) ∎ | |
)) | |
data Fin : Nat → Set where | |
zero : (n : Nat) → Fin (succ n) | |
succ : {n : Nat} → Fin n → Fin (succ n) | |
data Vec (A : Set) : Nat → Set where | |
[] : Vec A zero | |
_∷_ : {n : Nat} → A → Vec A n → Vec A (succ n) | |
replicate : {A : Set} (x : A) (n : Nat) → Vec A n | |
replicate x zero = [] | |
replicate x (succ n) = x ∷ replicate x n | |
∷-inj-head : {A : Set} {n : Nat} {h1 h2 : A} {t1 t2 : Vec A n} → (h1 ∷ t1) ≡ (h2 ∷ t2) → h1 ≡ h2 | |
∷-inj-head refl = refl | |
∷-inj-tail : {A : Set} {n : Nat} {h1 h2 : A} {t1 t2 : Vec A n} → (h1 ∷ t1) ≡ (h2 ∷ t2) → t1 ≡ t2 | |
∷-inj-tail refl = refl | |
data Expr (Γ : Nat) : Set where | |
var : Fin Γ → Expr Γ | |
inj : Nat → Expr Γ | |
_+e_ : Expr Γ → Expr Γ → Expr Γ | |
_⋅e_ : {Γ : Nat} → Nat → Expr Γ → Expr Γ | |
zero ⋅e u = inj 0 | |
succ n ⋅e u = u +e (n ⋅e u) | |
data _⊢_≡_ (Γ : Nat) : Expr Γ → Expr Γ → Set where | |
⊢refl : ∀{e} → Γ ⊢ e ≡ e | |
⊢sym : ∀{u v} → Γ ⊢ u ≡ v → Γ ⊢ v ≡ u | |
⊢trans : ∀{u v w} → Γ ⊢ u ≡ w → Γ ⊢ w ≡ v → Γ ⊢ u ≡ v | |
⊢+-comm : ∀{u v} → Γ ⊢ (u +e v) ≡ (v +e u) | |
⊢+-assoc : ∀{u v w} → Γ ⊢ (u +e (v +e w)) ≡ ((u +e v) +e w) | |
⊢inj-+ : ∀{m n} → Γ ⊢ (inj m +e inj n) ≡ inj (m +N n) | |
⊢+-zero : ∀{u} → Γ ⊢ (u +e inj 0) ≡ u | |
⊢ap-+ : ∀{ul ur vl vr} → Γ ⊢ ul ≡ vl → Γ ⊢ ur ≡ vr → Γ ⊢ (ul +e ur) ≡ (vl +e vr) | |
⊢≡⟨⟩-syntax : {Γ : Nat} (u : Expr Γ) {v w : Expr Γ} → Γ ⊢ u ≡ w → Γ ⊢ w ≡ v → Γ ⊢ u ≡ v | |
⊢≡⟨⟩-syntax w = ⊢trans | |
infixr 2 ⊢≡⟨⟩-syntax | |
syntax ⊢≡⟨⟩-syntax u p q = u ⊢≡⟨ p ⟩ q | |
_⊢∎ : {Γ : Nat} (u : Expr Γ) → Γ ⊢ u ≡ u | |
_⊢∎ u = ⊢refl | |
infix 3 _⊢∎ | |
⊢≡ : {Γ : Nat} {u v : Expr Γ} → u ≡ v → Γ ⊢ u ≡ v | |
⊢≡ refl = ⊢refl | |
⊢zero-+ : {Γ : Nat} {u : Expr Γ} → Γ ⊢ (inj 0 +e u) ≡ u | |
⊢zero-+ {Γ} {u} = | |
inj 0 +e u ⊢≡⟨ ⊢+-comm ⟩ | |
u +e inj 0 ⊢≡⟨ ⊢+-zero ⟩ | |
u ⊢∎ | |
⊢+⋅e : {Γ : Nat} (m n : Nat) (u : Expr Γ) → Γ ⊢ ((m +N n) ⋅e u) ≡ ((m ⋅e u) +e (n ⋅e u)) | |
⊢+⋅e zero n u = | |
n ⋅e u ⊢≡⟨ ⊢sym ⊢zero-+ ⟩ | |
inj 0 +e (n ⋅e u) ⊢∎ | |
⊢+⋅e (succ m) n u = | |
u +e ((m +N n) ⋅e u) ⊢≡⟨ ⊢ap-+ ⊢refl (⊢+⋅e m n u) ⟩ | |
u +e ((m ⋅e u) +e (n ⋅e u)) ⊢≡⟨ ⊢+-assoc ⟩ | |
(u +e (m ⋅e u)) +e (n ⋅e u) ⊢∎ | |
zeroes : (Γ : Nat) → Vec Nat Γ | |
zeroes Γ = replicate 0 Γ | |
record NF (Γ : Nat) : Set where | |
constructor mk-NF | |
field constant : Nat | |
field coefs : Vec Nat Γ | |
NF-inj : {Γ : Nat} → Nat → NF Γ | |
NF-inj n .NF.constant = n | |
NF-inj n .NF.coefs = zeroes _ | |
single-coef : {Γ : Nat} → Fin Γ → Vec Nat Γ | |
single-coef (zero Γ) = 1 ∷ zeroes Γ | |
single-coef (succ v) = 0 ∷ single-coef v | |
NF-var : {Γ : Nat} → Fin Γ → NF Γ | |
NF-var v .NF.constant = 0 | |
NF-var v .NF.coefs = single-coef v | |
_+coefs_ : {Γ : Nat} → Vec Nat Γ → Vec Nat Γ → Vec Nat Γ | |
[] +coefs [] = [] | |
(u ∷ us) +coefs (v ∷ vs) = (u +N v) ∷ (us +coefs vs) | |
+coefs-zero : {Γ : Nat} (u : Vec Nat Γ) → (u +coefs zeroes Γ) ≡ u | |
+coefs-zero [] = refl | |
+coefs-zero (u ∷ us) = ap2 _∷_ (+N-zero u) (+coefs-zero us) | |
+coefs-comm : {Γ : Nat} (u v : Vec Nat Γ) → (u +coefs v) ≡ (v +coefs u) | |
+coefs-comm [] [] = refl | |
+coefs-comm (u ∷ us) (v ∷ vs) = ap2 _∷_ (+N-comm u v) (+coefs-comm us vs) | |
+coefs-assoc : {Γ : Nat} (u v w : Vec Nat Γ) → (u +coefs (v +coefs w)) ≡ ((u +coefs v) +coefs w) | |
+coefs-assoc [] [] [] = refl | |
+coefs-assoc (u ∷ us) (v ∷ vs) (w ∷ ws) = ap2 _∷_ (+N-assoc u v w) (+coefs-assoc us vs ws) | |
+coefs-inj : {Γ : Nat} (u v w : Vec Nat Γ) → (u +coefs w) ≡ (v +coefs w) → u ≡ v | |
+coefs-inj [] [] [] p = p | |
+coefs-inj (u ∷ us) (v ∷ vs) (w ∷ ws) p = ap2 _∷_ | |
(+N-inj u v w (∷-inj-head p)) | |
(+coefs-inj us vs ws (∷-inj-tail p)) | |
_+NF_ : {Γ : Nat} → NF Γ → NF Γ → NF Γ | |
(u +NF v) .NF.constant = (u .NF.constant) +N (v .NF.constant) | |
(u +NF v) .NF.coefs = (u .NF.coefs) +coefs (v .NF.coefs) | |
+NF-comm : {Γ : Nat} (u v : NF Γ) → (u +NF v) ≡ (v +NF u) | |
+NF-comm u v = ap2 mk-NF | |
(+N-comm (u .NF.constant) (v .NF.constant)) | |
(+coefs-comm (u .NF.coefs) (v .NF.coefs)) | |
+NF-assoc : {Γ : Nat} (u v w : NF Γ) → (u +NF (v +NF w)) ≡ ((u +NF v) +NF w) | |
+NF-assoc u v w = ap2 mk-NF | |
(+N-assoc (u .NF.constant) (v .NF.constant) (w .NF.constant)) | |
(+coefs-assoc (u .NF.coefs) (v .NF.coefs) (w .NF.coefs)) | |
+NF-inj : {Γ : Nat} (u v w : NF Γ) → (u +NF w) ≡ (v +NF w) → u ≡ v | |
+NF-inj u v w p = ap2 mk-NF | |
(+N-inj (u .NF.constant) (v .NF.constant) (w .NF.constant) (ap NF.constant p)) | |
(+coefs-inj (u .NF.coefs) (v .NF.coefs) (w .NF.coefs) (ap NF.coefs p)) | |
eval : {Γ : Nat} → (e : Expr Γ) → NF Γ | |
eval {Γ} (var v) = NF-var v | |
eval (inj n) = NF-inj n | |
eval (u +e v) = eval u +NF eval v | |
quot-coefs : {Γ Δ : Nat} → Vec Nat Δ → (Fin Δ → Fin Γ) → Expr Γ | |
quot-coefs [] lift-var = inj 0 | |
quot-coefs (coef ∷ coefs) lift-var = (coef ⋅e var (lift-var (zero _))) +e (quot-coefs coefs λ v → lift-var (succ v)) | |
quot : {Γ : Nat} → NF Γ → Expr Γ | |
quot {Γ} nf = inj constant +e quot-coefs coefs (λ v → v) | |
where open NF nf | |
quot-coefs-zero : (Γ Δ : Nat) (lift-var : Fin Δ → Fin Γ) → Γ ⊢ quot-coefs (zeroes Δ) lift-var ≡ inj 0 | |
quot-coefs-zero Γ zero lift-var = | |
inj 0 ⊢∎ | |
quot-coefs-zero Γ (succ Δ) lift-var = | |
((0 ⋅e var (lift-var (zero Δ))) +e quot-coefs (zeroes Δ) (λ v → lift-var (succ v))) ⊢≡⟨ ⊢zero-+ ⟩ | |
quot-coefs (zeroes Δ) (λ v → lift-var (succ v)) ⊢≡⟨ quot-coefs-zero Γ Δ (λ v → lift-var (succ v)) ⟩ | |
inj 0 ⊢∎ | |
quot-coefs-+ : (Γ Δ : Nat) (lift-var : Fin Δ → Fin Γ) (u v : Vec Nat Δ) → Γ ⊢ quot-coefs (u +coefs v) lift-var ≡ (quot-coefs u lift-var +e quot-coefs v lift-var) | |
quot-coefs-+ Γ zero lift-var [] [] = | |
inj 0 ⊢≡⟨ ⊢sym ⊢inj-+ ⟩ | |
(inj 0 +e inj 0) ⊢∎ | |
quot-coefs-+ Γ (succ Δ) lift-var (u ∷ us) (v ∷ vs) = let | |
v0 = var (lift-var (zero Δ)) | |
qsum = quot-coefs (us +coefs vs) (λ v' → lift-var (succ v')) | |
qus = quot-coefs us (λ v' → lift-var (succ v')) | |
qvs = quot-coefs vs (λ v' → lift-var (succ v')) | |
in | |
(((u +N v) ⋅e v0) +e qsum) ⊢≡⟨ ⊢ap-+ (⊢+⋅e u v (var (lift-var (zero Δ)))) ⊢refl ⟩ | |
(((u ⋅e v0) +e (v ⋅e v0)) +e qsum) ⊢≡⟨ ⊢ap-+ ⊢refl (quot-coefs-+ Γ Δ (λ v' → lift-var (succ v')) us vs) ⟩ | |
(((u ⋅e v0) +e (v ⋅e v0)) +e (qus +e qvs)) ⊢≡⟨ ⊢sym ⊢+-assoc ⟩ | |
((u ⋅e v0) +e ((v ⋅e v0) +e (qus +e qvs))) ⊢≡⟨ ⊢ap-+ ⊢refl ⊢+-assoc ⟩ | |
((u ⋅e v0) +e (((v ⋅e v0) +e qus) +e qvs)) ⊢≡⟨ ⊢ap-+ ⊢refl (⊢ap-+ ⊢+-comm ⊢refl) ⟩ | |
((u ⋅e v0) +e ((qus +e (v ⋅e v0)) +e qvs)) ⊢≡⟨ ⊢ap-+ ⊢refl (⊢sym ⊢+-assoc) ⟩ | |
((u ⋅e v0) +e (qus +e ((v ⋅e v0) +e qvs))) ⊢≡⟨ ⊢+-assoc ⟩ | |
(((u ⋅e v0) +e qus) +e ((v ⋅e v0) +e qvs)) ⊢∎ | |
quot-+ : {Γ : Nat} (u v : NF Γ) → Γ ⊢ quot (u +NF v) ≡ (quot u +e quot v) | |
quot-+ {Γ} u v = let | |
coefs-sum = quot-coefs (NF.coefs (u +NF v)) (λ v₁ → v₁) | |
coefs-u = quot-coefs (NF.coefs u) (λ v' → v') | |
coefs-v = quot-coefs (NF.coefs v) (λ v' → v') | |
const-sum = inj (NF.constant (u +NF v)) | |
const-u = inj (NF.constant u) | |
const-v = inj (NF.constant v) | |
in | |
const-sum +e coefs-sum ⊢≡⟨ ⊢ap-+ (⊢sym ⊢inj-+) ⊢refl ⟩ | |
(const-u +e const-v) +e coefs-sum ⊢≡⟨ ⊢ap-+ ⊢refl (quot-coefs-+ Γ Γ (λ v' → v') (u .NF.coefs) (v .NF.coefs)) ⟩ | |
(const-u +e const-v) +e (coefs-u +e coefs-v) ⊢≡⟨ ⊢sym ⊢+-assoc ⟩ | |
const-u +e (const-v +e (coefs-u +e coefs-v)) ⊢≡⟨ ⊢ap-+ ⊢refl ⊢+-assoc ⟩ | |
const-u +e ((const-v +e coefs-u) +e coefs-v) ⊢≡⟨ ⊢ap-+ ⊢refl (⊢ap-+ ⊢+-comm ⊢refl) ⟩ | |
const-u +e ((coefs-u +e const-v) +e coefs-v) ⊢≡⟨ ⊢ap-+ ⊢refl (⊢sym ⊢+-assoc) ⟩ | |
const-u +e (coefs-u +e (const-v +e coefs-v)) ⊢≡⟨ ⊢+-assoc ⟩ | |
(const-u +e coefs-u) +e (const-v +e coefs-v) ⊢∎ | |
quot-eval-correct : {Γ : Nat} (e : Expr Γ) → Γ ⊢ quot (eval e) ≡ e | |
quot-eval-correct {Γ} (var v) = | |
inj 0 +e quot-coefs (single-coef v) (λ v₁ → v₁) ⊢≡⟨ ⊢zero-+ ⟩ | |
quot-coefs (single-coef v) (λ v₁ → v₁) ⊢≡⟨ go Γ (λ v' → v') v ⟩ | |
var v ⊢∎ | |
where | |
go : (Δ : Nat) (lift-var : Fin Δ → Fin Γ) (v : Fin Δ) → Γ ⊢ quot-coefs (single-coef v) lift-var ≡ var (lift-var v) | |
go (succ Δ) lift-var (zero .Δ) = | |
(var (lift-var (zero Δ)) +e inj 0) +e quot-coefs (zeroes Δ) (λ v₁ → lift-var (succ v₁)) ⊢≡⟨ ⊢ap-+ ⊢refl (quot-coefs-zero Γ Δ λ v' → lift-var (succ v')) ⟩ | |
(var (lift-var (zero Δ)) +e inj 0) +e inj 0 ⊢≡⟨ ⊢ap-+ ⊢+-zero ⊢refl ⟩ | |
var (lift-var (zero Δ)) +e inj 0 ⊢≡⟨ ⊢+-zero ⟩ | |
var (lift-var (zero Δ)) ⊢∎ | |
go (succ Δ) lift-var (succ v) = | |
inj 0 +e quot-coefs (single-coef v) (λ v' → lift-var (succ v')) ⊢≡⟨ ⊢zero-+ ⟩ | |
quot-coefs (single-coef v) (λ v' → lift-var (succ v')) ⊢≡⟨ go Δ (λ v' → lift-var (succ v')) v ⟩ | |
var (lift-var (succ v)) ⊢∎ | |
quot-eval-correct {Γ} (inj n) = | |
inj n +e quot-coefs (NF.coefs (eval (inj n))) (λ v → v) ⊢≡⟨ ⊢ap-+ ⊢refl (quot-coefs-zero Γ Γ (λ v → v)) ⟩ | |
inj n +e inj 0 ⊢≡⟨ ⊢+-zero ⟩ | |
inj n ⊢∎ | |
quot-eval-correct (u +e v) = | |
inj (eval (u +e v) .NF.constant) +e quot-coefs (eval (u +e v) .NF.coefs) (λ v' → v') ⊢≡⟨ quot-+ (eval u) (eval v) ⟩ | |
quot (eval u) +e quot (eval v) ⊢≡⟨ ⊢ap-+ (quot-eval-correct u) ⊢refl ⟩ | |
u +e quot (eval v) ⊢≡⟨ ⊢ap-+ ⊢refl (quot-eval-correct v) ⟩ | |
u +e v ⊢∎ | |
eval-preservation : {Γ : Nat} {u v : Expr Γ} → Γ ⊢ u ≡ v → eval u ≡ eval v | |
eval-preservation ⊢refl = refl | |
eval-preservation (⊢sym p) = sym (eval-preservation p) | |
eval-preservation (⊢trans p q) = trans (eval-preservation p) (eval-preservation q) | |
eval-preservation (⊢+-comm {u} {v}) = +NF-comm (eval u) (eval v) | |
eval-preservation (⊢+-assoc {u} {v} {w}) = +NF-assoc (eval u) (eval v) (eval w) | |
eval-preservation ⊢inj-+ = ap2 mk-NF refl (+coefs-zero (zeroes _)) | |
eval-preservation ⊢+-zero = ap2 mk-NF (+N-zero _) (+coefs-zero _) | |
eval-preservation (⊢ap-+ p q) = ap2 _+NF_ (eval-preservation p) (eval-preservation q) | |
eval-reflect : {Γ : Nat} {u v : Expr Γ} → eval u ≡ eval v → Γ ⊢ u ≡ v | |
eval-reflect {Γ} {u} {v} p = | |
u ⊢≡⟨ ⊢sym (quot-eval-correct u) ⟩ | |
quot (eval u) ⊢≡⟨ ⊢≡ (ap quot p) ⟩ | |
quot (eval v) ⊢≡⟨ quot-eval-correct v ⟩ | |
v ⊢∎ | |
theorem : {Γ : Nat} (u v : Expr Γ) → Γ ⊢ (u +e inj 1) ≡ (v +e inj 1) → Γ ⊢ u ≡ v | |
theorem u v p = | |
u ⊢≡⟨ eval-reflect (+NF-inj (eval u) (eval v) (NF-inj 1) (eval-preservation p)) ⟩ | |
v ⊢∎ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment