(********************************************************************)
(*                                                                  *)
(*  The Why3 Verification Platform   /   The Why3 Development Team  *)
(*  Copyright 2010-2018   --   Inria - CNRS - Paris-Sud University  *)
(*                                                                  *)
(*  This software is distributed under the terms of the GNU Lesser  *)
(*  General Public License version 2.1, with the special exception  *)
(*  on linking described in file LICENSE.                           *)
(*                                                                  *)
(********************************************************************)

(* This file is generated by Why3's Coq-realize 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 list.Append.

(* Why3 goal *)
Lemma reverse_def : forall {a:Type} {a_WT:WhyType a}, forall (l:(list a)),
  ((Lists.List.rev l) = match l with
  | Init.Datatypes.nil => Init.Datatypes.nil
  | (Init.Datatypes.cons x r) =>
      (Init.Datatypes.app (Lists.List.rev r) (Init.Datatypes.cons x Init.Datatypes.nil))
  end).
Proof.
now intros a a_WT [|x l].
Qed.

(* Why3 goal *)
Lemma reverse_append : forall {a:Type} {a_WT:WhyType a}, forall (l1:(list a))
  (l2:(list a)) (x:a),
  ((Init.Datatypes.app (Lists.List.rev (Init.Datatypes.cons x l1)) l2) = (Init.Datatypes.app (Lists.List.rev l1) (Init.Datatypes.cons x l2))).
Proof.
intros a a_WT l1 l2 x.
simpl.
now rewrite <- List.app_assoc.
Qed.

(* Why3 goal *)
Lemma reverse_cons : forall {a:Type} {a_WT:WhyType a}, forall (l:(list a))
  (x:a),
  ((Lists.List.rev (Init.Datatypes.cons x l)) = (Init.Datatypes.app (Lists.List.rev l) (Init.Datatypes.cons x Init.Datatypes.nil))).
intros a a_WT l x.
simpl.
auto.
Qed.

(* Why3 goal *)
Lemma cons_reverse : forall {a:Type} {a_WT:WhyType a}, forall (l:(list a))
  (x:a),
  ((Init.Datatypes.cons x (Lists.List.rev l)) = (Lists.List.rev (Init.Datatypes.app l (Init.Datatypes.cons x Init.Datatypes.nil)))).
intros a a_WT l x.
now rewrite List.rev_unit.
Qed.

(* Why3 goal *)
Lemma reverse_reverse : forall {a:Type} {a_WT:WhyType a},
  forall (l:(list a)), ((Lists.List.rev (Lists.List.rev l)) = l).
Proof.
intros a a_WT l.
apply List.rev_involutive.
Qed.

(* Why3 goal *)
Lemma reverse_mem : forall {a:Type} {a_WT:WhyType a}, forall (l:(list a))
  (x:a), (list.Mem.mem x l) <-> (list.Mem.mem x (Lists.List.rev l)).
intros a a_WT l x.
induction l; simpl; intuition.
rewrite Append.mem_append.
right; simpl; now intuition.
rewrite Append.mem_append.
now auto.
assert (Mem.mem x (List.rev l) \/ Mem.mem x (a0 :: nil))%list.
rewrite <- Append.mem_append; assumption.
intuition; simpl in *.
intuition.
Qed.

(* Why3 goal *)
Lemma Reverse_length : forall {a:Type} {a_WT:WhyType a}, forall (l:(list a)),
  ((list.Length.length (Lists.List.rev l)) = (list.Length.length l)).
Proof.
intros a a_WT l.
rewrite 2!Length.length_std.
now rewrite List.rev_length.
Qed.

