\begin{code}
{-# OPTIONS --safe #-}
module Data.Tree where
open import Prelude
\end{code}
%<*tree-def>
\begin{code}
data Tree : Type where
♢ ♠ : Tree
_⊛_ : Tree → Tree → Tree
\end{code}
%</tree-def>
\begin{code}
module TreeEq where
_≡ᴮ_ : Tree → Tree → Bool
♢ ≡ᴮ ♢ = true
♠ ≡ᴮ ♠ = true
(xˡ ⊛ xʳ) ≡ᴮ (yˡ ⊛ yʳ) = (xˡ ≡ᴮ yˡ) && (xʳ ≡ᴮ yʳ)
_ ≡ᴮ _ = false
&&-× : {x y : Bool} → T (x && y) → T x × T y
&&-× {true} {true} _ = tt , tt
sound : ∀ x y → T (x ≡ᴮ y) → x ≡ y
sound ♢ ♢ p = refl
sound ♠ ♠ p = refl
sound (xˡ ⊛ xʳ) (yˡ ⊛ yʳ) p = let l , r = &&-× p in cong₂ _⊛_ (sound xˡ yˡ l) (sound xʳ yʳ r)
×-&& : {x y : Bool} → T x → T y → T (x && y)
×-&& {true} {true} _ _ = tt
complete : ∀ x → T (x ≡ᴮ x)
complete ♢ = tt
complete ♠ = tt
complete (x ⊛ y) = ×-&& (complete x) (complete y)
tree-eq : Discrete Tree
tree-eq = from-bool-eq record { TreeEq }
left : Tree → Maybe Tree
left (x ⊛ _) = just x
left _ = nothing
right : Tree → Maybe Tree
right (_ ⊛ x) = just x
right _ = nothing
\end{code}