(** (Notice how the last example applies [MApp] to the strings [[1]] and [[2]] directly.  Since the goal mentions [[1; 2]] instead of [[1] ++ [2]], Coq wouldn't be able to figure out how to split the string on its own.)  Using [inversion], we can also show that certain strings do _not_ match a regular expression: *)
Example reg_exp_ex3 : ~ ([1; 2] =~ Char 1).
(** We can define helper functions to help write down regular expressions. The [reg_exp_of_list] function constructs a regular expression that matches exactly the list that it receives as an argument: *)
Fixpoint reg_exp_of_list {T} (l : list T) :=
match l with
| [] => EmptyStr
| x :: l' => App (Char x) (reg_exp_of_list l')
end.
Example reg_exp_ex4 : [1; 2; 3] =~ reg_exp_of_list [1; 2; 3].
(** We can also prove general facts about [exp_match].  For instance, the following lemma shows that every string [s] that matches [re] also matches [Star re]. *)

(* Specifications: *)
Lemma MStar1 :
forall T s (re : reg_exp T) ,
s =~ re ->
s =~ Star re.