[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
ht : IsTrail p
x : V
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ u ≠ v → x ≠ u ∧ x ≠ v
[PROOFSTEP]
induction' p with u u v w huv p ih
[GOAL]
case nil
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v : V
p : Walk G u✝ v
ht✝ : IsTrail p
x u : V
ht : IsTrail Walk.nil
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges Walk.nil)) ↔ u ≠ u → x ≠ u ∧ x ≠ u
[PROOFSTEP]
simp
[GOAL]
case cons
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ih : IsTrail p → (Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ v ≠ w → x ≠ v ∧ x ≠ w)
ht : IsTrail (cons huv p)
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges (cons huv p))) ↔ u ≠ w → x ≠ u ∧ x ≠ w
[PROOFSTEP]
rw [cons_isTrail_iff] at ht
[GOAL]
case cons
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ih : IsTrail p → (Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ v ≠ w → x ≠ v ∧ x ≠ w)
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges (cons huv p))) ↔ u ≠ w → x ≠ u ∧ x ≠ w
[PROOFSTEP]
specialize ih ht.1
[GOAL]
case cons
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ v ≠ w → x ≠ v ∧ x ≠ w
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges (cons huv p))) ↔ u ≠ w → x ≠ u ∧ x ≠ w
[PROOFSTEP]
simp only [List.countp_cons, Ne.def, edges_cons, Sym2.mem_iff]
[GOAL]
case cons
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ v ≠ w → x ≠ v ∧ x ≠ w
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges p) + if decide (x = u ∨ x = v) = true then 1 else 0) ↔
    ¬u = w → ¬x = u ∧ ¬x = w
[PROOFSTEP]
split_ifs with h
[GOAL]
case pos
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ v ≠ w → x ≠ v ∧ x ≠ w
h : decide (x = u ∨ x = v) = true
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges p) + 1) ↔ ¬u = w → ¬x = u ∧ ¬x = w
[PROOFSTEP]
rw [decide_eq_true_eq] at h
[GOAL]
case pos
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ v ≠ w → x ≠ v ∧ x ≠ w
h : x = u ∨ x = v
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges p) + 1) ↔ ¬u = w → ¬x = u ∧ ¬x = w
[PROOFSTEP]
obtain (rfl | rfl) := h
[GOAL]
case pos.inl
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v✝ : V
p✝ : Walk G u v✝
ht✝ : IsTrail p✝
x v w : V
p : Walk G v w
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ v ≠ w → x ≠ v ∧ x ≠ w
huv : Adj G x v
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (x, v) ∈ edges p
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges p) + 1) ↔ ¬x = w → ¬x = x ∧ ¬x = w
[PROOFSTEP]
rw [Nat.even_add_one, ih]
[GOAL]
case pos.inl
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v✝ : V
p✝ : Walk G u v✝
ht✝ : IsTrail p✝
x v w : V
p : Walk G v w
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ v ≠ w → x ≠ v ∧ x ≠ w
huv : Adj G x v
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (x, v) ∈ edges p
⊢ ¬(v ≠ w → x ≠ v ∧ x ≠ w) ↔ ¬x = w → ¬x = x ∧ ¬x = w
[PROOFSTEP]
simp only [huv.ne, imp_false, Ne.def, not_false_iff, true_and_iff, not_forall, Classical.not_not, exists_prop,
  eq_self_iff_true, not_true, false_and_iff, and_iff_right_iff_imp]
