(** Basic generator instances *)
Global Instance genBoolSized : GenSized bool :=
  {| arbitrarySized x := choose (false, true) |}.Instance genNatSized : GenSized nat :=
  {| arbitrarySized x := choose (0,x) |}.Global Instance genZSized : GenSized Z :=
  {| arbitrarySized x := let z := Z.of_nat x in
                         choose (-z, z)%Z |}.Global Instance genNSized : GenSized N :=
  {| arbitrarySized x := let n := N.of_nat x in
                         choose (N0, n) |}.Global Instance genListSized {A : Type} `{GenSized A} : GenSized (list A) :=
  {| arbitrarySized x := vectorOf x (arbitrarySized x) |}.(* [3] is a lower priority than [Classes.GenOfGenSized],
   avoiding an infinite loop in typeclass resolution. *)

Global Instance genList {A : Type} `{Gen A} : Gen (list A) | 3 :=
  {| arbitrary := listOf arbitrary |}.Global Instance genPairSized {A B : Type} `{GenSized A} `{GenSized B}
: GenSized (A*B) :=
  {| arbitrarySized x :=
       liftGen2 pair (arbitrarySized x)
                     (arbitrarySized x)
  |}.Global Instance genPair {A B : Type} `{Gen A} `{Gen B} : Gen (A * B) :=
  {| arbitrary := liftGen2 pair arbitrary arbitrary |}.(** Shrink Instances *)
Global Instance shrinkBool : Shrink bool :=
  {| shrink x :=
       match x with
         | false => nil
         | true  => cons false nil
       end
  |}.(** Shrinking of nat starts to become annoying *)
Function shrinkNatAux (x : nat) {measure (fun x => x) x} : list nat :=
  match x with
    | O => nil
    | S n =>
      let x' := Nat.div x 2 in
      x' :: shrinkNatAux x'
  end.Global Instance shrinkNat : Shrink nat :=
  {| shrink := shrinkNatAux |}.

(* Specifications: *)
Lemma abs_div2_pos : forall p, Z.abs_nat (Z.div2 (Z.pos p)) = Nat.div2 (Pos.to_nat p).
Lemma neg_succ : forall p, Z.neg (Pos.succ p) = Z.pred (Z.neg p).
Lemma neg_pred : forall p, (p > 1)%positive -> Z.neg (Pos.pred p) = Z.succ (Z.neg p).
Lemma abs_succ_neg : forall p, Z.abs_nat (Z.succ (Z.neg p)) = Nat.pred (Pos.to_nat p).
Lemma abs_succ_div2_neg : forall p, Z.abs_nat (Z.succ (Z.div2 (Z.neg p))) = Nat.div2 (Pos.to_nat p) \/ Z.abs_nat (Z.succ (Z.div2 (Z.neg p))) = Nat.pred (Nat.div2 (Pos.to_nat p)).