{-# OPTIONS --safe #-}
module Sequence where
open import Library
open import Tree using (Tree; ε; _∙_; tail; rotate; left-spine; right-spine)
open import SingleTreeGame
open ℕ
open ≡-Reasoning
cr : M
cr = c ∘ r
tr : M
tr = t ∘ r
crtr : M
crtr = c ∘ r ∘ t ∘ r
crtrr : M
crtrr = c ∘ r ∘ t ∘ r ∘ r
start : ℕ → M
start n = c ∘ c ∘ r ∘ cr ^ n ∘ t ∘ r ^ n
loop : ℕ → M
loop n = cr ∘ crtrr ^ n ∘ crtr ∘ t ∘ r ^ n
unravel : ℕ → M
unravel n = cr ∘ tr ^ n ∘ (t ∘ t)
seq : (m n : ℕ) → M
seq m n = (start n) ∘ (loop n) ^ m ∘ (unravel n)
lem-cr1 : ∀{n} → moves (C ∙ R) (ε ∙ left-spine n) ≡ just (ε ∙ left-spine (suc n))
lem-cr1 = refl
lem-cr : ∀ n m → move ((c ∘ r) ^ n) (ε ∙ left-spine m) ≡ just (ε ∙ left-spine (n + m))
lem-cr zero m = refl
lem-cr (suc n) m =
subst (λ □ → move ((c ∘ r) ^ n) (ε ∙ left-spine (suc m)) ≡ just (ε ∙ left-spine □))
(+-suc n m)
(lem-cr n (suc m))
ccrcrn : ℕ → M
ccrcrn n = c ∘ c ∘ r ∘ (c ∘ r) ^ n
thm-ccrcrn : ∀ n → move (ccrcrn n) ε ≡ just (ε ∙ left-spine (n + 1))
thm-ccrcrn n = lem-cr n 1
lem-rn : ∀ n m → move (r ^ n) (left-spine n ∙ right-spine m) ≡ just (ε ∙ right-spine (n + m))
lem-rn zero m = refl
lem-rn (suc n) m =
subst (λ □ → moves (((λ mv → R ∙ mv) ^ n) ε) (left-spine n ∙ (ε ∙ right-spine m)) ≡ just (ε ∙ right-spine □))
(+-suc n m)
(lem-rn n (suc m))
thm-trn : ∀ n → move (t ∘ r ^ n) (ε ∙ left-spine (1 + n)) ≡ just (right-spine (1 + n + 0))
thm-trn n = lem-rn n 0
lem-cr-suf : ∀ n m ms → moves ((cr ^ n) ms) (ε ∙ left-spine m) ≡ moves ms (ε ∙ left-spine (n + m))
lem-cr-suf zero m ms = refl
lem-cr-suf (suc n) m ms =
subst (λ □ → moves ((cr ^ n) ms) (ε ∙ left-spine (suc m)) ≡ moves ms (ε ∙ left-spine □))
(+-suc n m)
(lem-cr-suf n (suc m) ms)
lem-rn-suf : ∀ n m ms → moves ((r ^ n) ms) (left-spine n ∙ right-spine m) ≡ moves ms (ε ∙ right-spine (n + m))
lem-rn-suf zero m ms = refl
lem-rn-suf (suc n) m ms =
subst (λ □ → moves ((r ^ n) ms) (left-spine n ∙ (ε ∙ right-spine m)) ≡ moves ms (ε ∙ right-spine □))
(+-suc n m)
(lem-rn-suf n (suc m) ms)
thm-trn-suf : ∀ n ms → moves (t ((r ^ n) ms)) (ε ∙ left-spine (1 + n)) ≡ moves ms (right-spine (1 + n))
thm-trn-suf n ms =
subst
(λ k → moves (t ((r ^ n) ms)) (ε ∙ left-spine (1 + n)) ≡ moves ms (ε ∙ right-spine k))
(+-identityʳ n)
(lem-rn-suf n 0 ms)
thm-start-suf : ∀ n ms → moves (start n ms) ε ≡ moves ms (right-spine (1 + n))
thm-start-suf n ms =
begin
moves (start n ms) ε
≡⟨ refl ⟩
moves ((cr ^ n) (t ((r ^ n) ms))) (ε ∙ left-spine 1)
≡⟨ lem-cr-suf n 1 (t ((r ^ n) ms)) ⟩
moves (t ((r ^ n) ms)) (ε ∙ left-spine (n + 1))
≡⟨ subst
(λ k → moves (t ((r ^ n) ms)) (ε ∙ left-spine k) ≡ moves ms (right-spine (1 + n)))
(+-comm 1 n)
(thm-trn-suf n ms) ⟩
moves ms (right-spine (1 + n))
∎
thm-start : ∀ n → move (start n) ε ≡ just (right-spine (1 + n))
thm-start n = thm-start-suf n ε
lem-crtrr1 : ∀{n m} → moves ((((C ∙ R) ∙ T) ∙ R) ∙ R) (ε ∙ (right-spine (suc n) ∙ left-spine m))
≡ just (ε ∙ (right-spine n ∙ left-spine (suc m)))
lem-crtrr1 = refl
lem-crtrr : ∀ n m l → move ((c ∘ r ∘ t ∘ r ∘ r) ^ n) (ε ∙ (right-spine (n + m) ∙ left-spine l))
≡ just (ε ∙ (right-spine m ∙ left-spine (n + l)))
lem-crtrr zero m l = refl
lem-crtrr (suc n) m l =
subst
(λ k → move ((c ∘ r ∘ t ∘ r ∘ r) ^ n) (ε ∙ (right-spine (n + m) ∙ left-spine (suc l)))
≡ just (ε ∙ (right-spine m ∙ left-spine k)))
(+-suc n l)
(lem-crtrr n m (suc l))
lem-crtr : ∀{m} → moves (((C ∙ R) ∙ T) ∙ R) (ε ∙ (ε ∙ left-spine m))
≡ just (ε ∙ left-spine (suc m))
lem-crtr = refl
lem-cr-suf-right : ∀ n ms → moves (cr ms) (right-spine (1 + n)) ≡ moves ms (ε ∙ (right-spine n ∙ ε))
lem-cr-suf-right n ms = refl
lem-crtrr-suf : ∀ n m l ms → moves ((crtrr ^ n) ms) (ε ∙ (right-spine (n + m) ∙ left-spine l))
≡ moves ms (ε ∙ (right-spine m ∙ left-spine (n + l)))
lem-crtrr-suf zero m l ms = refl
lem-crtrr-suf (suc n) m l ms =
subst
(λ k → moves ((crtrr ^ n) ms) (ε ∙ (right-spine (n + m) ∙ left-spine (suc l)))
≡ moves ms (ε ∙ (right-spine m ∙ left-spine k)))
(+-suc n l)
(lem-crtrr-suf n m (suc l) ms)
lem-crtr-suf : ∀ m ms → moves (crtr ms) (ε ∙ (ε ∙ left-spine m)) ≡ moves ms (ε ∙ left-spine (suc m))
lem-crtr-suf m ms = refl
thm-loop-suf : ∀ n ms → moves (loop n ms) (right-spine (1 + n)) ≡ moves ms (right-spine (1 + n))
thm-loop-suf n ms =
begin
moves (loop n ms) (right-spine (1 + n))
≡⟨ lem-cr-suf-right n ((crtrr ^ n) (crtr (t ((r ^ n) ms)))) ⟩
moves ((crtrr ^ n) (crtr (t ((r ^ n) ms)))) (ε ∙ (right-spine n ∙ ε))
≡⟨ subst
(λ k → moves ((crtrr ^ n) (crtr (t ((r ^ n) ms)))) (ε ∙ (right-spine k ∙ ε))
≡ moves (crtr (t ((r ^ n) ms))) (ε ∙ (ε ∙ left-spine (n + 0))))
(+-identityʳ n)
(lem-crtrr-suf n 0 0 (crtr (t ((r ^ n) ms)))) ⟩
moves (crtr (t ((r ^ n) ms))) (ε ∙ (ε ∙ left-spine (n + 0)))
≡⟨ subst
(λ k → moves (crtr (t ((r ^ n) ms))) (ε ∙ (ε ∙ left-spine k))
≡ moves (t ((r ^ n) ms)) (ε ∙ left-spine (suc n)))
(sym (+-identityʳ n))
(lem-crtr-suf n (t ((r ^ n) ms))) ⟩
moves (t ((r ^ n) ms)) (ε ∙ left-spine (suc n))
≡⟨ thm-trn-suf n ms ⟩
moves ms (right-spine (1 + n))
∎
thm-loop : ∀ n → move (loop n) (right-spine (1 + n)) ≡ just (right-spine (1 + n))
thm-loop n = thm-loop-suf n ε
thm-loop-m-suf : ∀ m n ms → moves (((loop n) ^ m) ms) (right-spine (1 + n)) ≡ moves ms (right-spine (1 + n))
thm-loop-m-suf zero n ms = refl
thm-loop-m-suf (suc m) n ms =
begin
moves (((loop n) ^ suc m) ms) (right-spine (1 + n))
≡⟨ thm-loop-suf n (((loop n) ^ m) ms) ⟩
moves (((loop n) ^ m) ms) (right-spine (1 + n))
≡⟨ thm-loop-m-suf m n ms ⟩
moves ms (right-spine (1 + n))
∎
thm-loop-m : ∀ m n → move ((loop n) ^ m) (right-spine (1 + n)) ≡ just (right-spine (1 + n))
thm-loop-m m n = thm-loop-m-suf m n ε
lem-trr1 : ∀{n} → moves (T ∙ R) (ε ∙ (right-spine (suc n) ∙ ε))
≡ just (ε ∙ (right-spine n ∙ ε))
lem-trr1 = refl
lem-trr : ∀ n m → move ((t ∘ r) ^ n) (ε ∙ (right-spine (n + m) ∙ ε))
≡ just (ε ∙ (right-spine m ∙ ε))
lem-trr zero m = refl
lem-trr (suc n) m = lem-trr n m
lem-tr-suf : ∀ n m ms → moves ((tr ^ n) ms) (ε ∙ (right-spine (n + m) ∙ ε))
≡ moves ms (ε ∙ (right-spine m ∙ ε))
lem-tr-suf zero m ms = refl
lem-tr-suf (suc n) m ms = lem-tr-suf n m ms
thm-unravel-suf : ∀ n ms → moves (unravel n ms) (right-spine (1 + n)) ≡ moves ms ε
thm-unravel-suf n ms =
begin
moves (unravel n ms) (right-spine (1 + n))
≡⟨ lem-cr-suf-right n ((tr ^ n) (t (t ms))) ⟩
moves ((tr ^ n) (t (t ms))) (ε ∙ (right-spine n ∙ ε))
≡⟨ subst
(λ k → moves ((tr ^ n) (t (t ms))) (ε ∙ (right-spine k ∙ ε))
≡ moves (t (t ms)) (ε ∙ (ε ∙ ε)))
(+-identityʳ n)
(lem-tr-suf n 0 (t (t ms))) ⟩
moves (t (t ms)) (ε ∙ (ε ∙ ε))
≡⟨ refl ⟩
moves ms ε
∎
thm-unravel : ∀ n → move (unravel n) (right-spine (1 + n)) ≡ just ε
thm-unravel n = thm-unravel-suf n ε
thm-seq : ∀ m n → move (seq m n) ε ≡ just ε
thm-seq m n =
begin
move (seq m n) ε
≡⟨ thm-start-suf n (((loop n) ^ m) (unravel n ε)) ⟩
moves (((loop n) ^ m) (unravel n ε)) (right-spine (1 + n))
≡⟨ thm-loop-m-suf m n (unravel n ε) ⟩
move (unravel n) (right-spine (1 + n))
≡⟨ thm-unravel n ⟩
just ε
∎