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.