[GOAL]
case pos.inl
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v✝ : V
p✝ : Walk G u v✝
ht✝ : IsTrail p✝
x v w : V
p : Walk G v w
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ v ≠ w → x ≠ v ∧ x ≠ w
huv : Adj G x v
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (x, v) ∈ edges p
⊢ x = w → ¬v = w
[PROOFSTEP]
rintro rfl rfl
[GOAL]
case pos.inl
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v✝ : V
p✝ : Walk G u v✝
ht✝ : IsTrail p✝
v : V
huv : Adj G v v
p : Walk G v v
ih : Even (List.countp (fun e => decide (v ∈ e)) (edges p)) ↔ v ≠ v → v ≠ v ∧ v ≠ v
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (v, v) ∈ edges p
⊢ False
[PROOFSTEP]
exact G.loopless _ huv
[GOAL]
case pos.inr
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v : V
p✝ : Walk G u✝ v
ht✝ : IsTrail p✝
x u w : V
huv : Adj G u x
p : Walk G x w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, x) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ x ≠ w → x ≠ x ∧ x ≠ w
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges p) + 1) ↔ ¬u = w → ¬x = u ∧ ¬x = w
[PROOFSTEP]
rw [Nat.even_add_one, ih, ← not_iff_not]
[GOAL]
case pos.inr
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v : V
p✝ : Walk G u✝ v
ht✝ : IsTrail p✝
x u w : V
huv : Adj G u x
p : Walk G x w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, x) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ x ≠ w → x ≠ x ∧ x ≠ w
⊢ ¬¬(x ≠ w → x ≠ x ∧ x ≠ w) ↔ ¬(¬u = w → ¬x = u ∧ ¬x = w)
[PROOFSTEP]
simp only [huv.ne.symm, Ne.def, eq_self_iff_true, not_true, false_and_iff, not_forall, not_false_iff, exists_prop,
  and_true_iff, Classical.not_not, true_and_iff, iff_and_self]
