{-# OPTIONS --postfix-projections #-}
module BreadthFirst where
open import Prelude
record Stream (i : Size) (A : Set) : Set where
coinductive; constructor cons
field head : ∀{j : Size< i} → A
tail : ∀{j : Size< i} → Stream j A
open Stream
record Tree (i : Size) (A : Set) : Set where
coinductive
field label : ∀{j : Size< i} → A
left : ∀{j : Size< i} → Tree j A
right : ∀{j : Size< i} → Tree j A
open Tree
SS : (i : Size) (A : Set) → Set
SS i A = Stream i (Stream ∞ A)
record Result (i : Size) (A : Set) : Set where
field tree : Tree i A
rest : SS i A
open Result
fixR : ∀{i A} → (∀{j} → Result j A → Result (↑ j) A) → Result i A
fixR f .tree .label {j} = f (fixR {j} f) .tree .label
fixR f .tree .left {j} = f (fixR {j} f) .tree .left
fixR f .tree .right {j} = f (fixR {j} f) .tree .right
fixR f .rest .head {j} = f (fixR {j} f) .rest .head
fixR f .rest .tail {j} = f (fixR {j} f) .rest .tail
bfs : ∀{i A} → SS i A → Result i A
bfs ss .tree .label = ss .head .head
bfs ss .tree .left = bfs (ss .tail) .tree
bfs ss .tree .right = bfs (bfs (ss .tail) .rest) .tree
bfs ss .rest .head = ss .head. tail
bfs ss .rest .tail = bfs (bfs (ss .tail) .rest) .rest
bfp : ∀{i A} → Stream ∞ A → Result i A
bfp vs = fixR λ r → bfs (cons vs (r .rest))
bf : ∀{i A} → Stream ∞ A → Tree i A
bf vs = bfp vs .tree