49 lines
1.8 KiB
Text
49 lines
1.8 KiB
Text
@[simp] def List.count' [DecidableEq α] : List α → α → Nat
|
||
| [], _ => 0
|
||
| a::as, b => if a = b then as.count' b + 1 else as.count' b
|
||
|
||
inductive StarsAndBars : Nat → Nat → Type where
|
||
| nil : StarsAndBars 0 0
|
||
| star : StarsAndBars s b → StarsAndBars (s+1) b
|
||
| bar : StarsAndBars s b → StarsAndBars s (b+1)
|
||
|
||
namespace StarsAndBars
|
||
|
||
namespace Ex1
|
||
|
||
def toList : StarsAndBars s b → { bs : List Bool // bs.count' false = s ∧ bs.count' true = b }
|
||
| nil => ⟨[], by simp⟩
|
||
| star h => ⟨false :: toList h, by simp [(toList h).2]⟩
|
||
| bar h => ⟨true :: toList h, by simp [(toList h).2]⟩
|
||
|
||
theorem toList_star (h : StarsAndBars s b) (h') : toList (star h) = ⟨false :: toList h, h'⟩ := by
|
||
rfl
|
||
|
||
theorem toList_bar (h : StarsAndBars s b) (h') : toList (bar h) = ⟨true :: toList h, h'⟩ := by
|
||
rfl
|
||
|
||
end Ex1
|
||
|
||
/- Same example with explicit proofs -/
|
||
namespace Ex2
|
||
|
||
theorem toList_star_proof (h : bs.count' false = s ∧ bs.count' true = b) : (false :: bs).count' false = s.succ ∧ (false :: bs).count' true = b := by
|
||
simp [*]
|
||
|
||
theorem toList_bar_proof (h : bs.count' false = s ∧ bs.count' true = b) : (true :: bs).count' false = s ∧ (true :: bs).count' true = b.succ := by
|
||
simp [*]
|
||
|
||
def toList : StarsAndBars s b → { bs : List Bool // bs.count' false = s ∧ bs.count' true = b }
|
||
| nil => ⟨[], by simp⟩
|
||
| star h => ⟨false :: toList h, toList_star_proof (toList h).property⟩
|
||
| bar h => ⟨true :: toList h, toList_bar_proof (toList h).property⟩
|
||
|
||
theorem toList_star (h : StarsAndBars s b) : toList (star h) = ⟨false :: toList h, toList_star_proof (toList h).property⟩ := by
|
||
rfl
|
||
|
||
theorem toList_bar (h : StarsAndBars s b) : toList (bar h) = ⟨true :: toList h, toList_bar_proof (toList h).property⟩ := by
|
||
rfl
|
||
|
||
end Ex2
|
||
|
||
end StarsAndBars
|