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)).

(* if f is a complete coloring of g, then if there is a vertex whose neighborhood is not 2-colorable or the coloring is not complete then f cannot be a 3-coloring *)
Lemma nbd_not_2_col_graph_not_3_col : forall (g : graph) (f : coloring) (p : colors),
coloring_complete p g f ->
(exists (v : M.key) (ci : node),
M.find v f = Some ci /\
(~ two_coloring (restrict_on_nbd f g v) (S.remove ci p))) ->
~ three_coloring f p.