(* This program is free software; you can redistribute it and/or      *)
(* modify it under the terms of the GNU Lesser General Public License *)
(* as published by the Free Software Foundation; either version 2.1   *)
(* of the License, or (at your option) any later version.             *)
(*                                                                    *)
(* This program is distributed in the hope that it will be useful,    *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of     *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      *)
(* GNU General Public License for more details.                       *)
(*                                                                    *)
(* You should have received a copy of the GNU Lesser General Public   *)
(* License along with this program; if not, write to the Free         *)
(* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *)
(* 02110-1301 USA                                                     *)
(* fonction kill empty states *)
Fixpoint prec_list_kill (m : Map bool) (p : prec_list) {struct p} :
option prec_list :=
match p with
| prec_empty => Some prec_empty
| prec_cons a la ls =>
match ls with
| prec_empty =>
match MapGet bool m a with
| None => None
| Some b =>
if b
then
match prec_list_kill m la with
| None => None
| Some la' => Some (prec_cons a la' prec_empty)
end
else None
end
| prec_cons _ _ _ =>
match MapGet bool m a with
| None => prec_list_kill m ls
| Some b =>
if b
then
match prec_list_kill m la, prec_list_kill m ls with
| None, None => None
| None, Some ls' => Some ls'
| Some la', None =>
Some (prec_cons a la' prec_empty)
| Some la', Some ls' => Some (prec_cons a la' ls')
end
else prec_list_kill m ls
end
end
end.
Fixpoint states_kill_aux (m : Map bool) (s : state) {struct s} : state :=
match s with
| M0 => M0 prec_list
| M1 a p =>
match prec_list_kill m p with
| None => M0 prec_list
| Some p' => M1 prec_list a p'
end
| M2 s0 s1 =>
match states_kill_aux m s0, states_kill_aux m s1 with
| M0, M0 => M0 prec_list
| M0, M1 a p => M1 prec_list (Ndouble_plus_one a) p
| M1 a p, M0 => M1 prec_list (N.double a) p
| s0', s1' => M2 prec_list s0' s1'
end
end.
Definition states_kill (m : Map bool) (s : state) :
option state :=
match states_kill_aux m s with
| M0 => None
| x => Some x
end.
Fixpoint preDTA_kill (m : Map bool) (d : preDTA) {struct d} : preDTA :=
match d with
| M0 => M0 state
| M1 a s =>
match states_kill m s with
| None => M0 state
| Some s' => M1 state a s'
end
| M2 d0 d1 =>
match preDTA_kill m d0, preDTA_kill m d1 with
| M0, M0 => M0 state
| M0, M1 a s' => M1 state (Ndouble_plus_one a) s'
| M1 a s', M0 => M1 state (N.double a) s'
| d0', d1' => M2 state d0' d1'
end
end.
Definition DTA_simpl (d : DTA) : DTA :=
match d with
| dta p a =>
match MapGet state p a with
| None => dta (M1 state N0 (M0 prec_list)) N0
| _ => dta p a
end
end.
Definition DTA_kill (m : Map bool) (d : DTA) : DTA :=
match d with
| dta p a => DTA_simpl (dta (preDTA_kill m p) a)
end.
Definition DTA_kill_empty_states (d : DTA) : DTA :=
DTA_kill (dta_states_non_empty d) d.
Definition DTA_kill_empty_states_lazy (d : DTA) : DTA :=
DTA_kill (dta_states_non_empty_lazy d) d.

Lemma st_kill_2 :
forall (s : state) (m : Map bool) (a : ad) (p : prec_list),
MapGet prec_list (states_kill_aux m s) a = Some p ->
exists p' : prec_list,
MapGet prec_list s a = Some p' /\
prec_list_kill m p' = Some p.