{-# OPTIONS --safe #-}
open import Library hiding (m; n)
open import Data.Nat using (NonZero)
open import Tree using (ε; _⨮_)
open import SingleTreeGame using (Moves; ε; moves)
open import Sequence using (seq; thm-seq)
open import ResourcedSingleTreeGame using (rempty; module RMoves)
open import Counting using (MoveCounts; count; C:_T:_R:_; thm-counts-seq)
module Approx (N : ℕ) where
open ℕ
open ≤-Reasoning
p : ℕ
p = N * 36 + 10
q : ℕ
q = N * N * 36 + N * 12 + 3
Fraction = q ≥ N * p
fraction : Fraction
fraction = begin
N * p
≤⟨ m≤m+n (N * p) (N * 2 + 3) ⟩
N * p + (N * 2 + 3)
≡⟨ step N ⟩
q
∎
where
open ≤-Reasoning
step : ∀ N → N * (N * 36 + 10) + (N * 2 + 3) ≡ N * N * 36 + N * 12 + 3
step = ℕ.solve-∀
m : ℕ
m = N * 6
n : ℕ
n = N * 6
mv : Moves
mv = seq m n ε
open MoveCounts (count mv) public using (c#; t#; r#)
module Proofs
(kₐ kₜ : ℕ)
(hyp : ∀ mv t
→ moves mv ε ≡ just t
→ ∃ λ leftover → RMoves.rmoves kₐ kₜ mv rempty ≡ just (leftover ⨮ t))
where
Thm = q * (kₐ + kₜ) + p ≥ q * 4
open RMoves kₐ kₜ
hmv : ∃ λ leftover → rmoves mv rempty ≡ just (leftover ⨮ ε)
hmv = hyp mv ε (thm-seq m n)
lem : c# * kₐ + t# * kₜ ≥ r#
lem with hmv
... | leftover , run =
begin
r#
≤⟨ m≤m+n r# leftover ⟩
r# + leftover
≤⟨ thm-counts mv 0 ε run ⟩
c# * kₐ + (t# * kₜ + 0)
≡⟨ cong (c# * kₐ +_) (+-identityʳ (t# * kₜ)) ⟩
c# * kₐ + t# * kₜ
∎
lem' : (N * 6 * (N * 6 + 2) + N * 6 + 3) * kₐ + (N * 6 * (N * 6 + 2) + N * 6 + 3) * kₜ
≥ N * 6 * (4 * (N * 6) + 3) + 3 * (N * 6) + 2
lem' =
begin
N * 6 * (4 * (N * 6) + 3) + 3 * (N * 6) + 2
≡⟨ sym (cong MoveCounts.r# (thm-counts-seq m n)) ⟩
r#
≤⟨ lem ⟩
c# * kₐ + t# * kₜ
≡⟨ cong (λ x → x * kₐ + t# * kₜ) (cong MoveCounts.c# (thm-counts-seq m n)) ⟩
(N * 6 * (N * 6 + 2) + N * 6 + 3) * kₐ + t# * kₜ
≡⟨ cong (λ x → (N * 6 * (N * 6 + 2) + N * 6 + 3) * kₐ + x * kₜ)
(cong MoveCounts.t# (thm-counts-seq m n)) ⟩
(N * 6 * (N * 6 + 2) + N * 6 + 3) * kₐ + (N * 6 * (N * 6 + 2) + N * 6 + 3) * kₜ
∎
thm : Thm
thm = *-cancelˡ-≤ (N * 6 * (N * 6 + 2) + N * 6 + 3) {{nz}}
(begin
(N * 6 * (N * 6 + 2) + N * 6 + 3) * (q * 4)
≤⟨ m≤m+n ((N * 6 * (N * 6 + 2) + N * 6 + 3) * (q * 4)) (N * 6 * p) ⟩
(N * 6 * (N * 6 + 2) + N * 6 + 3) * (q * 4) + N * 6 * p
≡⟨ step₁ N ⟩
(N * 6 * (4 * (N * 6) + 3) + 3 * (N * 6) + 2) * q
+ (N * 6 * (N * 6 + 2) + N * 6 + 3) * p
≤⟨ +-monoˡ-≤ ((N * 6 * (N * 6 + 2) + N * 6 + 3) * p) (*-monoˡ-≤ q lem') ⟩
((N * 6 * (N * 6 + 2) + N * 6 + 3) * kₐ + (N * 6 * (N * 6 + 2) + N * 6 + 3) * kₜ) * q
+ (N * 6 * (N * 6 + 2) + N * 6 + 3) * p
≡⟨ step₂ N kₐ kₜ ⟩
(N * 6 * (N * 6 + 2) + N * 6 + 3) * (q * (kₐ + kₜ) + p)
∎)
where
open ≤-Reasoning
step₁ : ∀ N →
(N * 6 * (N * 6 + 2) + N * 6 + 3) * ((N * N * 36 + N * 12 + 3) * 4) + N * 6 * (N * 36 + 10)
≡ (N * 6 * (4 * (N * 6) + 3) + 3 * (N * 6) + 2) * (N * N * 36 + N * 12 + 3)
+ (N * 6 * (N * 6 + 2) + N * 6 + 3) * (N * 36 + 10)
step₁ = ℕ.solve-∀
step₂ : ∀ N kₐ kₜ →
((N * 6 * (N * 6 + 2) + N * 6 + 3) * kₐ + (N * 6 * (N * 6 + 2) + N * 6 + 3) * kₜ)
* (N * N * 36 + N * 12 + 3)
+ (N * 6 * (N * 6 + 2) + N * 6 + 3) * (N * 36 + 10)
≡ (N * 6 * (N * 6 + 2) + N * 6 + 3) * ((N * N * 36 + N * 12 + 3) * (kₐ + kₜ) + (N * 36 + 10))
step₂ = ℕ.solve-∀
nz : NonZero (N * 6 * (N * 6 + 2) + N * 6 + 3)
nz = subst NonZero (sym (+-suc (N * 6 * (N * 6 + 2) + N * 6) 2)) _