(* This file is generated by Why3's Coq driver *)
(* Beware! Only edit allowed sections below    *)
Require Import BuiltIn.
Require BuiltIn.
Require int.Int.
Require list.List.
Require list.Length.
Require list.Mem.
Require map.Map.
Require list.Append.
Require list.Distinct.

(* Why3 assumption *)
Definition unit := unit.

Axiom qtmark : Type.
Parameter qtmark_WhyType : WhyType qtmark.
Existing Instance qtmark_WhyType.

(* Why3 assumption *)
Inductive array (a:Type) :=
  | mk_array : Z -> (map.Map.map Z a) -> array a.
Axiom array_WhyType : forall (a:Type) {a_WT:WhyType a}, WhyType (array a).
Existing Instance array_WhyType.
Implicit Arguments mk_array [[a]].

(* Why3 assumption *)
Definition elts {a:Type} {a_WT:WhyType a} (v:(array a)): (map.Map.map Z a) :=
  match v with
  | (mk_array x x1) => x1
  end.

(* Why3 assumption *)
Definition length {a:Type} {a_WT:WhyType a} (v:(array a)): Z :=
  match v with
  | (mk_array x x1) => x
  end.

(* Why3 assumption *)
Definition get {a:Type} {a_WT:WhyType a} (a1:(array a)) (i:Z): a :=
  (map.Map.get (elts a1) i).

(* Why3 assumption *)
Definition set {a:Type} {a_WT:WhyType a} (a1:(array a)) (i:Z) (v:a): (array
  a) := (mk_array (length a1) (map.Map.set (elts a1) i v)).

(* Why3 assumption *)
Definition make {a:Type} {a_WT:WhyType a} (n:Z) (v:a): (array a) :=
  (mk_array n (map.Map.const v: (map.Map.map Z a))).

(* Why3 assumption *)
Inductive tree :=
  | Empty : tree
  | Node : tree -> tree -> tree.
Axiom tree_WhyType : WhyType tree.
Existing Instance tree_WhyType.

(* Why3 assumption *)
Fixpoint size (t:tree) {struct t}: Z :=
  match t with
  | Empty => 0%Z
  | (Node l r) => ((1%Z + (size l))%Z + (size r))%Z
  end.

Axiom size_nonneg : forall (t:tree), (0%Z <= (size t))%Z.

Axiom size_left : forall (t:tree), (0%Z < (size t))%Z -> exists l:tree,
  exists r:tree, (t = (Node l r)) /\ ((size l) < (size t))%Z.

(* Why3 assumption *)
Definition all_trees (n:Z) (l:(list tree)): Prop := (list.Distinct.distinct
  l) /\ forall (t:tree), ((size t) = n) <-> (list.Mem.mem t l).

(* Why3 goal *)
Theorem all_trees_0 : (all_trees 0%Z
  (Init.Datatypes.cons Empty Init.Datatypes.nil)).
Proof.
red; intuition.
apply Distinct.distinct_one.
destruct t; simpl; auto.
unfold size in H; fold size in H.
right; generalize (size_nonneg t1); generalize (size_nonneg t2); omega.
simpl in H; destruct H; intuition.
subst; simpl; auto.
Qed.

