Library zoo.common.treemap

Require Import stdpp.gmap.

Require Import zoo.prelude.
Require Import zoo.options.

Section treemap۰rooted.
  Context {N} `{Countable N} {E : Type}.

  Implicit Type node root src dst : N.
  Implicit Type edge : E.
  Implicit Type path : list E.
  Implicit Type ϵ : N × E.
  Implicit Type tree : gmap N (N × E).

  Inductive treemap۰path tree dst : N list E Prop :=
    | treemap۰pathnil :
        treemap۰path tree dst dst []
    | treemap۰pathcons {node1} ϵ node2 edge path :
        tree !! node1 = Some ϵ
        ϵ.1 = node2
        ϵ.2 = edge
        treemap۰path tree dst node2 path
        treemap۰path tree dst node1 (edge :: path).
  #[local] Hint Constructors treemap۰path : core.

  Definition treemap۰rooted tree root :=
    tree !! root = None
       node,
      is_Some (tree !! node)
         path,
        treemap۰path tree root node path.

  Definition treemap۰reroot tree root root' edge :=
    <[root := (root', edge)]> (delete root' tree).

  Lemma treemap۰pathapp tree dst1 node path1 dst2 path2 :
    treemap۰path tree dst1 node path1
    treemap۰path tree dst2 dst1 path2
    treemap۰path tree dst2 node (path1 ++ path2).
  Lemma treemap۰pathsnoc {tree dst1 node path} ϵ dst2 edge :
    treemap۰path tree dst1 node path
    tree !! dst1 = Some ϵ
    ϵ.1 = dst2
    ϵ.2 = edge
    treemap۰path tree dst2 node (path ++ [edge]).

  Lemma treemap۰pathnilinv tree dst node :
    treemap۰path tree dst node []
    node = dst.
  Lemma treemap۰pathconsinv tree dst node edge path :
    treemap۰path tree dst node (edge :: path)
       node',
      tree !! node = Some (node', edge)
      treemap۰path tree dst node' path.
  Lemma treemap۰pathappinv tree dst node path1 path2 :
    treemap۰path tree dst node (path1 ++ path2)
       node',
      treemap۰path tree node' node path1
      treemap۰path tree dst node' path2.

  Lemma treemap۰pathmono {tree dst node path} tree' :
    tree ##ₘ tree'
    treemap۰path tree dst node path
    treemap۰path (tree tree') dst node path.

  Lemma treemap۰rootedempty root :
    treemap۰rooted root.

  Lemma treemap۰rootedroot tree root :
    treemap۰rooted tree root
    tree !! root = None.

  Lemma treemap۰pathis_nil tree root path :
    treemap۰rooted tree root
    treemap۰path tree root root path
    path = [].
  Lemma treemap۰pathis_cons tree root node path :
    treemap۰rooted tree root
    treemap۰path tree root node path
    node root
       node' edge path',
      path = edge :: path'
      tree !! node = Some (node', edge)
      treemap۰path tree root node' path'.

  #[local] Lemma treemap۰pathacyclic {tree root path} node ϵ node' :
    treemap۰rooted tree root
    treemap۰path tree root node path
    tree !! node = Some ϵ
    ϵ.1 = node'
    node node'.
  Lemma treemap۰rootedacyclic {tree root} node ϵ node' :
    treemap۰rooted tree root
    tree !! node = Some ϵ
    ϵ.1 = node'
    node node'.

  Lemma treemap۰rootedpath {tree root} node :
    treemap۰rooted tree root
    is_Some (tree !! node)
       path,
      treemap۰path tree root node path.

  Lemma treemap۰rootedlift {tree root} root' edge :
    treemap۰rooted tree root
    tree !! root' = None
    root root'
    treemap۰rooted (<[root := (root', edge)]> tree) root'.

  Lemma treemaprerootpath {tree root} root' ϵ edge dst node path :
    treemap۰rooted tree root
    tree !! root' = Some ϵ
    ϵ.1 = root
    dst root
    treemap۰path tree dst node path
    treemap۰path (treemap۰reroot tree root root' edge) dst node path.
  Lemma treemaprerootpath' {tree root} root' ϵ edge node path :
    treemap۰rooted tree root
    tree !! root' = Some ϵ
    ϵ.1 = root
    treemap۰path tree root' node path
    treemap۰path (treemap۰reroot tree root root' edge) root' node path.
  Lemma treemaprerootrooted {tree root} root' ϵ edge :
    treemap۰rooted tree root
    tree !! root' = Some ϵ
    ϵ.1 = root
    treemap۰rooted (treemap۰reroot tree root root' edge) root'.
End treemap۰rooted.

#[global] Opaque treemap۰rooted.