Martin Escardo, Paulo Oliva, 2-27 July 2021
Example: Tic-tac-toe. We have two versions. The other version is in
another file.
\begin{code}
{-# OPTIONS --safe --without-K --no-exact-split #-}
module Games.TicTacToe2 where
open import MLTT.Spartan hiding (J)
open import MLTT.Fin
data π : Type where
O-wins draw X-wins : π
open import Games.Constructor π
open import Games.FiniteHistoryDependent π
open import Games.TypeTrees
open import Games.J
open import MLTT.Athenian
open list-util
tic-tac-toeβJ : GameJ
tic-tac-toeβJ = build-GameJ draw Board transition 9 boardβ
where
flip : π β π
flip O-wins = X-wins
flip draw = draw
flip X-wins = O-wins
data Player : Type where
O X : Player
Cell = Fin 9
record Board : Type where
pattern
constructor board
field
next-player : Player
available-moves : List Cell
X-moves : List Cell
O-moves : List Cell
open Board
opponent-wins : Player β π
opponent-wins X = O-wins
opponent-wins O = X-wins
winning : List Cell β Bool
winning = some-contained ((π β· π β· π β· [])
β· (π β· π β· π β· [])
β· (π β· π β· π β· [])
β· (π β· π β· π β· [])
β· (π β· π β· π β· [])
β· (π β· π β· π β· [])
β· (π β· π β· π β· [])
β· (π β· π β· π β· [])
β· [])
wins : Board β Bool
wins (board O _ _ os) = winning os
wins (board X _ xs _) = winning xs
boardβ : Board
boardβ = board X (list-Fin 9) [] []
Move : List Cell β Type
Move xs = Ξ£ c κ Cell , ((c is-in xs) οΌ true)
\end{code}
The following definition of argmax is somewhat convoluted because it
is optimized for time, by minimizing the number of evaluations of the
predicate q:
\begin{code}
argmax : (m : Cell) (ms : List Cell) β π β (Move (m β· ms) β π) β Move (m β· ms)
argmax m ms X-wins q = m , need m == m || (m is-in ms) οΌ true
which-is-given-by ||-left-intro _ (==-refl m)
argmax m [] r q = m , need m == m || (m is-in []) οΌ true
which-is-given-by ||-left-intro _ (==-refl m)
argmax m (x β· xs) O-wins q = ΞΉ Ξ³
where
ΞΉ : Move (x β· xs) β Move (m β· x β· xs)
ΞΉ (c , e) = c , need c == m || (c is-in (x β· xs)) οΌ true
which-is-given-by ||-right-intro {c == m} _ e
q' : Move (x β· xs) β π
q' m = q (ΞΉ m)
a : (x == m) || ((x == x) || (x is-in xs)) οΌ true
a = ||-right-intro {x == m} _ (||-left-intro _ (==-refl x))
Ξ³ : Move (x β· xs)
Ξ³ = argmax x xs (q (x , a)) q'
argmax m us@(x β· ms) draw q = g us c
where
c : ((x == x) || (x is-in ms)) && (ms contained-in (x β· ms)) οΌ true
c = &&-intro (||-left-intro _ (==-refl x)) (contained-lemmaβ x ms)
g : (vs : List Cell) β vs contained-in us οΌ true β Move (m β· us)
g [] c = m , need m == m || (m is-in (x β· ms)) οΌ true
which-is-given-by ||-left-intro _ (==-refl m)
g (y β· vs) c = k (q (y , a))
where
a : (y == m) || ((y == x) || (y is-in ms)) οΌ true
a = ||-right-intro {y == m} _ (prβ (&&-gives-Γ c))
b : (vs contained-in (x β· ms)) οΌ true
b = prβ (&&-gives-Γ c)
k : π β Move (m β· us)
k X-wins = y , a
k r = g vs b
open J-definitions π
argmin : (m : Cell) (ms : List Cell) β π β (Move (m β· ms) β π) β Move (m β· ms)
argmin m ms r q = argmax m ms (flip r) (Ξ» xs β flip (q xs))
arg : Player β (ms : List Cell) β empty ms οΌ false β J (Move ms)
arg _ [] e q = π-elim (true-is-not-false e)
arg X (m β· ms) e q = argmax m ms (q (m , ||-left-intro (m is-in ms) (==-refl m))) q
arg O (m β· ms) e q = argmin m ms (q (m , ||-left-intro (m is-in ms) (==-refl m))) q
play : (b : Board) β Move (available-moves b) β Board
play (board X as xs os) (c , e) = board O (remove c as) (insert c xs) os
play (board O as xs os) (c , e) = board X (remove c as) xs (insert c os)
transition : Board β π + (Ξ£ M κ Type , (M β Board) Γ J M)
transition b@(board next as xs os) =
if wins b
then inl (opponent-wins next)
else Bool-equality-cases (empty as)
(Ξ» (_ : empty as οΌ true) β inl draw)
(Ξ» (e : empty as οΌ false) β inr (Move as , play b , arg next as e))
tic-tac-toeβ : Game
tic-tac-toeβ = Game-from-GameJ tic-tac-toeβJ
tβ : π
tβ = optimal-outcome tic-tac-toeβ
sβ : Path (Xt tic-tac-toeβ)
sβ = strategic-path (selection-strategy (selections tic-tac-toeβJ) (q tic-tac-toeβ))
uβ : Path (Xt tic-tac-toeβ)
uβ = sequenceα΄Ά (selections tic-tac-toeβJ) (q tic-tac-toeβ)
lβ : β
lβ = plength sβ
\end{code}