(* QuickChick Prelude *)
Set Warnings "-extraction-opaque-accessed,-extraction".
Set Warnings "-notation-overridden,-parsing".
Set Bullet Behavior "Strict Subproofs".
(* End prelude *)
Inductive day : Type :=
| monday : day
| tuesday : day
| wednesday : day
| thursday : day
| friday : day
| saturday : day
| sunday : day.
Derive (Arbitrary, Show) for day.
Derive (Sized, CanonicalSized) for day.
Derive SizeMonotonic for day using genSday.
Derive SizedMonotonic for day.
Derive SizedCorrect for day using genSday and SizeMonotonicday.
Definition next_weekday (d:day) : day :=
match d with
| monday    => tuesday
| tuesday   => wednesday
| wednesday => thursday
| thursday  => friday
| friday    => monday
| saturday  => monday
| sunday    => monday
end.
Module BoolPlayground.
Inductive bool : Type :=
| true : bool
| false : bool.
Derive (Arbitrary, Show) for bool.
Derive (Sized, CanonicalSized) for bool.
Derive SizeMonotonic for bool using genSbool.
Derive SizedMonotonic for bool.
Derive SizedCorrect for bool using genSbool and SizeMonotonicbool.
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.
End BoolPlayground.
Module NatPlayground.
(* Note: nat already exists *)
(* Inductive nat : Type := | O : nat | S : nat -> nat. *)
Derive (Arbitrary, Show) for nat.
Derive (Sized, CanonicalSized) for 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'.
(* Not sure why this works but the above doesn't. If it's nat-specific I don't really care *)
(* Yes it was nat specific. It breaks because there are two instances for nat -- one of them handwritten. *)
Derive (Arbitrary, Show) for nat'.
Derive (Sized, CanonicalSized) for nat'.
Derive SizeMonotonic for nat' using genSnat'.
Derive SizedMonotonic for nat'.
Derive SizedCorrect for nat' using genSnat' and SizeMonotonicnat'.
(** The second branch can be read: "if [n] has the form [S n'] for some [n'], then return [n']."  *)
End NatPlayground.
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).
Module NatPlayground2.
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.
End NatPlayground2.
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.

(* Specifications: *)
Theorem plus_O_n : forall n : nat, 0 + n = n.
Admitted. (* QuickChick plus_O_n. *)
Theorem plus_O_n' : forall n : nat, 0 + n = n.
Admitted. (* QuickChick plus_O_n'. *)
Theorem plus_1_l : forall n:nat, 1 + n = S n.
Admitted. (* QuickChick plus_1_l. *)
Theorem mult_0_l : forall n:nat, 0 * n = 0.
Admitted. (* QuickChick mult_0_l. *)
Theorem plus_0_example: forall n, n = 17 -> n = 42.
Admitted. (* QuickChick plus_0_example. *)
Conjecture plus_id_example : forall n m : nat, n = m -> n + n = m + 0.