(** Properties of [switch] compilation *)

Inductive lbl_stmt_tail: lbl_stmt -> nat -> lbl_stmt -> Prop :=
  | lstail_O: forall sl,
      lbl_stmt_tail sl O sl
  | lstail_S: forall c s sl n sl',
      lbl_stmt_tail sl n sl' ->
      lbl_stmt_tail (LScons c s sl) (S n) sl'.(** Properties of [switch] compilation *)

Inductive lbl_stmt_tail: lbl_stmt -> nat -> lbl_stmt -> Prop :=
  | lstail_O: forall sl,
      lbl_stmt_tail sl O sl
  | lstail_S: forall c s sl n sl',
      lbl_stmt_tail sl n sl' ->
      lbl_stmt_tail (LScons c s sl) (S n) sl'.(** Properties of [switch] compilation *)

Inductive lbl_stmt_tail: lbl_stmt -> nat -> lbl_stmt -> Prop :=
  | lstail_O: forall sl,
      lbl_stmt_tail sl O sl
  | lstail_S: forall c s sl n sl',
      lbl_stmt_tail sl n sl' ->
      lbl_stmt_tail (LScons c s sl) (S n) sl'.

(* Specifications: *)
Lemma switch_table_default: forall sl base, exists n, lbl_stmt_tail sl n (select_switch_default sl) /\ snd (switch_table sl base) = (n + base)%nat.
Lemma switch_table_case: forall i sl base dfl, match select_switch_case i sl with | None => switch_target i dfl (fst (switch_table sl base)) = dfl | Some sl' => exists n, lbl_stmt_tail sl n sl' /\ switch_target i dfl (fst (switch_table sl base)) = (n + base)%nat end.
Lemma switch_table_select: forall i sl, lbl_stmt_tail sl (switch_target i (snd (switch_table sl O)) (fst (switch_table sl O))) (select_switch i sl).