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.
Admitted. (* QuickChick plus_O_n. *)
Admitted. (* QuickChick plus_O_n'. *)
Admitted. (* QuickChick plus_1_l. *)
Admitted. (* QuickChick mult_0_l. *)
Admitted. (* QuickChick plus_0_example. *)
Conjecture plus_id_example : forall n m : nat, n = m -> n + n = m + 0.
QuickChick plus_id_example.
(* Derive ArbitrarySizedSuchThat for (fun x => eq x a).  QuickChickDebug Debug On.  Derive SizeMonotonicSuchThatOpt for (fun x => eq x a).  Derive SizedProofEqs for (fun x => eq x a).   refine ((fun x' => ex_intro _ _) _). refine (ex_intro _). refine (eq_ind (fun _gen (input0_ : A) => bigcup setT (fun n => let fix aux_iter size0 (input0_ : A) := match size0 with | O => setU (set1 input0_) set0 | S size' => setU (set1 input0_) set0 end in aux_iter n input0_) _gen) _ x input0_). (fun x => ex_intro _ (Coq.Init.Datatypes.S 0) (conj I (or_introl (Logic.eq_refl _)))) x input0_).   Definition s A (input0_ : A) := (fun x => conj (fun Hin => match Hin with | ex_intro s Hc => match Hc with | conj Hl Hin => nat_ind (fun n => forall x (input0_ : A), Basics.impl ((let fix aux_iter size0 (input0_ : A) := match size0 with | O => setU (set1 input0_) set0 | S size' => setU (set1 input0_) set0 end in aux_iter n input0_) x) ((@eq A) x input0_)) (fun x (input0_ : A) hin => match hin with | or_introl Hr0 => eq_ind _ _ (eq_refl _) _ Hr0 | or_intror Hl0 => False_ind _ Hl0 end) (fun size0 IHs x (input0_ : A) hin => match hin with | or_introl Hr1 => eq_ind _ _ (eq_refl _) _ Hr1 | or_intror Hl1 => False_ind _ Hl1 end) s x input0_ Hin end end) (eq_ind (fun _gen (input0_ : A) => bigcup setT (fun n => let fix aux_iter size0 (input0_ : A) := match size0 with | O => setU (set1 input0_) set0 | S size' => setU (set1 input0_) set0 end in aux_iter n input0_) _gen) (fun x => ex_intro _ (Coq.Init.Datatypes.S 0) (conj I (or_introl (Logic.eq_refl _)))) x input0_)).   (* TODO: Replace these with derived versions *)
(*  QuickChickDebug Debug On.    Derive GenSizedSuchThatCorrect for (fun eq => eq x a).  Derive GenSizedSuchThatSizeMonotonicOpt for (fun foo => goodFooUnif n foo). *)
*)

Theorem plus_id_exercise : forall n m o : nat,
n = m -> m = o -> n + m = m + o.