{-# OPTIONS --safe #-}
module MultiTreeGame where
open import Library
open import Tree using (Tree; ε; _∙_; Resourced; _⨮_; module Potential)
open ℕ
open Potential
ForestSize = ℕ
Forest = Vec Tree
Φs : Forest n → ℕ
Φs [] = 0
Φs (t ∷ ts) = Φ t + Φs ts
ε^_ : (n : ℕ) → Forest n
ε^ n = replicate n ε
Φ-init : ∀ n → Φs (ε^ n) ≡ 0
Φ-init (zero) = refl
Φ-init (suc n) = Φ-init n
Φ-initial : ∀ n → Φs (ε^ n) ≤ 0
Φ-initial n rewrite Φ-init n = z≤n
pick : Fin n → Forest n → ∃ λ m → n ≡ suc m × Tree × Forest m
pick zero (t ∷ ts) = _ , refl , t , ts
pick (suc i) (t' ∷ ts) with pick i ts
... | _ , refl , t , ts' = _ , refl , t , (t' ∷ ts')
unit : Forest m → Forest (1 + m)
unit ts = ε ∷ ts
concat : (i : Fin (1 + m)) (j : Fin m) → Forest (1 + m) → Forest m
concat i j ts₀ with pick i ts₀
... | _ , refl , t₁ , ts₁ with pick j ts₁
... | _ , refl , t₂ , ts₂ = (t₁ ∙ t₂) ∷ ts₂
rotate : (i : Fin m) → Forest m → Maybe (Forest m)
rotate i ts with pick i ts
... | _ , refl , t₁ , ts₁ with Tree.rotate t₁
... | nothing = nothing
... | just t₂ = just (t₂ ∷ ts₁)
tail : (i : Fin m) → Forest m → Maybe (Forest m)
tail i ts with pick i ts
... | _ , refl , t₁ , ts₁ with Tree.tail t₁
... | nothing = nothing
... | just t₂ = just (t₂ ∷ ts₁)
data Moves : (m n : ForestSize) → Set where
U : Moves m (1 + m)
C : (i : Fin (1 + m)) (j : Fin m) → Moves (1 + m) m
R : (i : Fin m) → Moves m m
T : (i : Fin m) → Moves m m
ε : Moves m m
_∙_ : (mv₁ : Moves l m) (mv₂ : Moves m n) → Moves l n
run : Moves m n → Forest m → Maybe (Forest n)
run U = just ∘ unit
run (C i j) = just ∘ concat i j
run (R i) = rotate i
run (T i) = tail i
run ε = just
run (mv₁ ∙ mv₂) = run mv₁ >=> run mv₂
RF : ForestSize → Set
RF n = Resourced (Forest n)
rempty : RF 0
rempty = 0 ⨮ []
module RMoves (kₐ kₜ : ℕ) where
rmoves : Moves m n → RF m → Maybe (RF n)
rmoves U (k ⨮ ts) = just (k ⨮ ε ∷ ts)
rmoves (C i j) (k ⨮ ts) = just (kₐ + k ⨮ concat i j ts)
rmoves (T i) (k ⨮ ts) = Maybe.map (kₜ + k ⨮_) (tail i ts)
rmoves (R i) (suc k ⨮ ts) = Maybe.map (k ⨮_) (rotate i ts)
rmoves (R _) (zero ⨮ ts) = nothing
rmoves ε = just
rmoves (m ∙ m') = rmoves m >=> rmoves m'