import data.list
open nat

definition foo (a : nat) : nat :=
match a with
| zero   := zero
| succ n := n
end

example : foo 3 = 2 := rfl

open decidable

protected theorem dec_eq : ∀ x y : nat, decidable (x = y)
| dec_eq zero     zero     := inl rfl
| dec_eq (succ x) zero     := inr (λ h, nat.no_confusion h)
| dec_eq zero     (succ y) := inr (λ h, nat.no_confusion h)
| dec_eq (succ x) (succ y) :=
  match dec_eq x y with
  | inl H := inl (eq.rec_on H rfl)
  | inr H := inr (λ h : succ x = succ y, nat.no_confusion h (λ heq : x = y, absurd heq H))
  end

context
  open list
  parameter {A : Type}
  parameter (p : A → Prop)
  parameter [H : decidable_pred p]
  include H

  definition filter : list A → list A
  | filter nil      := nil
  | filter (a :: l) :=
    match H a with
    | inl h := a :: filter l
    | inr h := filter l
    end

  theorem filter_nil : filter nil = nil :=
  rfl

  theorem filter_cons (a : A) (l : list A) : filter (a :: l) = if p a then a :: filter l else filter l :=
  rfl
end

definition sub2 (a : nat) : nat :=
match a with
| 0   := 0
| 1   := 0
| b+2 := b
end

example (a : nat) : sub2 (succ (succ a)) = a := rfl
