(* Predicate that takes a vertex with high degree (> K) *)
Definition high_deg (K: nat) (n: node) (adj: nodeset) : bool := K <? S.cardinal adj.
Definition injective {A B} (f : A -> B) := forall x y, f x = f y -> x = y.
Local Open Scope positive_scope.
(* Wigderson's algorithm definition  let G be a graph, |G.v| = k a vertex v is high-degree if deg(v) > k^2 phase1 is selecting the high-degree vertices and coloring their neighborhoods phase2 is coloring the remaining nodes with at most sqrt(k) colors *)
Function selectW (K: nat) (g: graph) {measure M.cardinal g} : list node :=
match S.choose (subset_nodes (high_deg K) g) with
| Some n => n :: selectW K (remove_node n g)
| None => nil
end.
(* Phase 1 of Wigderson *)
(* Let: - k: bound for degree of vertices - c: color currently used - g: graph - f: coloring - H: proof that g is 3-colorable - H1: proof that f is a complete coloring of g - Hf: proof that f is a 3-coloring  phase1(g,c): if a high degree vertex in g exists: v := select a high-degree vertex in g nbhd := neighborhood of v in g coloring_of_nbhd := 2-coloring of nbhd using c+1 and c+2 g' := remove nbhd from g return union(coloring_of_nbhd, phase1(g',c+2)) else: return empty coloring  *)
(* Two-coloring of neighborhood *)
Definition two_color_nbd (g : graph) (v : node) (c1 c2 : positive) : option coloring.
Admitted.
Program Fixpoint phase1
(* The criterion for high-degree vertices *)
(k : nat)
(* Current color count *)
(c : positive)
(g : graph) {measure (M.cardinal g)} : option coloring :=
(* Choose a high-degree vertex *)
match S.choose (subset_nodes (high_deg k) g) with
| Some v =>
let nbhd := neighborhood g v in
(* i is the map that turns the coloring using colors 1,2 into c+1, c+2 *)
let coloring_of_nbhd := two_color_nbd g c (c+1) v in
let g' := remove_nodes g (nodes nbhd) in
(* color the high-degree vertex 1 each time *)
match coloring_of_nbhd with
| None => None
| Some m' => option_map (Munion (M.add v 1 m')) (phase1 k (c+2) g')
end
| None => Some (@M.empty _)
end.
Next Obligation.
Admitted.
Functional Scheme phase1_ind := Induction for phase1 Sort Prop.
(* things we want to prove: - let d be the number of iterations - prove that the resulting color uses 2d+1 colors - induction on size of graph - two new colors each time - base case: no more high degree vertices, color with phase2 - there are no more high-degree nodes (this is the hypothesis for phase2) - need to identify the terminal properties for phase1 to supply to phase2 *)
(* induction on M.cardinal g *)
Check phase1.
(* Lemmas: - you can color any graph with max degree + 1 colors - can prove 3*(sqrt n) + 1 *)
(* Some notes about how the algorithm will be written:  - we will not pass proofs that the graph is 3-colorable all the time, since later we want to talk about robustness  - we want to break down algorithm enough to reason about the graph and the coloring at each step while still making the overall algorithm clear  - an important lemma we will use repeatedly is that we can combine OK disjoint colorings into larger colorings, and that the number of colors used is the size of the palette  - to show that the coloring is complete, we show that a vertex must be one of the following:  1) a high-degree vertex, in which case it's colored by phase 1 2) a neighbor of a high-degree vertex, in which case it's colored by phase 1 3) a low-degree vertex, in which case it's colored by phase 2 *)
(* We define phase 1 of the algorithm in several pieces:  two_color_step takes: - a graph g - a high-degree vertex v - the current color number c two_color_step outputs: - a complete coloring of N(v) using colors c+1, c+2 note: - phase 1 will color v with c - the expectation is that two_color_step will be called with another vertex and c+2  so phase 1 will fold over the list of high-degree vertices Lv and do: - the state of the fold will be (c,m), where c is a number and m is the coloring - call two_color_step on each vertex to produce the coloring and update m - update c to c+2  we will have to show that:  - the resulting tuple will be (d,m), where d is the number of high-degree vertices and m is the coloring of all the neighborhoods of high-degree vertices - d*d <= k - the number of colors used is 2*d  random lemmas that we have to show: - it's decidable to check whether a node is colored or not (WF.In_Dec) - the number of high-degree vertices cannot exceed sqrt(k) *)

(* Lifting two color maps with any injective function *)
Lemma two_color_up_inj f g (inj : S.elt -> S.elt) :
injective inj ->
undirected g ->
coloring_ok two_colors g f ->
{h | coloring_ok (fold_right S.add S.empty [inj 1;inj 2]) g h}.