[GOAL]
case pos.inr
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v : V
p✝ : Walk G u✝ v
ht✝ : IsTrail p✝
x u w : V
huv : Adj G u x
p : Walk G x w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, x) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ x ≠ w → x ≠ x ∧ x ≠ w
⊢ x = w → ¬u = w
[PROOFSTEP]
rintro rfl
[GOAL]
case pos.inr
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v : V
p✝ : Walk G u✝ v
ht✝ : IsTrail p✝
x u : V
huv : Adj G u x
p : Walk G x x
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, x) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ x ≠ x → x ≠ x ∧ x ≠ x
⊢ ¬u = x
[PROOFSTEP]
exact huv.ne
[GOAL]
case neg
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ v ≠ w → x ≠ v ∧ x ≠ w
h : ¬decide (x = u ∨ x = v) = true
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges p) + 0) ↔ ¬u = w → ¬x = u ∧ ¬x = w
[PROOFSTEP]
rw [decide_eq_true_eq, not_or] at h
[GOAL]
case neg
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ v ≠ w → x ≠ v ∧ x ≠ w
h : ¬x = u ∧ ¬x = v
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges p) + 0) ↔ ¬u = w → ¬x = u ∧ ¬x = w
[PROOFSTEP]
simp only [h.1, h.2, not_false_iff, true_and_iff, add_zero, Ne.def] at ih ⊢
[GOAL]
case neg
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
h : ¬x = u ∧ ¬x = v
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ ¬v = w → ¬x = w
⊢ Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ ¬u = w → ¬x = w
[PROOFSTEP]
rw [ih]
[GOAL]
case neg
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
h : ¬x = u ∧ ¬x = v
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ ¬v = w → ¬x = w
⊢ ¬v = w → ¬x = w ↔ ¬u = w → ¬x = w
[PROOFSTEP]
constructor
[GOAL]
case neg.mp
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
h : ¬x = u ∧ ¬x = v
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ ¬v = w → ¬x = w
⊢ (¬v = w → ¬x = w) → ¬u = w → ¬x = w
[PROOFSTEP]
rintro h' h'' rfl
[GOAL]
case neg.mp
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v : V
huv : Adj G u v
h : ¬x = u ∧ ¬x = v
p : Walk G v x
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ ¬v = x → ¬x = x
h' : ¬v = x → ¬x = x
h'' : ¬u = x
⊢ False
[PROOFSTEP]
simp only [imp_false, eq_self_iff_true, not_true, Classical.not_not] at h'
[GOAL]
case neg.mp
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v : V
huv : Adj G u v
h : ¬x = u ∧ ¬x = v
p : Walk G v x
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ ¬v = x → ¬x = x
h'' : ¬u = x
h' : v = x
⊢ False
[PROOFSTEP]
cases h'
[GOAL]
case neg.mp.refl
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v : V
p✝ : Walk G u✝ v
ht✝ : IsTrail p✝
x u : V
h'' : ¬u = x
huv : Adj G u x
h : ¬x = u ∧ ¬x = x
p : Walk G x x
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, x) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ ¬x = x → ¬x = x
⊢ False
[PROOFSTEP]
simp only [not_true, and_false, false_and] at h
[GOAL]
case neg.mpr
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v w : V
huv : Adj G u v
p : Walk G v w
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
h : ¬x = u ∧ ¬x = v
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ ¬v = w → ¬x = w
⊢ (¬u = w → ¬x = w) → ¬v = w → ¬x = w
[PROOFSTEP]
rintro h' h'' rfl
[GOAL]
case neg.mpr
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v : V
huv : Adj G u v
h : ¬x = u ∧ ¬x = v
p : Walk G v x
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ ¬v = x → ¬x = x
h' : ¬u = x → ¬x = x
h'' : ¬v = x
⊢ False
[PROOFSTEP]
simp only [imp_false, eq_self_iff_true, not_true, Classical.not_not] at h'
[GOAL]
case neg.mpr
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u✝ v✝ : V
p✝ : Walk G u✝ v✝
ht✝ : IsTrail p✝
x u v : V
huv : Adj G u v
h : ¬x = u ∧ ¬x = v
p : Walk G v x
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (u, v) ∈ edges p
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ ¬v = x → ¬x = x
h'' : ¬v = x
h' : u = x
⊢ False
[PROOFSTEP]
cases h'
[GOAL]
case neg.mpr.refl
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v✝ : V
p✝ : Walk G u v✝
ht✝ : IsTrail p✝
x v : V
p : Walk G v x
ih : Even (List.countp (fun e => decide (x ∈ e)) (edges p)) ↔ ¬v = x → ¬x = x
h'' : ¬v = x
huv : Adj G x v
h : ¬x = x ∧ ¬x = v
ht : IsTrail p ∧ ¬Quotient.mk (Sym2.Rel.setoid V) (x, v) ∈ edges p
⊢ False
[PROOFSTEP]
simp only [not_true, and_false, false_and] at h
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
h : IsEulerian p
⊢ IsTrail p
[PROOFSTEP]
rw [isTrail_def, List.nodup_iff_count_le_one]
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
h : IsEulerian p
⊢ ∀ (a : Sym2 V), List.count a (edges p) ≤ 1
[PROOFSTEP]
intro e
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
h : IsEulerian p
e : Sym2 V
⊢ List.count e (edges p) ≤ 1
[PROOFSTEP]
by_cases he : e ∈ p.edges
[GOAL]
case pos
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
h : IsEulerian p
e : Sym2 V
he : e ∈ edges p
⊢ List.count e (edges p) ≤ 1
[PROOFSTEP]
exact (h e (edges_subset_edgeSet _ he)).le
[GOAL]
case neg
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
h : IsEulerian p
e : Sym2 V
he : ¬e ∈ edges p
⊢ List.count e (edges p) ≤ 1
[PROOFSTEP]
simp [he]
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
h : IsEulerian p
e : Sym2 V
he : e ∈ edgeSet G
⊢ e ∈ edges p
[PROOFSTEP]
simpa using (h e he).ge
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
h : IsEulerian p
e : Sym2 V
⊢ e ∈ IsTrail.edgesFinset (_ : IsTrail p) ↔ e ∈ edgeSet G
[PROOFSTEP]
simp only [Finset.mem_mk, Multiset.mem_coe, h.mem_edges_iff]
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
⊢ IsEulerian p ↔ IsTrail p ∧ ∀ (e : Sym2 V), e ∈ edgeSet G → e ∈ edges p
[PROOFSTEP]
constructor
[GOAL]
case mp
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
⊢ IsEulerian p → IsTrail p ∧ ∀ (e : Sym2 V), e ∈ edgeSet G → e ∈ edges p
[PROOFSTEP]
intro h
[GOAL]
case mp
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
h : IsEulerian p
⊢ IsTrail p ∧ ∀ (e : Sym2 V), e ∈ edgeSet G → e ∈ edges p
[PROOFSTEP]
exact ⟨h.isTrail, fun _ => h.mem_edges_iff.mpr⟩
[GOAL]
case mpr
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
⊢ (IsTrail p ∧ ∀ (e : Sym2 V), e ∈ edgeSet G → e ∈ edges p) → IsEulerian p
[PROOFSTEP]
rintro ⟨h, hl⟩
[GOAL]
case mpr.intro
V : Type u_1
G : SimpleGraph V
inst✝ : DecidableEq V
u v : V
p : Walk G u v
h : IsTrail p
hl : ∀ (e : Sym2 V), e ∈ edgeSet G → e ∈ edges p
⊢ IsEulerian p
[PROOFSTEP]
exact h.isEulerian_of_forall_mem hl
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝¹ : DecidableEq V
inst✝ : Fintype ↑(edgeSet G)
u v : V
p : Walk G u v
h : IsEulerian p
⊢ IsTrail.edgesFinset (_ : IsTrail p) = edgeFinset G
[PROOFSTEP]
ext e
[GOAL]
case a
V : Type u_1
G : SimpleGraph V
inst✝¹ : DecidableEq V
inst✝ : Fintype ↑(edgeSet G)
u v : V
p : Walk G u v
h : IsEulerian p
e : Sym2 V
⊢ e ∈ IsTrail.edgesFinset (_ : IsTrail p) ↔ e ∈ edgeFinset G
[PROOFSTEP]
simp [h.mem_edges_iff]
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
x u v : V
p : Walk G u v
ht : IsEulerian p
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
⊢ Even (degree G x) ↔ u ≠ v → x ≠ u ∧ x ≠ v
[PROOFSTEP]
convert ht.isTrail.even_countp_edges_iff x
[GOAL]
case h.e'_1.h.e'_3
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
x u v : V
p : Walk G u v
ht : IsEulerian p
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
⊢ degree G x = List.countp (fun e => decide (x ∈ e)) (edges p)
[PROOFSTEP]
rw [← Multiset.coe_countp, Multiset.countp_eq_card_filter, ← card_incidenceFinset_eq_degree]
[GOAL]
case h.e'_1.h.e'_3
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
x u v : V
p : Walk G u v
ht : IsEulerian p
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
⊢ Finset.card (incidenceFinset G x) = ↑Multiset.card (Multiset.filter (fun e => x ∈ e) ↑(edges p))
[PROOFSTEP]
change Multiset.card _ = _
[GOAL]
case h.e'_1.h.e'_3
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
x u v : V
p : Walk G u v
ht : IsEulerian p
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
⊢ ↑Multiset.card (incidenceFinset G x).val = ↑Multiset.card (Multiset.filter (fun e => x ∈ e) ↑(edges p))
[PROOFSTEP]
congr 1
[GOAL]
case h.e'_1.h.e'_3.h.e_6.h
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
x u v : V
p : Walk G u v
ht : IsEulerian p
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
⊢ (incidenceFinset G x).val = Multiset.filter (fun e => x ∈ e) ↑(edges p)
[PROOFSTEP]
convert_to _ = (ht.isTrail.edgesFinset.filter (Membership.mem x)).val
[GOAL]
case h.e'_1.h.e'_3.h.e_6.h.convert_2
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
x u v : V
p : Walk G u v
ht : IsEulerian p
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
⊢ (incidenceFinset G x).val = (Finset.filter (Membership.mem x) (IsTrail.edgesFinset (_ : IsTrail p))).val
[PROOFSTEP]
have : Fintype G.edgeSet := fintypeEdgeSet ht
[GOAL]
case h.e'_1.h.e'_3.h.e_6.h.convert_2
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
x u v : V
p : Walk G u v
ht : IsEulerian p
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
this : Fintype ↑(edgeSet G)
⊢ (incidenceFinset G x).val = (Finset.filter (Membership.mem x) (IsTrail.edgesFinset (_ : IsTrail p))).val
[PROOFSTEP]
rw [ht.edgesFinset_eq, G.incidenceFinset_eq_filter x]
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
s : Finset V
h : s = Finset.filter (fun v => Odd (degree G v)) Finset.univ
⊢ Finset.card s = 0 ∨ Finset.card s = 2
[PROOFSTEP]
subst s
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
⊢ Finset.card (Finset.filter (fun v => Odd (degree G v)) Finset.univ) = 0 ∨
    Finset.card (Finset.filter (fun v => Odd (degree G v)) Finset.univ) = 2
