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 (Ndouble 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 (Ndouble 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.

(* Specifications: *)
Lemma kill_empty_states_lazy_eg_kill_empty_states :
forall d : DTA, DTA_kill_empty_states_lazy d = DTA_kill_empty_states d.
Lemma pl_kill_0 :
forall (p : prec_list) (m : Map bool) (plp : pl_path),
pl_path_incl plp p ->
pl_path_true plp m ->
exists pl : prec_list,
prec_list_kill m p = Some pl /\ pl_path_incl plp pl.
Lemma pl_kill_1 :
forall (p p' : prec_list) (m : Map bool) (pl : pl_path),
prec_list_kill m p = Some p' ->
pl_path_incl pl p' -> pl_path_incl pl p /\ pl_path_true pl m.
Lemma pl_kill_prec_empty :
forall (p : prec_list) (m : Map bool),
prec_list_kill m p = Some prec_empty -> p = prec_empty.
Lemma st_kill_0 :
forall (s : state) (m : Map bool) (a : ad) (p p' : prec_list),
prec_list_kill m p = Some p' ->
MapGet prec_list s a = Some p ->
MapGet prec_list (states_kill_aux m s) a = Some p'.
Lemma st_kill_1 :
forall (s : state) (m : Map bool) (a : ad) (p p' : prec_list),
prec_list_kill m p = Some p' ->
MapGet prec_list s a = Some p ->
exists s' : state,
states_kill m s = Some s' /\
MapGet prec_list s' a = Some p'.
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.
Lemma st_kill_3 :
forall (s' s : state) (m : Map bool),
states_kill_aux m s = s' ->
s' <> M0 prec_list ->
exists p : prec_list,
(exists a : ad, MapGet prec_list s' a = Some p).
Lemma st_kill_4 :
forall (s s' : state) (m : Map bool),
states_kill m s = Some s' ->
exists p : prec_list,
(exists a : ad, MapGet prec_list s' a = Some p).
Lemma dt_kill_0 :
forall (d : preDTA) (m : Map bool) (a : ad) (s s' : state),
states_kill m s = Some s' ->
MapGet state d a = Some s ->
MapGet state (preDTA_kill m d) a = Some s'.
Lemma dt_kill_1 :
forall (d : preDTA) (m : Map bool) (a : ad) (s : state),
MapGet state (preDTA_kill m d) a = Some s ->
exists s' : state,
MapGet state d a = Some s' /\ states_kill m s' = Some s.