Admitted. (* OUT-OF-SCOPE *)
Inductive reg_exp (T : Type) : Type :=
| EmptySet : reg_exp T
| EmptyStr : reg_exp T
| Char : T -> reg_exp T
| App : reg_exp T -> reg_exp T -> reg_exp T
| Union : reg_exp T -> reg_exp T -> reg_exp T
| Star : reg_exp T -> reg_exp T.
Arguments EmptySet {T}.
Arguments EmptyStr {T}.
Arguments Char {T} _.
Arguments App {T} _ _.
Arguments Union {T} _ _.
Arguments Star {T} _.
Derive (Arbitrary, Show) for reg_exp.
Derive (Sized, CanonicalSized) for reg_exp.
Derive SizeMonotonic for reg_exp using genSreg_exp.
Derive SizedMonotonic for reg_exp.
Derive SizedCorrect for reg_exp using genSreg_exp and SizeMonotonicreg_exp.
Inductive exp_match {T} : list T -> reg_exp T -> Prop :=
| MEmpty : exp_match [] EmptyStr
| MChar : forall x, exp_match [x] (Char x)
| MApp : forall s1 re1 s2 re2,
exp_match s1 re1 ->
exp_match s2 re2 ->
exp_match (s1 ++ s2) (App re1 re2)
| MUnionL : forall s1 re1 re2,
exp_match s1 re1 ->
exp_match s1 (Union re1 re2)
| MUnionR : forall re1 s2 re2,
exp_match s2 re2 ->
exp_match s2 (Union re1 re2)
| MStar0 : forall re, exp_match [] (Star re)
| MStarApp : forall s1 s2 re,
exp_match s1 re ->
exp_match s2 (Star re) ->
exp_match (s1 ++ s2) (Star re).
Notation "s =~ re" := (exp_match s re) (at level 80).
(* Leo: TODO *)
(* Derive ArbitrarySizedSuchThat for (fun n => exp_match n re). Derive SizedProofEqs for (fun n => exp_match n re). Derive SizeMonotonicSuchThatOpt for (fun n => exp_match n re). Derive GenSizedSuchThatCorrect for (fun n => exp_match n re). Derive GenSizedSuchThatSizeMonotonicOpt for (fun n => exp_match n re).   Fixpoint reg_exp_of_list {T} (l : list T) := match l with | [] => EmptyStr | x :: l' => App (Char x) (reg_exp_of_list l') end.  Lemma MStar1 : forall T s (re : reg_exp T) , s =~ re -> s =~ Star re. Admitted. (* Leo: TODO *)
*)

Lemma MUnion' : forall T (s : list T) (re1 re2 : reg_exp T),
s =~ re1 \/ s =~ re2 ->
s =~ Union re1 re2.