[PROOFSTEP]
simp only [Nat.odd_iff_not_even, Finset.card_eq_zero]
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
⊢ Finset.filter (fun v => ¬Even (degree G v)) Finset.univ = ∅ ∨
    Finset.card (Finset.filter (fun v => ¬Even (degree G v)) Finset.univ) = 2
[PROOFSTEP]
simp only [ht.even_degree_iff, Ne.def, not_forall, not_and, Classical.not_not, exists_prop]
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
⊢ Finset.filter (fun v_1 => ¬u = v ∧ (¬v_1 = u → v_1 = v)) Finset.univ = ∅ ∨
    Finset.card (Finset.filter (fun v_1 => ¬u = v ∧ (¬v_1 = u → v_1 = v)) Finset.univ) = 2
[PROOFSTEP]
obtain rfl | hn := eq_or_ne u v
[GOAL]
case inl
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u : V
p : Walk G u u
ht : IsEulerian p
⊢ Finset.filter (fun v => ¬u = u ∧ (¬v = u → v = u)) Finset.univ = ∅ ∨
    Finset.card (Finset.filter (fun v => ¬u = u ∧ (¬v = u → v = u)) Finset.univ) = 2
[PROOFSTEP]
left
[GOAL]
case inl.h
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u : V
p : Walk G u u
ht : IsEulerian p
⊢ Finset.filter (fun v => ¬u = u ∧ (¬v = u → v = u)) Finset.univ = ∅
[PROOFSTEP]
simp
[GOAL]
case inr
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
hn : u ≠ v
⊢ Finset.filter (fun v_1 => ¬u = v ∧ (¬v_1 = u → v_1 = v)) Finset.univ = ∅ ∨
    Finset.card (Finset.filter (fun v_1 => ¬u = v ∧ (¬v_1 = u → v_1 = v)) Finset.univ) = 2
