Theory BFS

theory BFS
imports BNF_Corec Stream Simps_Case_Conv
theory BFS imports
  "../../BNF_Corec"
  "~~/src/HOL/Library/Stream"
  "~~/src/HOL/Library/Simps_Case_Conv"
begin

codatatype 'a tree = Node (root: 'a) (left: "'a tree") (right: "'a tree")

corec (friend) bfs2 :: "'a stream stream ⇒ 'a stream stream"
where "bfs2 labels = (case labels of (x ## xs) ## xss ⇒ xs ## bfs2 (bfs2 xss))"

corec bfs_tree :: "'a stream stream ⇒ 'a tree"
where
  "bfs_tree labels = (case labels of (x ## xs) ## xss ⇒ Node x (bfs_tree xss) (bfs_tree (bfs2 xss)))"

definition bfs :: "'a stream stream ⇒ 'a tree × 'a stream stream"
where "bfs labels = (bfs_tree labels, bfs2 labels)"

corec levels :: "'a stream ⇒ 'a stream stream"
where "levels xs = bfs2 (xs ## levels xs)"

definition bf :: "'a stream ⇒ 'a tree"
where "bf xs = bfs_tree (xs ## levels xs)"

simps_of_case bfs2_simps [simp]: bfs2.code
simps_of_case bfs_tree_simps [simp]: bfs_tree.code

lemma bfs_simps:
  "bfs ((x ## xs) ## xss) = (let (l, xss') = bfs xss; (r, xss'') = bfs xss' in (Node x l r, xs ## xss''))"
by(simp add: bfs_def)

lemma bfs2_sel [simp]:
  "shd (bfs2 xss) = stl (shd xss)"
  "stl (bfs2 xss) = bfs2 (bfs2 (stl xss))"
by(subst bfs2.code; simp split: stream.split; fail)+

lemma bfs_tree_sel [simp]:
  shows root_bfs_tree: "root (bfs_tree xss) = shd (shd xss)"
  and left_bfs_tree: "left (bfs_tree xss) = bfs_tree (stl xss)"
  and right_bfs_tree: "right (bfs_tree xss) = bfs_tree (bfs2 (stl xss))"
by(subst bfs_tree.code; simp split: stream.split; fail)+

lemma labels_sel [simp]:
  "shd (levels xs) = shd (bfs2 (xs ## levels xs))"
  "stl (levels xs) = stl (bfs2 (xs ## levels xs))"
by(subst levels.code; simp; fail)+

end