(* End prelude *)

Inductive day : Type :=
  | monday : day
  | tuesday : day
  | wednesday : day
  | thursday : day
  | friday : day
  | saturday : day
  | sunday : day.(* End prelude *)

Inductive day : Type :=
  | monday : day
  | tuesday : day
  | wednesday : day
  | thursday : day
  | friday : day
  | saturday : day
  | sunday : day.(* End prelude *)

Inductive day : Type :=
  | monday : day
  | tuesday : day
  | wednesday : day
  | thursday : day
  | friday : day
  | saturday : day
  | sunday : day.(* End prelude *)

Inductive day : Type :=
  | monday : day
  | tuesday : day
  | wednesday : day
  | thursday : day
  | friday : day
  | saturday : day
  | sunday : day.(* End prelude *)

Inductive day : Type :=
  | monday : day
  | tuesday : day
  | wednesday : day
  | thursday : day
  | friday : day
  | saturday : day
  | sunday : day.(* End prelude *)

Inductive day : Type :=
  | monday : day
  | tuesday : day
  | wednesday : day
  | thursday : day
  | friday : day
  | saturday : day
  | sunday : day.(* End prelude *)

Inductive day : Type :=
  | monday : day
  | tuesday : day
  | wednesday : day
  | thursday : day
  | friday : day
  | saturday : day
  | sunday : day.(* End prelude *)

Inductive day : Type :=
  | monday : day
  | tuesday : day
  | wednesday : day
  | thursday : day
  | friday : day
  | saturday : day
  | sunday : day.Definition next_weekday (d:day) : day :=
  match d with
  | monday    => tuesday
  | tuesday   => wednesday
  | wednesday => thursday
  | thursday  => friday
  | friday    => monday
  | saturday  => monday
  | sunday    => monday
  end.Inductive bool : Type :=
  | true : bool
  | false : bool.Inductive bool : Type :=
  | true : bool
  | false : bool.Inductive bool : Type :=
  | true : bool
  | false : bool.Definition negb (b:bool) : bool :=
  match b with
  | true => false
  | false => true
  end.Definition andb (b1:bool) (b2:bool) : bool :=
  match b1 with
  | true => b2
  | false => false
  end.Definition orb (b1:bool) (b2:bool) : bool :=
  match b1 with
  | true => true
  | false => b2
  end.(* XXX these do not work because there's already an instance for nat. *)
(*
Derive SizeMonotonic for nat using genSnat.
Derive SizedMonotonic for nat.
Derive SizedCorrect for nat using genSnat and SizeMonotonicnat.
*)

Inductive nat' : Type :=
  | stop : nat'
  | tick : nat' -> nat'.(* XXX these do not work because there's already an instance for nat. *)
(*
Derive SizeMonotonic for nat using genSnat.
Derive SizedMonotonic for nat.
Derive SizedCorrect for nat using genSnat and SizeMonotonicnat.
*)

Inductive nat' : Type :=
  | stop : nat'
  | tick : nat' -> nat'.(* XXX these do not work because there's already an instance for nat. *)
(*
Derive SizeMonotonic for nat using genSnat.
Derive SizedMonotonic for nat.
Derive SizedCorrect for nat using genSnat and SizeMonotonicnat.
*)

Inductive nat' : Type :=
  | stop : nat'
  | tick : nat' -> nat'.Definition pred (n : nat) : nat :=
  match n with
    | O => O
    | S n' => n'
  end.Definition minustwo (n : nat) : nat :=
  match n with
    | O => O
    | S O => O
    | S (S n') => n'
  end.Fixpoint evenb (n:nat) : bool :=
  match n with
  | O        => true
  | S O      => false
  | S (S n') => evenb n'
  end.Definition oddb (n:nat) : bool   :=   negb (evenb n).Fixpoint plus (n : nat) (m : nat) : nat :=
  match n with
    | O => m
    | S n' => S (plus n' m)
  end.Fixpoint mult (n m : nat) : nat :=
  match n with
    | O => O
    | S n' => plus m (mult n' m)
  end.Fixpoint minus (n m:nat) : nat :=
  match n, m with
  | O   , _    => O
  | S _ , O    => n
  | S n', S m' => minus n' m'
  end.Fixpoint beq_nat (n m : nat) : bool :=
  match n with
  | O => match m with
         | O => true
         | S m' => false
         end
  | S n' => match m with
            | O => false
            | S m' => beq_nat n' m'
            end
  end.Fixpoint leb (n m : nat) : bool :=
  match n with
  | O => true
  | S n' =>
      match m with
      | O => false
      | S m' => leb n' m'
      end
  end.

Theorem plus_0_example: forall n, n = 17 -> n = 42.