Graphs
Require Export Rel.
Fixpoint sum (ns : list nat) : nat :=
match ns with
| [] ⇒ 0
| n::ns ⇒ n + sum ns
end.
Fixpoint sum_map {X : Type} (f : X → nat) (xs : list X) : nat :=
match xs with
| [] ⇒ 0
| x::xs ⇒ f x + sum_map f xs
end.
Fixpoint remove_first {X : Type} (eq_dec : ∀ (x y : X), {x=y} + {x≠y}) (y:X) (xs : list X) : list X :=
match xs with
| [] ⇒ []
| (x::xs) ⇒ if eq_dec y x then xs else x::remove_first eq_dec y xs
end.
Inductive setlike {X:Type} : list X → Prop :=
| setlike_nil : setlike []
| setlike_cons : ∀ (v:X) (vs:list X),
setlike vs → ¬In v vs → setlike (v::vs).
Module ExplicitType.
(* adapted from https://coq.inria.fr/V8.2pl1/contribs/GraphBasics.html *)
Parameter X : Type.
Axiom eq_dec_V : ∀ (x y : X), {x = y} + {x ≠ y}.
Lemma eq_dec_E : ∀ (e1 e2 : X * X), {e1 = e2} + {e1 ≠ e2}.
Proof.
intros.
destruct e1 as [src1 tgt1]. destruct e2 as [src2 tgt2].
destruct (eq_dec_V src1 src2) as [Heqsrc | Hneqsrc];
destruct (eq_dec_V tgt1 tgt2) as [Heqtgt | Hneqtgt].
- left. rewrite Heqsrc. rewrite Heqtgt. reflexivity.
- right. intros Hcontra. inversion Hcontra. contradiction.
- right. intros Hcontra. inversion Hcontra. contradiction.
- right. intros Hcontra. inversion Hcontra. contradiction.
Qed.
Inductive graph : list X → list (X * X) → Type :=
| g_empty : graph [] []
| g_vertex :
∀ (V : list X) (E : list (X * X)) (g : graph V E) (v : X),
¬ In v V → graph (v::V) E
| g_arc :
∀ (V : list X) (E : list (X * X)) (g : graph V E) (src tgt : X),
In src V →
In tgt V →
¬ In (src,tgt) E → graph V ((src,tgt)::E).
Lemma vertex_setlike : ∀ {V : list X} {E : list (X * X)} (g:graph V E), setlike V.
Proof.
(* FILL IN HERE *) Admitted.
Fixpoint in_degree {V : list X} {E : list (X * X)} (v:X) (g:graph V E) : nat :=
match g with
| g_empty ⇒ 0
| g_vertex V' E' g' _ _ ⇒ in_degree v g'
| g_arc V' E' g' _ tgt _ _ _ ⇒
if eq_dec_V v tgt
then 1 + in_degree v g'
else in_degree v g'
end.
Fixpoint out_degree {V : list X} {E : list (X * X)} (v:X) (g:graph V E) : nat (* REPLACE THIS LINE WITH ":= _your_definition_ ." *). Admitted.
Definition degree {V : list X} {E : list (X * X)} (v:X) (g:graph V E) : nat :=
in_degree v g + out_degree v g.
Fixpoint sum_vertex_degree {V : list X} {E : list (X * X)} (g:graph V E) : nat :=
match g with
| g_empty ⇒ 0
| g_vertex V' E' g' _ _ ⇒ sum_vertex_degree g'
| g_arc V' E' g' _ _ _ _ _ ⇒ 2 + sum_vertex_degree g'
end.
Lemma not_in__degree_O :
∀ {V : list X} {E : list (X * X)} (v:X) (g:graph V E),
¬In v V → degree v g = 0.
Proof.
(* FILL IN HERE *) Admitted.
Lemma sum_vertex_degree__sum_map_degree :
∀ {V : list X} {E : list (X * X)} (g:graph V E),
sum_vertex_degree g = sum_map (fun v ⇒ in_degree v g) V + sum_map (fun v ⇒ out_degree v g) V.
Proof.
(* FILL IN HERE *) Admitted.
Fixpoint num_edges {V : list X} {E : list (X * X)} (g:graph V E) : nat :=
match g with
| g_empty ⇒ 0
| g_vertex V' E' g' _ _ ⇒ num_edges g'
| g_arc V' E' g' _ _ _ _ _ ⇒ 1 + num_edges g'
end.
Lemma num_edges__length : ∀ {V : list X} {E : list (X * X)} (g:graph V E),
num_edges g = length E.
Proof.
(* FILL IN HERE *) Admitted.
Lemma inductive_handshake : ∀ {V : list X} {E : list (X * X)} (g:graph V E),
sum_vertex_degree g = 2 * num_edges g.
Proof.
(* FILL IN HERE *) Admitted.
Lemma euler_handshake : ∀ {V : list X} {E : list (X * X)} (g:graph V E),
sum (map (fun v ⇒ degree v g) V) = 2 * length E.
Proof.
(* FILL IN HERE *) Admitted.
End ExplicitType.