Local Open Scope positive_scope.
(** * Properties of coloring maps *)
(** ** Definition of a set of colors *)
Definition colors := S.t.
(** ** A coloring is complete if every vertex is colored *)
Definition coloring_complete (palette: colors) (g: graph) (f: coloring) :=
(forall i, M.In i g -> M.In i f) /\ coloring_ok palette g f.
Example ex_graph :=
mk_graph [ (6,4); (4,5); (4,3); (3,2); (5,2); (1,2); (1,5) ]%positive.
Definition two_colors: colors := SP.of_list [1; 2]%positive.
Definition three_colors: colors := SP.of_list [1; 2; 3]%positive.
Local Open Scope positive_scope.
(* Example of 3-coloring the example graph and proof with ok_coloring *)
Example ex_coloring :=
fold_right (fun p m => M.add (fst p) (snd p) m) (@M.empty _) [(6,1);(3,1);(5,1);(4,2);(2,2);(1,3)].
(* Proving that an explicit graph coloring is a valid coloring *)
Example ex_coloring_good : coloring_ok three_colors ex_graph ex_coloring.
(** ** Definition of $n$-coloring *)
Definition n_coloring (f : coloring) (p : colors) (n : nat) :=
S.cardinal p = n /\ forall v c, M.find v f = Some c -> S.In c p.
(** ** Definition of 3-coloring *)
Definition three_coloring (f : coloring) p := n_coloring f p 3.
(** ** Definition of 2-coloring *)
Definition two_coloring (f : coloring) p := n_coloring f p 2.
(** ** $(n+1)$-coloring not using a color is $n$-coloring *)
(** Let: - [f] be a coloring - [p] be palette of colors of size [n] - [c] be a color in [p]  Assume that [f] is a $(n+1)$-coloring wrt. [p], [c] is in [p], and [c] is unused by [f]. Then [f] is a $n$-coloring wrt. [c\{p}]. *)
(** ** Restriction to 3-coloring to 2-coloring *)
(** ** Restricting a coloring on the neighborhood of a node *)
Definition restrict_on_nbd (f : coloring) (g : graph) (v : node) :=
restrict f (nodes (neighborhood g v)).
(** * Constant coloring of a vertex set [s] with [c] *)
Definition constant_color {A} (s : nodeset) c := S.fold (fun v => M.add v c) s (@M.empty A).
(** * 2-color step *)
(** Let [g] be a graph, [v] be a vertex, $c_1$ and $c_2$ the colors we have that this function colors [v] with $c_1$ and colors its neighbors with $c_2$. *)
Definition two_color_step (g : graph) (v : node) c1 c2 (f : coloring) : coloring :=
M.add v c1 (constant_color (adj g v) c2).

(** ** Correctness of 2-color step *)
Lemma two_color_step_correct : forall (g : graph) (v : node) c1 c2,
c1 <> c2 ->
no_selfloop g ->
undirected g ->
M.In v g ->
(exists m, two_coloring m (SP.of_list [c1;c2]) /\ coloring_complete (SP.of_list [c1;c2]) g m) ->
coloring_ok (SP.of_list [c1;c2]) g (two_color_step g v c1 c2 (@M.empty _)).