[PROOFSTEP]
right
[GOAL]
case inr.h
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
hn : u ≠ v
⊢ Finset.card (Finset.filter (fun v_1 => ¬u = v ∧ (¬v_1 = u → v_1 = v)) Finset.univ) = 2
[PROOFSTEP]
convert_to _ = ({ u, v } : Finset V).card
[GOAL]
case h.e'_3
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
hn : u ≠ v
⊢ 2 = Finset.card {u, v}
[PROOFSTEP]
simp [hn]
[GOAL]
case inr.h.convert_2
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
hn : u ≠ v
⊢ Finset.card (Finset.filter (fun v_1 => ¬u = v ∧ (¬v_1 = u → v_1 = v)) Finset.univ) = Finset.card {u, v}
[PROOFSTEP]
congr
[GOAL]
case inr.h.convert_2.e_s
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
hn : u ≠ v
⊢ Finset.filter (fun v_1 => ¬u = v ∧ (¬v_1 = u → v_1 = v)) Finset.univ = {u, v}
[PROOFSTEP]
ext x
[GOAL]
case inr.h.convert_2.e_s.a
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
hn : u ≠ v
x : V
⊢ x ∈ Finset.filter (fun v_1 => ¬u = v ∧ (¬v_1 = u → v_1 = v)) Finset.univ ↔ x ∈ {u, v}
[PROOFSTEP]
simp [hn, imp_iff_not_or]
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
⊢ Fintype.card ↑{v | Odd (degree G v)} = 0 ∨ Fintype.card ↑{v | Odd (degree G v)} = 2
[PROOFSTEP]
rw [← Set.toFinset_card]
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
⊢ Finset.card (Set.toFinset {v | Odd (degree G v)}) = 0 ∨ Finset.card (Set.toFinset {v | Odd (degree G v)}) = 2
[PROOFSTEP]
apply IsEulerian.card_filter_odd_degree ht
[GOAL]
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v : V
p : Walk G u v
ht : IsEulerian p
⊢ Set.toFinset {v | Odd (degree G v)} = Finset.filter (fun v => Odd (degree G v)) Finset.univ
[PROOFSTEP]
ext v
[GOAL]
case a
V : Type u_1
G : SimpleGraph V
inst✝² : DecidableEq V
inst✝¹ : Fintype V
inst✝ : DecidableRel G.Adj
u v✝ : V
p : Walk G u v✝
ht : IsEulerian p
v : V
⊢ v ∈ Set.toFinset {v | Odd (degree G v)} ↔ v ∈ Finset.filter (fun v => Odd (degree G v)) Finset.univ
[PROOFSTEP]
simp