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

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

Axiom char : Type.
Parameter char_WhyType : WhyType char.
Existing Instance char_WhyType.

(* Why3 assumption *)
Inductive regexp :=
  | Empty : regexp
  | Epsilon : regexp
  | Char : char -> regexp
  | Alt : regexp -> regexp -> regexp
  | Concat : regexp -> regexp -> regexp
  | Star : regexp -> regexp.
Axiom regexp_WhyType : WhyType regexp.
Existing Instance regexp_WhyType.

(* Why3 assumption *)
Definition word := (list char).

(* Why3 assumption *)
Inductive mem: (list char) -> regexp -> Prop :=
  | mem_eps : (mem Init.Datatypes.nil Epsilon)
  | mem_char : forall (c:char), (mem
      (Init.Datatypes.cons c Init.Datatypes.nil) (Char c))
  | mem_altl : forall (w:(list char)) (r1:regexp) (r2:regexp), (mem w r1) ->
      (mem w (Alt r1 r2))
  | mem_altr : forall (w:(list char)) (r1:regexp) (r2:regexp), (mem w r2) ->
      (mem w (Alt r1 r2))
  | mem_concat : forall (w1:(list char)) (w2:(list char)) (r1:regexp)
      (r2:regexp), (mem w1 r1) -> ((mem w2 r2) -> (mem
      (Init.Datatypes.app w1 w2) (Concat r1 r2)))
  | mems1 : forall (r:regexp), (mem Init.Datatypes.nil (Star r))
  | mems2 : forall (w1:(list char)) (w2:(list char)) (r:regexp), (mem w1
      r) -> ((mem w2 (Star r)) -> (mem (Init.Datatypes.app w1 w2) (Star r))).

Axiom inversion_mem_star_gen : forall (c:char) (w:(list char)) (r:regexp)
  (w':(list char)) (r':regexp), ((w' = (Init.Datatypes.cons c w)) /\
  (r' = (Star r))) -> ((mem w' r') -> exists w1:(list char),
  exists w2:(list char), (w = (Init.Datatypes.app w1 w2)) /\ ((mem
  (Init.Datatypes.cons c w1) r) /\ (mem w2 r'))).

Axiom inversion_mem_star : forall (c:char) (w:(list char)) (r:regexp), (mem
  (Init.Datatypes.cons c w) (Star r)) -> exists w1:(list char),
  exists w2:(list char), (w = (Init.Datatypes.app w1 w2)) /\ ((mem
  (Init.Datatypes.cons c w1) r) /\ (mem w2 (Star r))).

(* Why3 goal *)
Theorem WP_parameter_residual : forall (r:regexp) (c:char),
  forall (x:regexp), (r = (Star x)) -> forall (o:regexp),
  (forall (w:(list char)), (mem w o) <-> (mem (Init.Datatypes.cons c w)
  x)) -> forall (w:(list char)), (mem w (Concat o r)) <-> (mem
  (Init.Datatypes.cons c w) r).
(* Why3 intros r c x h1 o h2 w. *)
intros r c x h1 o h2 w.
subst.
intuition.

inversion H; subst; clear H.
rewrite List.app_comm_cons.
constructor; auto.
rewrite <- h2; auto.

destruct (inversion_mem_star _ _ _ H) as (w1 & w2 & hh1 & hh2 & hh3).
subst w.
constructor; auto.
now rewrite h2.

Qed.

