summaryrefslogtreecommitdiff
path: root/src/Problem18.agda
diff options
context:
space:
mode:
authorChloe Brown <chloe.brown.00@outlook.com>2024-01-22 11:51:56 +0000
committerChloe Brown <chloe.brown.00@outlook.com>2024-01-22 11:51:56 +0000
commit4527250aee1d1d4655e84f0583d04410b7c53642 (patch)
treea87ce7f38a26b1d9fb11248f9428704816fc4fb4 /src/Problem18.agda
Advent of proof submissions.HEADmaster
Completed all problems save 12, where I had to postulate two lemma.
Diffstat (limited to 'src/Problem18.agda')
-rw-r--r--src/Problem18.agda113
1 files changed, 113 insertions, 0 deletions
diff --git a/src/Problem18.agda b/src/Problem18.agda
new file mode 100644
index 0000000..e71dcb9
--- /dev/null
+++ b/src/Problem18.agda
@@ -0,0 +1,113 @@
+{-# OPTIONS --safe #-}
+
+module Problem18 (Symbol : Set) where
+
+open import Data.Nat
+open import Data.Vec
+open import Relation.Binary.PropositionalEquality
+open import Data.Product
+
+open ≡-Reasoning
+
+variable n m a b c d : ℕ
+
+data Patch : ℕ → ℕ → Set where
+ end : Patch 0 0
+ skp : Patch n m → Patch (suc n) (suc m)
+ del : Patch n m → Patch (suc n) m
+ ins : Symbol → Patch n m → Patch n (suc m)
+
+apply : Patch n m → Vec Symbol n → Vec Symbol m
+apply end [] = []
+apply (ins x p) xs = x ∷ apply p xs
+apply (skp p) (x ∷ xs) = x ∷ apply p xs
+apply (del p) (x ∷ xs) = apply p xs
+
+infixl 50 _·_
+_·_ : Patch a b → Patch b c → Patch a c
+end · p₂ = p₂
+skp p₁ · skp p₂ = skp (p₁ · p₂)
+skp p₁ · del p₂ = del (p₁ · p₂)
+skp p₁ · ins x p₂ = ins x (skp p₁ · p₂)
+ins x p₁ · ins x₂ p₂ = ins x₂ (ins x p₁ · p₂)
+del p₁ · ins x₂ p₂ = ins x₂ (del p₁ · p₂)
+del p₁ · p₂ = del (p₁ · p₂)
+ins x p₁ · skp p₂ = ins x (p₁ · p₂)
+ins x p₁ · del p₂ = p₁ · p₂
+
+_≈_ : (x y : Patch a b) → Set
+x ≈ y = ∀ d → apply x d ≡ apply y d
+
+compose-correct : ∀ (p₁ : Patch a b) (p₂ : Patch b c) (d : Vec Symbol a)
+ → apply (p₁ · p₂) d ≡ apply p₂ (apply p₁ d)
+compose-correct end p₂ [] = refl
+compose-correct (skp p₁) (skp p₂) (x ∷ d) = cong (x ∷_) (compose-correct p₁ p₂ d)
+compose-correct (skp p₁) (del p₂) (x ∷ d) = compose-correct p₁ p₂ d
+compose-correct (skp p₁) (ins y p₂) (x ∷ d) = cong (y ∷_) (compose-correct (skp p₁) p₂ (x ∷ d))
+compose-correct (del p₁) end (x ∷ d) = compose-correct p₁ end d
+compose-correct (del p₁) (skp p₂) (x ∷ d) = compose-correct p₁ (skp p₂) d
+compose-correct (del p₁) (del p₂) (x ∷ d) = compose-correct p₁ (del p₂) d
+compose-correct (del p₁) (ins y p₂) (x ∷ d) = cong (y ∷_) (compose-correct (del p₁) p₂ (x ∷ d))
+compose-correct (ins y p₁) (skp p₂) d = cong (y ∷_) (compose-correct p₁ p₂ d)
+compose-correct (ins y p₁) (del p₂) d = compose-correct p₁ p₂ d
+compose-correct (ins y p₁) (ins z p₂) d = cong (z ∷_) (compose-correct (ins y p₁) p₂ d)
+
+compose-assoc : ∀ (p₁ : Patch a b) (p₂ : Patch b c) (p₃ : Patch c d)
+ → (p₁ · p₂) · p₃ ≈ p₁ · (p₂ · p₃)
+compose-assoc p₁ p₂ p₃ d = begin
+ apply (p₁ · p₂ · p₃) d ≡⟨ compose-correct (p₁ · p₂) p₃ d ⟩
+ apply p₃ (apply (p₁ · p₂) d) ≡⟨ cong (apply p₃) (compose-correct p₁ p₂ d) ⟩
+ apply p₃ (apply p₂ (apply p₁ d)) ≡˘⟨ compose-correct p₂ p₃ (apply p₁ d) ⟩
+ apply (p₂ · p₃) (apply p₁ d) ≡˘⟨ compose-correct p₁ (p₂ · p₃) d ⟩
+ apply (p₁ · (p₂ · p₃)) d ∎
+
+
+record Merge (p₁ : Patch a b)(p₂ : Patch a c) : Set where
+ constructor M
+ field size : ℕ
+ field p₁′ : Patch b size
+ field p₂′ : Patch c size
+
+
+merge : ∀(p₁ : Patch a b)(p₂ : Patch a c) → Merge p₁ p₂
+merge end end = M 0 end end
+merge p₁ (ins x p₂) = let m = merge p₁ p₂ in M (suc (Merge.size m)) (ins x (Merge.p₁′ m)) (skp (Merge.p₂′ m))
+merge (ins x p₁) p₂ = let m = merge p₁ p₂ in M (suc (Merge.size m)) (skp (Merge.p₁′ m)) (ins x (Merge.p₂′ m))
+merge (del p₁) (skp p₂) = let m = merge p₁ p₂ in M (Merge.size m) (Merge.p₁′ m) (del (Merge.p₂′ m))
+merge (skp p₁) (del p₂) = let m = merge p₁ p₂ in M (Merge.size m) (del (Merge.p₁′ m)) (Merge.p₂′ m)
+merge (del p₁) (del p₂) = let m = merge p₁ p₂ in M (Merge.size m) (Merge.p₁′ m) (Merge.p₂′ m)
+merge (skp p₁) (skp p₂) = let m = merge p₁ p₂ in M (suc (Merge.size m)) (skp (Merge.p₁′ m)) (skp (Merge.p₂′ m))
+
+merge-pushout :
+ (p₁ : Patch a b) (p₂ : Patch a c) →
+ p₁ · Merge.p₁′ (merge p₁ p₂) ≈ p₂ · Merge.p₂′ (merge p₁ p₂)
+merge-pushout end end d = refl
+merge-pushout end (ins z p₂) d = cong (z ∷_) (merge-pushout end p₂ d)
+merge-pushout (skp p₁) (skp p₂) (x ∷ d) = cong (x ∷_) (merge-pushout p₁ p₂ d)
+merge-pushout (skp p₁) (del p₂) (x ∷ d) = begin
+ apply (p₁ · Merge.p₁′ (merge p₁ p₂)) d ≡⟨ merge-pushout p₁ p₂ d ⟩
+ apply (p₂ · Merge.p₂′ (merge p₁ p₂)) d ≡⟨ compose-correct p₂ (Merge.p₂′ (merge p₁ p₂)) d ⟩
+ apply (Merge.p₂′ (merge p₁ p₂)) (apply p₂ d) ≡⟨⟩
+ apply (Merge.p₂′ (merge p₁ p₂)) (apply (del p₂) (x ∷ d)) ≡˘⟨ compose-correct (del p₂) (Merge.p₂′ (merge p₁ p₂)) (x ∷ d) ⟩
+ apply (del p₂ · Merge.p₂′ (merge p₁ p₂)) (x ∷ d) ∎
+merge-pushout (skp p₁) (ins z p₂) d = cong (z ∷_) (merge-pushout (skp p₁) p₂ d )
+merge-pushout (del p₁) (skp p₂) (x ∷ d) = begin
+ apply (del p₁ · Merge.p₁′ (merge p₁ p₂)) (x ∷ d) ≡⟨ compose-correct (del p₁) (Merge.p₁′ (merge p₁ p₂)) (x ∷ d) ⟩
+ apply (Merge.p₁′ (merge p₁ p₂)) (apply (del p₁) (x ∷ d)) ≡⟨⟩
+ apply (Merge.p₁′ (merge p₁ p₂)) (apply p₁ d) ≡˘⟨ compose-correct p₁ (Merge.p₁′ (merge p₁ p₂)) d ⟩
+ apply (p₁ · Merge.p₁′ (merge p₁ p₂)) d ≡⟨ merge-pushout p₁ p₂ d ⟩
+ apply (p₂ · Merge.p₂′ (merge p₁ p₂)) d ∎
+merge-pushout (del p₁) (del p₂) (x ∷ d) = begin
+ apply (del p₁ · Merge.p₁′ (merge p₁ p₂)) (x ∷ d) ≡⟨ compose-correct (del p₁) (Merge.p₁′ (merge p₁ p₂)) (x ∷ d) ⟩
+ apply (Merge.p₁′ (merge p₁ p₂)) (apply (del p₁) (x ∷ d)) ≡⟨⟩
+ apply (Merge.p₁′ (merge p₁ p₂)) (apply p₁ d) ≡˘⟨ compose-correct p₁ (Merge.p₁′ (merge p₁ p₂)) d ⟩
+ apply (p₁ · Merge.p₁′ (merge p₁ p₂)) d ≡⟨ merge-pushout p₁ p₂ d ⟩
+ apply (p₂ · Merge.p₂′ (merge p₁ p₂)) d ≡⟨ compose-correct p₂ (Merge.p₂′ (merge p₁ p₂)) d ⟩
+ apply (Merge.p₂′ (merge p₁ p₂)) (apply p₂ d) ≡⟨⟩
+ apply (Merge.p₂′ (merge p₁ p₂)) (apply (del p₂) (x ∷ d)) ≡˘⟨ compose-correct (del p₂) (Merge.p₂′ (merge p₁ p₂)) (x ∷ d) ⟩
+ apply (del p₂ · Merge.p₂′ (merge p₁ p₂)) (x ∷ d) ∎
+merge-pushout (del p₁) (ins z p₂) d = cong (z ∷_) (merge-pushout (del p₁) p₂ d)
+merge-pushout (ins y p₁) end d = cong (y ∷_) (merge-pushout p₁ end d)
+merge-pushout (ins y p₁) (skp p₂) d = cong (y ∷_) (merge-pushout p₁ (skp p₂) d)
+merge-pushout (ins y p₁) (del p₂) d = cong (y ∷_) (merge-pushout p₁ (del p₂) d)
+merge-pushout (ins y p₁) (ins z p₂) d = cong (z ∷_) (merge-pushout (ins y p₁) p₂ d)