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.

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.